POI操作PowerPoint自動(dòng)生成報(bào)表

1、需求

接到一個(gè)很蛋疼的需求:每天自動(dòng)查詢前一天的運(yùn)營數(shù)據(jù),生成power point圖表,發(fā)送給相關(guān)領(lǐng)導(dǎo)。

ppt有固定模板,只需要變更每張報(bào)表的數(shù)據(jù)源即可。

2、初步思路

操作office組件,第一個(gè)能想到的肯定是POI。

但實(shí)際上POI對(duì)于power point的操作封裝的還是很差的,畢竟沒誰閑的蛋疼用代碼來操作ppt。

POI操作power point更像是在操作XML的每個(gè)節(jié)點(diǎn),逐個(gè)取值、寫入(pptx文件格式本身就是xml)。

POI的maven依賴如下:

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.0.0</version>
        </dependency>

注意要用5.0版本,網(wǎng)上大多數(shù)資料里提到的3.17版本,無法讀取到圖表關(guān)聯(lián)的數(shù)據(jù)源。

3、Java實(shí)現(xiàn)

3-1、獲取圖表對(duì)象

        // 讀PPT模板
        File fileIn = new File(PPT_TEMPLATE);
        FileInputStream fin = new FileInputStream(fileIn);
        XMLSlideShow ppt = new XMLSlideShow(fin);
        fin.close();
        // 幻燈片對(duì)象
        XSLFSlide slide = ppt.getSlides().get(0);

        // ==============================================
        // 處理下部圖表(下idx=4)
        XSLFChart chart = slide.getRelationParts().get(4).getDocumentPart();
        CTPlotArea plot = chart.getCTChart().getPlotArea();
        CTBarChart barChart = plot.getBarChartArray(0);

至于為什么是slide.getRelationParts().get(4)?
呵呵,我特么也不知道我要操作的這個(gè)圖表的index是幾!

方法是debug一下,看slide.getRelationParts()對(duì)象的內(nèi)容,看它下面每一個(gè)item的documentPart的Name,是不是“/ppt/charts/chartn.xml”,這對(duì)應(yīng)的是圖表。

至于plot、barChart都是啥對(duì)象,鬼才知道,反正xml里面節(jié)點(diǎn)就是這樣的,就一層一層往下找吧,后面要用到。

3-2、更新圖表關(guān)聯(lián)的Excel數(shù)據(jù)源

要修改power point中報(bào)表的內(nèi)容,本質(zhì)上是修改跟報(bào)表綁定的Excel表的數(shù)據(jù)。

        // 更新圖表關(guān)聯(lián)的Excel數(shù)據(jù)源
        XSSFWorkbook workbook = chart.getWorkbook();
        // "sheet1"
        XSSFSheet sheet = workbook.getSheetAt(0);
        for (int i = 0; i < 10; i++) {
            sheet.getRow(i + 2).getCell(0).setCellValue(mapChartTitle.get(i));
            sheet.getRow(i + 2).getCell(1).setCellValue(mapChartData.get(i));
        }
        workbook.write(chart.getPackagePart().getOutputStream());

3-3、更新ppt緩存

power point這玩意,最x蛋的就是只變更數(shù)據(jù)源沒用,它自己有緩存!幻燈片上展示的數(shù)據(jù)從緩存來讀,如果只改變Excel數(shù)據(jù)源中的數(shù)據(jù),必須點(diǎn)“編輯數(shù)據(jù)”以后才能觸發(fā)頁面刷新。

        // 更新chart緩存數(shù)據(jù)
        CTBarSer ser = barChart.getSerList().get(0);
        // 變更坐標(biāo)軸標(biāo)題
        for (int i = 0; i < 10; i++) {
            CTStrVal cat = ser.getCat().getStrRef().getStrCache().getPtArray(i);
            cat.setIdx(i);
            cat.setV(mapChartBTitle.get(i));
        }
        // 變更數(shù)據(jù)
        for (int i = 0; i < 10; i++) {
            CTNumVal val = ser.getVal().getNumRef().getNumCache().getPtArray(i);
            val.setIdx(i);
            val.setV(mapChartBData.get(i).toString());
        }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容