You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Apache POI中XSSFClientAnchor的背景颜色?

如何修改Apache POI环形图表的锚点区域背景颜色

我正在使用Apache POI创建三个环形图表,当前图表背景为白色,希望将XSSFClientAnchor对应的区域修改为自定义RGB颜色,相关代码如下:

private void createDounughtChart(final XSSFWorkbook workbook, String sheetName) {
    final XSSFSheet uebersicht = workbook.getSheet(sheetName);
    String[] categories = new String[]{"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"};
    Number[] values = new Number[]{11L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L};
    XSSFChart chart1 = createDoughnutChart(uebersicht, categories, values, "Zusammensetzung Abfallfraktionen", 2, 5, 5, 26);

    categories = new String[]{"one", "two"};
    values = new Number[]{60L, 40L};
    XSSFChart chart2 = createDoughnutChart(uebersicht, categories, values, "Anteil gefährliche / nicht gefährliche Abfälle", 5, 5, 8, 24);

    categories = new String[]{"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"};
    values = new Number[]{11L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L};
    XSSFChart chart3 = createDoughnutChart(uebersicht, categories, values, "Zusammensetzung Entsorgungswege", 8, 5, 11, 26);
}

static XSSFChart createDoughnutChart(XSSFSheet sheet, String[] categories, Number[] values, String titleText, int col1, int row1, int col2, int row2) {
    XSSFDrawing drawing = sheet.createDrawingPatriarch();
    XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, col1, row1, col2, row2);

    XSSFChart chart = drawing.createChart(anchor);
    chart.setTitleText(titleText);
    chart.setTitleOverlay(false);

    XDDFChartLegend legend = chart.getOrAddLegend();
    legend.setPosition(LegendPosition.BOTTOM);

    XDDFDataSource<String> cat = XDDFDataSourcesFactory.fromArray(categories);
    XDDFNumericalDataSource<Number> val = XDDFDataSourcesFactory.fromArray(values);

    XDDFDoughnutChartData data = (XDDFDoughnutChartData) chart.createData(ChartTypes.DOUGHNUT, null, null);
    data.setVaryColors(true);
    XDDFChartData.Series series = data.addSeries(cat, val);
    chart.plot(data);

    // 禁止自动删除标题,确保在Calc中显示标题
    if (chart.getCTChart().getAutoTitleDeleted() == null) chart.getCTChart().addNewAutoTitleDeleted();
    chart.getCTChart().getAutoTitleDeleted().setVal(false);

    // 设置数据点颜色,确保在Calc中显示数据点
    int pointCount = series.getCategoryData().getPointCount();
    for (int p = 0; p < pointCount; p++) {
        chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDPt().addNewIdx().setVal(p);
        chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDPtArray(p)
                .addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(XlsxService.getColor(p));
    }

    // 添加数据标签
    if (!chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).isSetDLbls()) {
        chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDLbls();
    }
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(true);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowPercent().setVal(false);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);

    // 移除图表区域边框
    chart.getCTChartSpace().addNewSpPr().addNewLn().addNewNoFill();

    return chart;
}

解决方案

XSSFClientAnchor仅用于定义图表在工作表中的位置范围,要修改该区域的背景色,实际是设置图表容器(ChartSpace)的填充颜色。在createDoughnutChart方法中,添加以下代码来设置自定义RGB背景色:

// 设置图表区域的自定义RGB背景色
CTSolidFill solidFill = chart.getCTChartSpace().getSpPr().addNewSolidFill();
CTSrgbClr rgbClr = solidFill.addNewSrgbClr();
// 替换为你需要的RGB值,示例为浅蓝色(RGB:204,229,255)
rgbClr.setVal(new byte[]{(byte)204, (byte)229, (byte)255});

修改后的完整方法

static XSSFChart createDoughnutChart(XSSFSheet sheet, String[] categories, Number[] values, String titleText, int col1, int row1, int col2, int row2) {
    XSSFDrawing drawing = sheet.createDrawingPatriarch();
    XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, col1, row1, col2, row2);

    XSSFChart chart = drawing.createChart(anchor);
    chart.setTitleText(titleText);
    chart.setTitleOverlay(false);

    XDDFChartLegend legend = chart.getOrAddLegend();
    legend.setPosition(LegendPosition.BOTTOM);

    XDDFDataSource<String> cat = XDDFDataSourcesFactory.fromArray(categories);
    XDDFNumericalDataSource<Number> val = XDDFDataSourcesFactory.fromArray(values);

    XDDFDoughnutChartData data = (XDDFDoughnutChartData) chart.createData(ChartTypes.DOUGHNUT, null, null);
    data.setVaryColors(true);
    XDDFChartData.Series series = data.addSeries(cat, val);
    chart.plot(data);

    // 禁止自动删除标题,确保在Calc中显示标题
    if (chart.getCTChart().getAutoTitleDeleted() == null) chart.getCTChart().addNewAutoTitleDeleted();
    chart.getCTChart().getAutoTitleDeleted().setVal(false);

    // 设置数据点颜色,确保在Calc中显示数据点
    int pointCount = series.getCategoryData().getPointCount();
    for (int p = 0; p < pointCount; p++) {
        chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDPt().addNewIdx().setVal(p);
        chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDPtArray(p)
                .addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(XlsxService.getColor(p));
    }

    // 添加数据标签
    if (!chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).isSetDLbls()) {
        chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).addNewDLbls();
    }
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(true);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowPercent().setVal(false);
    chart.getCTChart().getPlotArea().getDoughnutChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);

    // 移除图表区域边框
    chart.getCTChartSpace().addNewSpPr().addNewLn().addNewNoFill();

    // 设置图表区域的自定义RGB背景色
    CTSolidFill solidFill = chart.getCTChartSpace().getSpPr().addNewSolidFill();
    CTSrgbClr rgbClr = solidFill.addNewSrgbClr();
    // 替换为你需要的RGB值,示例为浅蓝色(RGB:204,229,255)
    rgbClr.setVal(new byte[]{(byte)204, (byte)229, (byte)255});

    return chart;
}

说明

  • RGB值需要转换为byte数组,由于Java的byte是有符号类型(范围-128到127),所以大于127的RGB分量需要用(byte)强制转换,比如204对应(byte)204。
  • 你可以根据需求修改rgbClr.setVal中的byte数组,替换成目标颜色的RGB值。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:54:53