You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Apache POI生成Excel折线图单数据系列图例异常问题

解决Apache POI单系列折线图图例异常问题

我之前用Apache POI生成Excel折线图时也踩过一模一样的坑,咱们来聊聊问题根源和修复方案:

问题原因

当你只保留单个数据系列时,Apache POI 4.1.1会犯一个小错误——它把**分类轴的标签(china、usa、japan)**当成了图例项,而不是用你设置的系列标题(Area)。多系列时因为有明确的多个系列区分,所以不会触发这个问题,单系列时就暴露了这个默认逻辑的bug。

修复方案

在绘制图表后,手动清除错误的图例条目,然后添加正确的系列标题作为图例项。修改后的代码如下:

public static void test() throws Exception {
  try (XSSFWorkbook wb = new XSSFWorkbook()) {
    String sheetName = "CountryLineChart";
    XSSFSheet sheet = wb.createSheet(sheetName);
    XSSFDrawing drawing = sheet.createDrawingPatriarch();
    XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 4, 7, 26);
    XSSFChart chart = drawing.createChart(anchor);
    chart.setTitleText("Area-wise Top Seven Countries");
    chart.setTitleOverlay(false);
    XDDFChartLegend legend = chart.getOrAddLegend();
    legend.setPosition(LegendPosition.TOP_RIGHT);
    XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
    bottomAxis.setTitle("Country");
    XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
    leftAxis.setTitle("Area & Population");
    XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromArray(new String[] { "china", "usa", "japan" });
    XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromArray(new Double[] { 12d, 22d, 12d });
    // XDDFNumericalDataSource<Double> population = XDDFDataSourcesFactory.fromArray(new Double[] { 33d, 12d, 16d });
    XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
    XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(countries, area);
    series1.setTitle("Area", null);
    series1.setSmooth(false);
    series1.setMarkerStyle(MarkerStyle.STAR);
    // 注释掉第二个系列的代码
    // ===========================================================================
    // XDDFLineChartData.Series series2 = (XDDFLineChartData.Series) data.addSeries(countries, population);
    // series2.setTitle("Population", null);
    // series2.setSmooth(true);
    // series2.setMarkerStyle(MarkerStyle.SQUARE);
    // ===========================================================================
    chart.plot(data);

    // ------------------------ 新增修复图例的代码 ------------------------
    // 清除默认生成的错误图例条目
    while (legend.getEntries().size() > 0) {
        legend.removeEntry(0);
    }
    // 添加正确的系列标题作为图例项
    if (!data.getSeries().isEmpty()) {
        XDDFLineChartData.Series singleSeries = (XDDFLineChartData.Series) data.getSeries().get(0);
        XDDFLegendEntry legendEntry = legend.addEntry(0, LegendEntryType.SERIES);
        legendEntry.setText(singleSeries.getTitleText());
    }
    // -------------------------------------------------------------------

    // 写入Excel文件
    String filename = "/Users/jiangxingshang/Downloads/tmp/line-chart.xlsx";
    try (FileOutputStream fileOut = new FileOutputStream(filename)) {
      wb.write(fileOut);
    }
  }
}

补充说明

  • 这段修复代码会先清空所有自动生成的错误图例条目,然后从当前数据系列中获取唯一的系列标题,添加为新的图例项,确保图例显示的是你预期的系列名称。
  • 如果你后续又恢复多系列,这段代码也能兼容——当有多个系列时,你可以注释掉手动修复的代码,让POI自动处理图例即可。

内容的提问来源于stack exchange,提问作者user1434702

火山引擎 最新活动