使用 Apache POI 组合条形图和折线图



我按照这里的例子:

Apache Poi:如何创建同时包含条形和折线的图表?

但是,图表以两个 y 轴显示。 似乎创建第二种类型的图表会导致双轴。 任何想法如何在POI中组合两种类型的图表并且不会发生这种情况?

谢谢!杰夫

我的代码如下。 与我所指的帖子几乎相同,但有我的数据:

File    file = null;
FileOutputStream    fos = null;
XSSFWorkbook    workBook = new XSSFWorkbook();
XSSFSheet   sheet = (XSSFSheet) workBook.createSheet("LineBarChart");
XSSFCellStyle   bmDataStyle;
XSSFRow     row = null;
XSSFCell    cell = null;
// Define a data Font
Font    dataFont = workBook.createFont();
dataFont.setFontHeightInPoints((short)11);
dataFont.setBold(false);
Font    dataFontBold = workBook.createFont();
dataFontBold.setFontHeightInPoints((short)11);
dataFontBold.setBold(true);
// Row 1
// Create FY month Headings (also used as range for X series labels)
bmDataStyle = bmDataStyle(workBook, dataFontBold, null, null, "right", false, false, false, false);
int rowCtr = 0;
int cellCnt = 0;
row = sheet.createRow(rowCtr++);
cell = row.createCell(cellCnt++);
for (int i = 0; i < FYMONTHS.length; i++) {
    cell = row.createCell(cellCnt++);
    cell.setCellValue(CpttUtil.toSentenceCase(FYMONTHS[i]));
    cell.setCellStyle(bmDataStyle);
}
// Row 2
// Create Projected Obligation Plan dollars data
bmDataStyle = bmDataStyle(workBook, dataFont, null, null, null, false, false, false, false);
cellCnt = 0;
row = sheet.createRow(rowCtr++);
cell = row.createCell(cellCnt++);
cell.setCellValue("Projected Obligation Plans ($K)");
cell.setCellStyle(bmDataStyle);
sheet.autoSizeColumn(0);
bmDataStyle = bmDataStyle(workBook, dataFont, null, "currency", "right", false, false, false, false);
for (int i = 0; i < POP_DOLLARS.length; i++) {
    cell = row.createCell(cellCnt++);
    cell.setCellValue(POP_DOLLARS[i]);
    cell.setCellStyle(bmDataStyle);
    sheet.autoSizeColumn(i);
}
// Row 3
// Create Projected Obligation Plan percent data
bmDataStyle = bmDataStyle(workBook, dataFont, null, null, null, false, false, false, false);
cellCnt = 0;
row = sheet.createRow(rowCtr++);
cell = row.createCell(cellCnt++);
cell.setCellValue("Projected Obligation Plans (%)");
cell.setCellStyle(bmDataStyle);
sheet.autoSizeColumn(0);
bmDataStyle = bmDataStyle(workBook, dataFont, null, "pct0", "right", false, false, false, false);
for (int i = 0; i < POP_PCT.length; i++) {
    cell = row.createCell(cellCnt++);
    cell.setCellValue(POP_PCT[i]);
    sheet.autoSizeColumn(i);
    cell.setCellStyle(bmDataStyle);
}
// Row 4
// Create Actual Obligations dollars data
bmDataStyle = bmDataStyle(workBook, dataFont, null, null, null, false, false, false, false);
cellCnt = 0;
row = sheet.createRow(rowCtr++);
cell = row.createCell(cellCnt++);
cell.setCellValue("Actual Obligations ($K)");
cell.setCellStyle(bmDataStyle);
sheet.autoSizeColumn(0);
bmDataStyle = bmDataStyle(workBook, dataFont, null, "currency", "right", false, false, false, false);
for (int i = 0; i < OBL_ACTUALS.length; i++) {
    cell = row.createCell(cellCnt++);
    cell.setCellValue(OBL_ACTUALS[i]);
    cell.setCellStyle(bmDataStyle);
    sheet.autoSizeColumn(i);
}
// Row 5
// Create Actual Obligations percent data
bmDataStyle = bmDataStyle(workBook, dataFont, null, null, null, false, false, false, false);
cellCnt = 0;
row = sheet.createRow(rowCtr++);
cell = row.createCell(cellCnt++);
cell.setCellValue("Actual Obligations (%)");
cell.setCellStyle(bmDataStyle);
sheet.autoSizeColumn(0);
bmDataStyle = bmDataStyle(workBook, dataFont, null, "pct0", "right", false, false, false, false);
for (int i = 0; i < OBL_PCT.length; i++) {
    cell = row.createCell(cellCnt++);
    cell.setCellValue(OBL_PCT[i]);
    cell.setCellStyle(bmDataStyle);
    sheet.autoSizeColumn(i);
}
// Row 6
// Create Cash Allocation Plan data
bmDataStyle = bmDataStyle(workBook, dataFont, null, null, null, false, false, false, false);
cellCnt = 0;
row = sheet.createRow(rowCtr++);
cell = row.createCell(cellCnt++);
cell.setCellValue("Cash Allocation Plan");
cell.setCellStyle(bmDataStyle);
sheet.autoSizeColumn(0);
bmDataStyle = bmDataStyle(workBook, dataFont, null, "currency", "right", false, false, false, false);
for (int i = 0; i < CASH_ALLOC.length; i++) {
    cell = row.createCell(cellCnt++);
    cell.setCellValue(CASH_ALLOC[i]);
    cell.setCellStyle(bmDataStyle);
    sheet.autoSizeColumn(i);
}
// Row 7
// Create Cash Disbursement dollars data
bmDataStyle = bmDataStyle(workBook, dataFont, null, null, null, false, false, false, false);
cellCnt = 0;
row = sheet.createRow(rowCtr++);
cell = row.createCell(cellCnt++);
cell.setCellValue("Cash Disbursements ($K)");
cell.setCellStyle(bmDataStyle);
sheet.autoSizeColumn(0);
bmDataStyle = bmDataStyle(workBook, dataFont, null, "currency", "right", false, false, false, false);
for (int i = 0; i < CASH_DISBURSE.length; i++) {
    cell = row.createCell(cellCnt++);
    cell.setCellValue(CASH_DISBURSE[i]);
    cell.setCellStyle(bmDataStyle);
    sheet.autoSizeColumn(i);
}
// Row 8
// Create OSD Benchmarks dollars data
bmDataStyle = bmDataStyle(workBook, dataFont, null, null, null, false, false, false, false);
cellCnt = 0;
row = sheet.createRow(rowCtr++);
cell = row.createCell(cellCnt++);
cell.setCellValue("OSD Benchmarks ($K)");
cell.setCellStyle(bmDataStyle);
sheet.autoSizeColumn(0);
bmDataStyle = bmDataStyle(workBook, dataFont, null, "currency", "right", false, false, false, false);
for (int i = 0; i < BENCH_DOLLARS.length; i++) {
    cell = row.createCell(cellCnt++);
    cell.setCellValue(BENCH_DOLLARS[i]);
    cell.setCellStyle(bmDataStyle);
    sheet.autoSizeColumn(i);
}
try {
    // Create a drawing canvas on the worksheet
    XSSFDrawing drawing = sheet.createDrawingPatriarch();
    // Define anchor points in the worksheet to position the chart
    XSSFClientAnchor    anchor = drawing.createAnchor(0, 0, 0, 0, 0, 12, 13, 40);
    // Create the chart object based on the anchor point
    XSSFChart   chart = drawing.createChart(anchor);
    CTChart     ctChart = ((XSSFChart)chart).getCTChart();
    CTPlotArea  ctPlotArea = ctChart.getPlotArea();
    String  monthsRefer = "LineBarChart!$B$1:$M$1";  // Range where months are
    // Bar Chart
    CTBarChart  ctBarChart = ctPlotArea.addNewBarChart();
    CTBoolean   ctBoolean = ctBarChart.addNewVaryColors();
    ctBoolean.setVal(false);
    ctBarChart.addNewBarDir().setVal(STBarDir.COL);
    // Name the series
    CTBarSer    ctBarSer = ctBarChart.addNewSer();
    CTSerTx     ctSerTx = ctBarSer.addNewTx();
    CTStrRef    ctStrRef = ctSerTx.addNewStrRef();
    ctStrRef.setF("LineBarChart!$A$6");
    ctBarSer.addNewIdx().setVal(0);  // 0 = blue
    // Labels for Bar Chart
    CTAxDataSource  ctAxDataSource = ctBarSer.addNewCat();
    ctStrRef = ctAxDataSource.addNewStrRef();
    ctStrRef.setF(monthsRefer);
    // Values for Bar Chart
    CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
    CTNumRef        ctNumRef = ctNumDataSource.addNewNumRef();
    String  valuesRefer = "LineBarChart!$B$6:$M$6";  // Range where values are
    ctNumRef.setF(valuesRefer);
    rgb = CTSRgbColor.Factory.newInstance();
ctBarSer.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte)157,(byte)195,(byte)230});
    // Name the series
    CTBarSer    ctBarSer2 = ctBarChart.addNewSer();
    CTSerTx     ctSerTx2 = ctBarSer2.addNewTx();
    CTStrRef    ctStrRef2 = ctSerTx2.addNewStrRef();
    ctStrRef2.setF("LineBarChart!$A$7");
    ctBarSer2.addNewIdx().setVal(2);  // 1 = gray
    // Labels for Bar Chart
    CTAxDataSource  ctAxDataSource2 = ctBarSer2.addNewCat();
    ctStrRef2 = ctAxDataSource2.addNewStrRef();
    ctStrRef2.setF(monthsRefer);
    // Values for Bar Chart
    CTNumDataSource ctNumDataSource2 = ctBarSer2.addNewVal();
    CTNumRef        ctNumRef2 = ctNumDataSource2.addNewNumRef();
    String  valuesRefer2 = "LineBarChart!$B$7:$M$7";  // Range where values are
    ctNumRef2.setF(valuesRefer2);
ctBarSer2.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte)219,(byte)219,(byte)219});
    // Axis
    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(true);
    ctCatAx.addNewAxPos().setVal(STAxPos.L);
    ctCatAx.addNewCrossAx().setVal(123457);  // ID of the Val axis
    //ctCatAx.addNewMinorTickMark().setVal(STTickMark.NONE);
    //ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
    // Val Left Axis
    CTValAx ctValAx = ctPlotArea.addNewValAx();
    ctValAx.addNewAxId().setVal(123457);
    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 Val axis
    ctValAx.addNewMinorTickMark().setVal(STTickMark.NONE);
    //ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
    ctValAx.addNewMajorGridlines();

    // Line Chart
    // Val Right Axis
    CTLineChart ctLineChart = ctPlotArea.addNewLineChart();
    CTBoolean   ctBooleanLine = ctLineChart.addNewVaryColors();
    ctBooleanLine.setVal(false);
    CTLineSer   ctLineSer = ctLineChart.addNewSer();
    CTSerTx     ctSerTx1 = ctLineSer.addNewTx();
    CTStrRef    ctStrRef1 = ctSerTx1.addNewStrRef();
    ctStrRef1.setF("LineBarChart!$A2");
    ctLineSer.addNewIdx().setVal(4);  // 2 = gray
    CTAxDataSource  ctAxDataSource1 = ctLineSer.addNewCat();
    ctStrRef1 = ctAxDataSource1.addNewStrRef();
    ctStrRef1.setF(monthsRefer);   // Months
    ctLineSer.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte)0,(byte)0,(byte)0});
    String  values2Refer = "LineBarChart!$B$2:$M$2";   // Range for POP values
    CTNumDataSource ctNumDataSource1 = ctLineSer.addNewVal();
    CTNumRef    ctNumRef1 = ctNumDataSource1.addNewNumRef();
    ctNumRef1.setF(values2Refer);
    // Axis
    ctLineChart.addNewAxId().setVal(1234);   // ID of the Cat axis
    ctLineChart.addNewAxId().setVal(12345);   // ID of the Val axis
    CTCatAx ctCatAx1 = ctPlotArea.addNewCatAx();
    ctCatAx1.addNewAxId().setVal(1234);      // Cat axis
    CTScaling   ctScaling1 = ctCatAx1.addNewScaling();
    ctScaling1.addNewOrientation().setVal(STOrientation.MIN_MAX);
    ctCatAx1.addNewDelete().setVal(true);
    ctCatAx1.addNewAxPos().setVal(STAxPos.L);
    ctCatAx1.addNewCrossAx().setVal(12345);   // Val axis
    //CTBoolean ctBoolean1 = ctCatAx1.addNewAuto();
    CTValAx ctValAx2 = ctPlotArea.addNewValAx();
    ctValAx2.addNewAxId().setVal(12345);       // Val axis
    ctScaling1 = ctValAx2.addNewScaling();
    ctScaling1.addNewOrientation().setVal(STOrientation.MIN_MAX);
    ctValAx2.addNewDelete().setVal(false);
    ctValAx2.addNewAxPos().setVal(STAxPos.L);
    ctValAx2.addNewCrossAx().setVal(1234);    // Cat axis
    ctValAx2.addNewMinorTickMark().setVal(STTickMark.NONE);
    //ctValAx2.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);

    // Legend
    // Define legends for the line chart and set the position of the legend
    CTLegend    ctLegend = ctChart.addNewLegend();
    ctLegend.addNewLegendPos().setVal(STLegendPos.L);
    ctLegend.addNewOverlay().setVal(true);
    // Finally output the file
    file = new File(fileName);
    fos = new FileOutputStream(file);
    workBook.write(fos);
} catch (IOException ioe) {
    System.out.println("Caught a: " + ioe.getClass().getName());
    System.out.println("Message: " + ioe.getMessage());
    System.out.println("Stacktrace follows:.....");
    ioe.printStackTrace(System.out);
} finally {
    try {
        if (fos != null) {
            fos.close();
            fos = null;
        }
        workBook.close();
    } catch (IOException ioe) {
        System.out.println("Caught a: " + ioe.getClass().getName());
        System.out.println("Message: " + ioe.getMessage());
        System.out.println("Stacktrace follows:.....");
        ioe.printStackTrace(System.out);
    }
}

两个图表的 Y 轴都由CTValAx类控制。要使 Y 轴刻度不显示,请设置为 ctValAx1.addNewDelete().setVal(true); 。这意味着图表的 Y 轴已创建,但删除了垂直表示。

最新更新