Search code examples
javaapache-poi

Set single data label bold in XSSFChart with Apache Poi 5


Is it possible to set a bold single data label text of XSSFChart? I can change the font settings of ALL data labels like this:

chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewTxPr();
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().getTxPr().addNewBodyPr();
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().getTxPr().addNewP();
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().getTxPr().getPArray(0).addNewPPr();        
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().getTxPr().getPArray(0).getPPr().addNewDefRPr().setB(true);     

However, I want to change the font settings of a single data label. In unzipped XML I found that there should be an opportunity to get data label objects by index from the data labels list. Then apply font changes for this single label. But I can't get a single data label object (CTDLbl) to apply some changes in Java code. There are no available methods for the CTDLbl object. I'm using Apache Poi 5.3.0.

enter image description here

Is it possible to change the settings of a single data label? Thanks.


Solution

  • It the need is to set special settings for a single data label, then there must be dlbl elements having a special idx in dlbls. Settings in dlbls set the defaults for all data labels while settings in dlbl set special settings for the data label at position idx.

    Apache POI delivers per default only poi-ooxml-lite-5.*.*.jar which is a lite version of the underlying XML beans only. This lite version does not contain CTDlbl as this is not provided by Apache POI high level classes up to now. Thus, if one needs CTDlbl to construct dlbl elements, one needs poi-ooxml-full-5.*.*.jar in class path.

    Flowing complete code shows the wanted for a pie chart. It sets special settings for the data label at position 9. The code needs poi-ooxml-full-5.*.*.jar to be in class path.

    import java.io.FileOutputStream;
    import java.io.IOException;
    
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.ss.usermodel.ClientAnchor;
    import org.apache.poi.xddf.usermodel.chart.LegendPosition;
    import org.apache.poi.xddf.usermodel.chart.XDDFChart;
    import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
    import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
    import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
    import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
    import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
    import org.apache.poi.xddf.usermodel.chart.XDDFPieChartData;
    import org.apache.poi.xddf.usermodel.chart.ChartTypes;
    import org.apache.poi.xddf.usermodel.XDDFNoFillProperties;
    import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
    import org.apache.poi.xssf.usermodel.XSSFChart;
    import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
    import org.apache.poi.xssf.usermodel.XSSFDrawing;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    public class PieChart {
          
      public static void main(String[] args) throws IOException {
        try (XSSFWorkbook wb = new XSSFWorkbook()) {
          XSSFSheet sheet = wb.createSheet("piechart");
          final int NUM_OF_ROWS = 2;
          final int NUM_OF_COLUMNS = 10;
    
          // Create a row and put some cells in it. Rows are 0 based.
          Row row;
          Cell cell;
          for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
            row = sheet.createRow((short) rowIndex);
            for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
              cell = row.createCell((short) colIndex);
              if (rowIndex == 0) cell.setCellValue("Cat " + (colIndex + 1));
              else cell.setCellValue((colIndex + 1) * (rowIndex + 1));
            }
          }
    
          XSSFDrawing drawing = sheet.createDrawingPatriarch();
          XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 4, 10, 25);
          
          anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
    
          XSSFChart chart = drawing.createChart(anchor);
          
          chart.setTitleText("Pie Chart");
          chart.setTitleOverlay(false);
          
          XDDFChartLegend legend = chart.getOrAddLegend();
          legend.setPosition(LegendPosition.TOP_RIGHT);
    
          XDDFDataSource<String> cat = XDDFDataSourcesFactory.fromStringCellRange(sheet,
              new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
          XDDFNumericalDataSource<Double> val = XDDFDataSourcesFactory.fromNumericCellRange(sheet,
              new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
    
          XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
          data.setVaryColors(true);
          data.addSeries(cat, val);
          chart.plot(data);
          
          // Add data labels
          if (!chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).isSetDLbls()) 
            chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDLbls();
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .addNewDLblPos().setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STDLblPos.OUT_END);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .addNewShowLegendKey().setVal(true);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .addNewShowPercent().setVal(true);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .addNewShowSerName().setVal(false);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .addNewShowCatName().setVal(false);
            
          // Special setting for one data label at idx 9
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .addNewDLbl();
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).addNewIdx().setVal(9);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).addNewDLblPos().setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STDLblPos.OUT_END);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).addNewShowLegendKey().setVal(true);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).addNewShowPercent().setVal(true);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).addNewShowSerName().setVal(false);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).addNewShowCatName().setVal(false);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).addNewTxPr();
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).getTxPr().addNewBodyPr();
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).getTxPr().addNewP();
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).getTxPr().getPArray(0).addNewPPr();        
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).getTxPr().getPArray(0).getPPr().addNewDefRPr().setB(true);
          chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls()
            .getDLblArray(0).getTxPr().getPArray(0).getPPr().getDefRPr().setSz(2000);
            
          // Write the output to a file
          try (FileOutputStream fileOut = new FileOutputStream("ooxml-pie-chart.xlsx")) {
            wb.write(fileOut);
          }
        }
      }
    }