簡體   English   中英

java-具有多個圖表的Apache POI繪圖區域

[英]java - Apache POI plot area with multiple charts

我正在嘗試使用PowerPoint文件作為模板來生成另一個替換購物車數據的PowerPoint。 為了使外觀與模板盡可能相似,我只是嘗試替換需要替換的數據,從圖表的第一個CT*Ser復制所有其他數據。 當繪圖區域內部僅包含一個圖表時,所有類型的圖表都可以正常工作(目前我對餅圖,條形圖和折線圖感興趣)。

當繪圖區域有多個圖表時(在我的情況下為具有多個系列的BarChart,而僅有一個為LineChart ),則看起來有些錯誤,並且Microsoft PowerPoint無法打開文件或文件的一部分,因為它似乎是受管理的。

為此,我對每個圖表和圖表類型執行以下代碼(graph是我用來在模板文件中保留引用的對象)。

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) + "$1");
        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$2:$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$2:$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 + "$2:$" + 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,order和tx;
  3. 如果CT * Ser中包含帶有blbl標簽的DLbl,則刪除DLbl,然后將delete設置為true來添加它們。
  4. 修改貓;
    1. 如果類別都是數字值,則使用NumRefs,否則使用StrRefs;
  5. 修改Val;
  6. 刪除以前的系列

我也更改了Excel支持資源,僅更改了用於構建圖形的數據(在繪圖區域中每個圖形有一張圖紙)。 我也檢查了對單元格和單元格范圍的引用,它們還可以。

我使用以下軟件檢查了產生的文件,並報告了結果:

  • Libre Office(按預期工作)
  • Onlyoffice(有效,但似乎每個區域不支持多個圖表嗎?)
  • Microsoft Powerpoint桌面(打開文件時出錯,嘗試還原,但失敗,並且不會從錯誤的幻燈片上加載幻燈片內容)
  • Microsoft Powerpoint在線(不會打開文件)

有沒有相對簡單的方法來驗證Powerpoint文件並查找導致文件無法與Powerpoint一起使用的錯誤? 有什么方法可以可靠地診斷這些問題? 在Linux上工作?

模板文件已使用Powerpoint創建。 如果我沒有報告軟件版本,但我不記得他們(Powerpoint不在我的PC上),我很抱歉。

請幫助我了解問題所在,因為我實際上開始感到愚蠢。 任何建議將不勝感激。 非常感謝。

我終於找到了問題所在(或至少看起來是這樣):如在發布的代碼中一樣,對於每個圖,我都將一個漸進ID設置為idx並為該元素設置順序,但是對於繪圖區域中的每個圖,我都從0開始。 對於每個繪圖區域內的元素,使這些idx和order保持唯一,它起作用了。

希望這可以在將來對某人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM