【问题标题】:Excel Generation [Java] - BarChart - Enable Multi Category LabelExcel 生成 [Java] - 条形图 - 启用多类别标签
【发布时间】:2020-04-18 04:59:18
【问题描述】:

我使用 org.apache.poi 库生成了 excel。这里我需要生成一个条形图,应该如下所示:

我的excel看起来像:

代码:

    //CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol)
    XDDFDataSource<String> department = XDDFDataSourcesFactory.fromStringCellRange(sheet,
            new CellRangeAddress(7, 17, 1, 1));

如果我设置 CellRangeAddress firstCol - 0 和 lastCol - 1 它不起作用?

是否有任何选项可以在 java 中启用此功能:

【问题讨论】:

    标签: java excel apache-poi bar-chart xssf


    【解决方案1】:

    使用 apache poi 的 XDDF 东西无法实现多级类别标签。 XDDF 始终使用 StrRef 作为图表数据源的引用。要创建多级类别标签,必须使用MultiLvlStrRef。所以这个任务只能直接使用低级org.openxmlformats.schemas.drawingml.x2006.chart.*类来解决。

    这就是为什么下面的代码需要类路径中所有ooxml-schemas 的完整jar,即当前apache poi 4.1.2ooxml-schemas-1.4.jarpoi-ooxml-schemas-4.1.2.jar 不包含 org.openxmlformats.schemas.drawingml.x2006.chart.CTMultiLvlStrRef

    由于Microsoft 的粗略逻辑,它使用NoMultiLvlLbl-true 作为类别轴的默认设置,现在必须告诉类别轴它没有没有多级标签。因此,如果轴要具有多级类别标签,则必须设置NoMultiLvlLblfalse。好吧,看来Microsoft 想检查程序员是否很好地学习了他们的逻辑课程;-)。

    完整示例:

    import java.io.FileOutputStream;
    
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
    import org.apache.poi.xddf.usermodel.chart.LegendPosition;
    import org.apache.poi.xssf.usermodel.*;
    
    import org.openxmlformats.schemas.drawingml.x2006.chart.*;
    
    public class BarChartMultiLevelCategories {
    
     public static void main(String[] args) throws Exception {
    
      String[] series = new String[]{"January","February","March"};
      String[] charges = new String[]{"Charges not Tally","Deposit","High Charges", "Quotation"};
      String[] treatment = new String[]{"Diagnosis","Explanation","Procedure"};
      String[] behaviour = new String[]{"Miscommunication","Not Attentive","Not Friendly", "Rude"};
      Double[][] values = new Double[][]{
       new Double[]{1d, 2d, 3d},
       new Double[]{1d, 3d, 2d},
       new Double[]{2d, 1d, 3d},
       new Double[]{2d, 3d, 1d},
       new Double[]{3d, 1d, 2d},
       new Double[]{3d, 2d, 1d},
       new Double[]{1d, 2d, 3d},
       new Double[]{1d, 3d, 2d},
       new Double[]{2d, 1d, 3d},
       new Double[]{2d, 3d, 1d},
       new Double[]{3d, 1d, 2d},
      };
    
      try (XSSFWorkbook wb = new XSSFWorkbook()) {
       //the sheet for the chart
       XSSFSheet chartSheet = wb.createSheet("barchart");
       //the sheet for the data
       XSSFSheet dataSheet = wb.createSheet("data");
    
       Row row;
       Cell cell;
       row = dataSheet.createRow(0);
       for (int i = 0; i < series.length; i++) {
        cell = row.createCell(i+2); cell.setCellValue(series[i]);
       }
       for (int i = 0; i < charges.length; i++) {
        row = dataSheet.createRow(i+1);
        if (i == 0) { cell = row.createCell(0); cell.setCellValue("Charges"); }
        cell = row.createCell(1); cell.setCellValue(charges[i]);
       }
       dataSheet.addMergedRegion(new CellRangeAddress(1, charges.length, 0, 0));
       for (int i = 0; i < treatment.length; i++) {
        row = dataSheet.createRow(i+1+charges.length);
        if (i == 0) { cell = row.createCell(0); cell.setCellValue("Treatment"); }
        cell = row.createCell(1); cell.setCellValue(treatment[i]);
       }
       dataSheet.addMergedRegion(new CellRangeAddress(1+charges.length, charges.length+treatment.length, 0, 0));
       for (int i = 0; i < behaviour.length; i++) {
        row = dataSheet.createRow(i+1+charges.length+treatment.length);
        if (i == 0) { cell = row.createCell(0); cell.setCellValue("Behaviour"); }
        cell = row.createCell(1); cell.setCellValue(behaviour[i]);
       }
       dataSheet.addMergedRegion(
       new CellRangeAddress(1+charges.length+treatment.length, charges.length+treatment.length+behaviour.length, 0, 0));
       for (int i = 0; i < values.length; i++) {
        Double[] valuesRow = values[i];
        row = dataSheet.getRow(i+1);
        for (int j = 0; j < valuesRow.length; j++) {
         cell = row.createCell(j+2); cell.setCellValue(valuesRow[j]);
        }
       }
    
       XSSFDrawing drawing = chartSheet.createDrawingPatriarch();
       XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 10, 20);
    
       XSSFChart chart = drawing.createChart(anchor);
       chart.setTitleText("Chart title");
       chart.setTitleOverlay(false);
       //do not auto delete the title; is necessary for showing title in Calc
       if (chart.getCTChart().getAutoTitleDeleted() == null) chart.getCTChart().addNewAutoTitleDeleted();
       chart.getCTChart().getAutoTitleDeleted().setVal(false);
    
       XDDFChartLegend legend = chart.getOrAddLegend();
       legend.setPosition(LegendPosition.RIGHT);
    
       CTChart ctChart = chart.getCTChart();
       CTPlotArea ctPlotArea = ctChart.getPlotArea();
       CTBarChart ctBarChart = ctPlotArea.addNewBarChart();
       CTBoolean ctBoolean = ctBarChart.addNewVaryColors();
       ctBoolean.setVal(true);
       ctBarChart.addNewBarDir().setVal(STBarDir.COL);
    
       //telling the BarChart that it has axes and giving them Ids
       ctBarChart.addNewAxId().setVal(123456);
       ctBarChart.addNewAxId().setVal(123457);
    
       //cat axis
       CTCatAx ctCatAx = ctPlotArea.addNewCatAx(); 
       ctCatAx.addNewAxId().setVal(123456); //id of the cat axis
       CTScaling ctScaling = ctCatAx.addNewScaling();
       ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
       ctCatAx.addNewDelete().setVal(false);
       ctCatAx.addNewAxPos().setVal(STAxPos.B);
       ctCatAx.addNewCrossAx().setVal(123457); //id of the val axis
       ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
    
       //telling the category axis that it not has no multi level labels ;-)
       ctCatAx.addNewNoMultiLvlLbl().setVal(false);
    
       //val axis
       CTValAx ctValAx = ctPlotArea.addNewValAx(); 
       ctValAx.addNewAxId().setVal(123457); //id of the val axis
       ctScaling = ctValAx.addNewScaling();
       ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
       ctValAx.addNewDelete().setVal(false);
       ctValAx.addNewAxPos().setVal(STAxPos.L);
       ctValAx.addNewCrossAx().setVal(123456); //id of the cat axis
       ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
    
       //series
       byte[][] seriesColors = new byte[][] {
        new byte[]{(byte)255, 0, 0}, //red
        new byte[]{0, (byte)255, 0}, //green
        new byte[]{0, 0, (byte)255}  //blue
       };
       for (int i = 0; i < series.length; i++) {
        CTBarSer ctBarSer = ctBarChart.addNewSer();
        CTSerTx ctSerTx = ctBarSer.addNewTx();
        CTStrRef ctStrRef = ctSerTx.addNewStrRef();
        ctStrRef.setF(
         new CellRangeAddress(0, 0, i+2, i+2)
              .formatAsString(dataSheet.getSheetName(), true)); //data!R1C(i+2)
        ctBarSer.addNewIdx().setVal(i);  
    
        CTAxDataSource cttAxDataSource = ctBarSer.addNewCat();
        //do using MultiLvlStrRef instead of StrRef 
        CTMultiLvlStrRef ctMultiLvlStrRef = cttAxDataSource.addNewMultiLvlStrRef();
        ctMultiLvlStrRef.setF(
         new CellRangeAddress(1, charges.length+treatment.length+behaviour.length, 0, 1)
              .formatAsString(dataSheet.getSheetName(), true)); //data!$A$2:$B$12
    
        CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
        CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
        ctNumRef.setF(
         new CellRangeAddress(1, charges.length+treatment.length+behaviour.length, i+2, i+2)
              .formatAsString(dataSheet.getSheetName(), true)); //data!R2C(i+2):R12C(i+2)
    
        ctBarSer.addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(seriesColors[i]);   
    
       } 
    
       try (FileOutputStream fileOut = new FileOutputStream("ooxml-bar-chart.xlsx")) {
        wb.write(fileOut);
       }
      }
     }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-19
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-24
      • 1970-01-01
      相关资源
      最近更新 更多