gpt4 book ai didi

java - Excel 生成 [Java] - 条形图 - 启用多类别标签

转载 作者:行者123 更新时间:2023-12-01 17:21:19 29 4
gpt4 key购买 nike

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

enter image description here我的 Excel 看起来像:

enter image description here

代码:

    //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 中启用此功能:

enter image description here

最佳答案

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

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

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

完整示例:

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);
}
}
}
}

关于java - Excel 生成 [Java] - 条形图 - 启用多类别标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61284419/

29 4 0