java - 具有多个图表的 Apache POI 绘图区

java - Apache POI plot area with multiple charts

我正在尝试使用 PowerPoint 文件作为模板来生成另一个 powerpoint 来替换购物车数据。为了使模板看起来尽可能相似,我只是尝试替换我需要替换的数据,复制图表第一个 CT*Ser 中的所有其他数据。当绘图区域只有一个图表时,大多数图表(目前我对饼图、条形图和折线图感兴趣)一切正常。

当绘图区域有多个图表时(在我的例子中,一个包含多个系列的条形图和一个只有一个系列的折线图),看起来有些不对劲,Microsoft PowerPoint 可以'不要打开文件或其中的一部分,因为它似乎是被管理的。

为此,我正在为每个图表和图表类型执行以下代码(图表是我用来在模板文件中保留引用的对象)。

if (graph.getType().equals(CTArea3DChart.class.getName())) {
    CTArea3DChart c = plot.getArea3DChartArray()[graph.getIndex()];
    int removeSeries = c.getSerArray().length;
    for (int s = 0; s < graph.getSeries().size(); s++) {
        CTAreaSer ser = (CTAreaSer) c.getSerArray(0).copy();
        ser.getIdx().setVal(s);
        ser.getOrder().setVal(s);
        //ser.unsetSpPr();
        Serie serie = graph.getSeries().get(s);
        boolean delete = ser.isSetDLbls() && ser.getDLbls().getDLblArray().length > 0;
        if (delete) {
            int cntDlbls = ser.getDLbls().getDLblArray().length;
            for (int d = 0; d < cntDlbls; d++) {
                ser.getDLbls().removeDLbl(0);
            }
        }
        ser.unsetTx();
        CTStrRef serTitle = ser.addNewTx().addNewStrRef();
        serTitle.setF(graph.getSheetName() + "!$" + (char) ('B' + s) + "");
        CTStrData serTitleData = serTitle.addNewStrCache();
        serTitleData.addNewPtCount().setVal(1);
        CTStrVal serTitleDataVal = serTitleData.addNewPt();
        serTitleDataVal.setIdx(0);
        serTitleDataVal.setV(serie.getTitle());
        // Cat
        CTAxDataSource cat = ser.getCat();
        if (cat.isSetNumRef()) {
            cat.unsetNumRef();
        }
        if (cat.isSetStrRef()) {
            cat.unsetStrRef();
        }
        if (serie.isNumericCategories()) {
            CTNumRef numRef = cat.addNewNumRef();
            numRef.setF(graph.getSheetName() + "!$A:$A$" + (serie.getCategories().size() + 1));
            CTNumData data = numRef.addNewNumCache();
            data.setFormatCode("General");
            CTUnsignedInt cnt = data.addNewPtCount();
            cnt.setVal(serie.getCategories().size());
            int r = 0;
            for (String v : serie.getCategories()) {
                CTNumVal pt = data.addNewPt();
                pt.setIdx(r++);
                pt.setV(StringUtils.isBlank(v) ? "0" : v);
                if (delete) {
                    CTDLbl dlbl = ser.getDLbls().addNewDLbl();
                    dlbl.addNewIdx().setVal(r - 1);
                    dlbl.addNewDelete().setVal(true);
                }
            }
        }
        else {
            CTStrRef strRef = cat.addNewStrRef();
            strRef.setF(graph.getSheetName() + "!$A:$A$" + (serie.getCategories().size() + 1));
            CTStrData data = strRef.addNewStrCache();
            CTUnsignedInt cnt = data.addNewPtCount();
            cnt.setVal(serie.getCategories().size());
            int r = 0;
            for (String v : serie.getCategories()) {
                CTStrVal pt = data.addNewPt();
                pt.setIdx(r++);
                pt.setV(v);
                if (delete) {
                    CTDLbl dlbl = ser.getDLbls().addNewDLbl();
                    dlbl.addNewIdx().setVal(r - 1);
                    dlbl.addNewDelete().setVal(true);
                }
            }
        }
        // Values
        CTNumDataSource val = ser.getVal();
        val.unsetNumRef();
        CTNumRef numRef = val.addNewNumRef();
        char letter = (char) ('B' + s);
        numRef.setF(graph.getSheetName() + "!$" + letter + ":$" + letter + "$" + (serie.getValues().size() + 1));
        CTNumData data = numRef.addNewNumCache();
        data.setFormatCode("General");
        CTUnsignedInt cnt = data.addNewPtCount();
        cnt.setVal(serie.getValues().size());
        int r = 0;
        for (String v : serie.getValues()) {
            CTNumVal pt = data.addNewPt();
            pt.setIdx(r++);
            pt.setV(StringUtils.isBlank(v) ? "0" : v);
        }
        c.addNewSer().set(ser);
    }
    for (int s = 0; s < removeSeries; s++) {
        c.removeSer(0);
    }
}

总结:

  1. 克隆第一个 CT*Ser;
  2. 正在替换 idx、订单和 tx;
  3. 如果 CT*Ser 有 DLbls,里面有 DLbl 标签,我删除 DLbl,然后添加它们,并将 delete 设置为 true;
  4. 修改猫;
    1. 如果类别都是数值,我使用 NumRefs,否则使用 StrRefs;
  5. 修改值;
  6. 删除之前的系列

我也更改了支持 Excel 资源,仅使用构建图表的数据(绘图区域中每个图表有一个 sheet)。我也检查了对单元格和单元格范围的引用,它们没问题。

我用以下软件检查了生成的文件,报告结果:

是否有相对简单的方法来验证 powerpoint 文件并找出阻止文件与 powerpoint 一起工作的错误?有什么方法可以可靠地诊断这些问题吗?正在处理 linux?

已使用 Powerpoint 创建模板文件。很抱歉,如果我没有报告软件版本,但我不记得它们(Powerpoint 不在我的电脑上)。

请帮助我了解问题所在,因为我实际上开始觉得自己很愚蠢。任何建议将不胜感激。非常感谢。

我终于找到了问题所在(或者至少看起来是这样):如发布的代码中所示,对于每个图表,我将渐进式 ID 设置为 idx 并为元素设置顺序,但我从每个图表的 0 开始在绘图区。使每个绘图区域内的元素的 idx 和顺序保持唯一,它起作用了。

希望这对以后的人有所帮助。