2

我有一个 pptx 模板,它只有一张幻灯片用于测试目的。幻灯片有一个简单的条形图。我可以通过在 pptx 文件上双击条形图来编辑条形图,并且可以更改 Sheet1(条形图的数据表)中的值,并且可以立即在条形图中看到更改。

现在,我正在尝试使用 POI API 来做同样的事情。我在这里执行以下步骤

  1. 阅读模板文件 = “MyTemplate.pptx” - https://docs.google.com/file/d/0B-q0lBy0lKLic3dCSUVsZUdGQzA/edit?usp=sharing
  2. 拥有地图中的所有形状
  3. 通过引用其名称来阅读 BarChart 形状 - “MyBarChart”
  4. 读取条形图的excel文件
  5. 更新 Sheet1 中的单元格值
  6. 保存所有内容并写入另一个文件 - “MyPresentation.pptx”

当我打开文件“MyPresentation.pptx”时,它不会在栏中预先显示更新的单元格值。我需要双击图表将其更改为 EDIT 模式以获取反映的最新值。为什么使用 POI 更新底层数据表时,BarChart 没有刷新?

有什么建议可以解决这个问题吗?

这是完整的代码,以及附加的 pptx 模板文件。

package com.ppt;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFGraphicFrame;
import org.apache.poi.xslf.usermodel.XSLFShape;
import org.apache.poi.xslf.usermodel.XSLFSheet;
import org.apache.poi.xslf.usermodel.XSLFSlide;

public class PPTChart {

    public static void main(String args[]) throws InvalidFormatException, IOException{ 

        XMLSlideShow ppt;

        // Read pptx template
        ppt = new XMLSlideShow(new FileInputStream("MyTemplate.pptx"));

        // Get all slides
        XSLFSlide[] slide = ppt.getSlides();

        // Get working slide that is slide=0
        XSLFSlide slide0 = slide[0];
        XSLFShape[] shapes = slide0.getShapes();

        // Add all shapes into a Map
        Map <String, XSLFShape> shapesMap = new HashMap<String, XSLFShape>();
        for(XSLFShape shape : shapes)
        {
            shapesMap.put(shape.getShapeName(), shape);
            System.out.println(shape.getShapeName() + "  " + shape.getShapeId() + "   " + shape);

        }

        // Read the bar chart
        XSLFGraphicFrame chart = (XSLFGraphicFrame) shapesMap.get("MyBarChart");

        // Get the chart sheet
        XSLFSheet sheet =  chart.getSheet();

        for(int i=0; i<sheet.getRelations().size(); i++)
        {
            System.out.println("Partname =" + sheet.getRelations().get(i).getPackagePart().getPartName());



            if(sheet.getRelations().get(i).getPackagePart().getPartName().toString().contains(".xls"))
            {

                System.out.println("Found the bar chart excel");

                // BarChart Excel package part
                PackagePart barChartExcel  = sheet.getRelations().get(i).getPackagePart();

                // Reference the excel in workbook
                HSSFWorkbook wb = new HSSFWorkbook(barChartExcel.getInputStream());

                // Read sheet where Barchart data is available
                HSSFSheet mysheet =  wb.getSheetAt(1);

                // Read first
                HSSFRow row = mysheet.getRow(1);


                //Print first cell value for debugging
                System.out.println("Updating cell value from - " + row.getCell(1));

                // New value
                double insertValue = 7777777.0;


                wb.getSheetAt(1).getRow(1).getCell(1).setCellValue(insertValue);

                // Set first BarChart as active sheet
                HSSFSheet mysheet0 =  wb.getSheetAt(0);
                mysheet0.setActive(true);

                // Write the updated excel back to workbook
                OutputStream excelOut = barChartExcel.getOutputStream();
                excelOut.flush();
                wb.write(excelOut);
                excelOut.close();

                // Write workbook to file
                FileOutputStream o = new FileOutputStream("MyPresentation.pptx");
                ppt.write(o);
                o.close();
                System.out.println("new ppt is created....");

                break; // Exit
            }

        }
    }
}
4

2 回答 2

1

Here is the code you'd use to do it with pptx4j.

You ought to be able to convert that to equivalent POI code.

Note that the pptx4j code is updating an OpenXML spreadsheet, whereas your code is targeting the legacy binary format.

于 2013-07-28T01:31:36.223 回答
1

I'm working on something similar right now. Check out the thread link below for actually updating the chart visuals. You have to modify the plot area portion of the underlying XML.

How can one programmatically read the graph values from a Powerpoint presentation using Apache's POI?

于 2016-04-03T05:00:23.727 回答