,POI3.15版本. 在模板中构造几中基本图表进行测试就行了.
完整下载地址:http://download.csdn.net/detail/mike_caoyong/9841635
其它操作ppt的基础资料见:http://blog.csdn.net/mike_caoyong/article/details/28651665
1 . 图表数据类
import java.util.List;
/**
* 图表系列数据
*
* @author caoyong
*
*/
public class GraphData
{
// 图形标题
private String title;
// 系列值
private List
public GraphData(String title, List
{
this.title = title;
this.serList = serList;
}
public String getTitle()
{
return title;
}
public List
{
return serList;
}
}
class SeriesData
{
// 系列名称
private String serName;
// 系列值
private double serVal;
public SeriesData(String serName, double serVal)
{
this.serName = serName;
this.serVal = serVal;
}
public String getSerName()
{
return serName;
}
public double getSerVal()
{
return serVal;
}
}
2. pptl图表操作公共类
import java.io.IOException;
import java.io.OutputStream;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFChart;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAreaChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAreaSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrVal;
/**
* PPT公具类
*
* @author CAOYONG
*
*/
public class PPTGrapthUtils
{
public static void updateGraph(XSLFChart chart, GraphData graphData)
{
String type = PPTGrapthUtils.getGraphType(chart);
if ("pie".equalsIgnoreCase(type))
{
PPTGrapthUtils.refreshPieGraph(chart, graphData);
} else if ("bar".equalsIgnoreCase(type))
{
refreshBarGraph(chart, graphData);
} else if ("line".equalsIgnoreCase(type))
{
refreshLineGraph(chart, graphData);
} else if ("area".equalsIgnoreCase(type))
{
refreshAreaGraph(chart, graphData);
}
System.out.println("updateGraph type:" + type);
}
/**
* 判断PPT图表类型(注意需要依赖:ooxml-schemas-1.1.jar)
*
* @param pptx
*/
public static void judgeGraphSheetType(XMLSlideShow pptx)
{
int pageIdx = 1;
for (XSLFSlide slide : pptx.getSlides())
{
for (POIXMLDocumentPart part : slide.getRelations())
{
if (part instanceof XSLFChart)
{
XSLFChart chart = (XSLFChart) part;
CTPlotArea plot = chart.getCTChart().getPlotArea();
judgeGraphSheetType(plot, pageIdx);
}
}
pageIdx++;
}
}
// 具体判断
private static void judgeGraphSheetType(CTPlotArea plot, int pageIdx)
{
StringBuffer infos = new StringBuffer();
if (null != plot && plot.getBarChartList().size() > 0)
{
infos.append("pageIdx:" + pageIdx + " has 柱状图");
infos.append(" DetailInfo: \n ");
for (CTBarSer ser : plot.getBarChartList().get(0).getSerList())
{
infos.append(getGraphTitle(ser.getTx()));
infos.append(" ");
String info = getGraphDetailInfo(ser.getCat());
ser.getTx();
if (info.length() > 0)
{
infos.append(info + "\n");
}
}
} else if (null != plot && plot.getPieChartList().size() > 0)
{
infos.append("pageIdx:" + pageIdx + " has 圆饼图");
infos.append(" DetailInfo: \n ");
for (CTPieSer ser : plot.getPieChartList().get(0).getSerList())
{
infos.append(getGraphTitle(ser.getTx()));
infos.append(" ");
String info = getGraphDetailInfo(ser.getCat());
if (info.length() > 0)
{
infos.append(info + "\n");
}
}
} else if (null != plot && plot.getLineChartList().size() > 0)
{
infos.append("pageIdx:" + pageIdx + " has 线性图");
infos.append(" DetailInfo: \n ");
for (CTLineSer ser : plot.getLineChartList().get(0).getSerList())
{
infos.append(getGraphTitle(ser.getTx()));
infos.append(" ");
String info = getGraphDetailInfo(ser.getCat());
if (info.length() > 0)
{
infos.append(info + "\n");
}
}
} else if (null != plot && plot.getAreaChartList().size() > 0)
{
infos.append("pageIdx:" + pageIdx + " has 面积图");
infos.append(" DetailInfo: \n ");
for (CTAreaSer ser : plot.getAreaChartList().get(0).getSerList())
{
infos.append(getGraphTitle(ser.getTx()));
infos.append(" ");
String info = getGraphDetailInfo(ser.getCat());
if (info.length() > 0)
{
infos.append(info + "\n");
}
}
}
// 还可以判断其它图
System.out.println(infos.toString());
}
// 得到图表标题
private static String getGraphTitle(CTSerTx tx)
{
StringBuilder infos = new StringBuilder();
if (null != tx && null != tx.getStrRef())
{
for (CTStrVal val : tx.getStrRef().getStrCache().getPtList())
{
infos.append("Title ID:" + val.getIdx() + " V:" + val.getV());
}
infos.append("\n");
}
return infos.toString();
}
// 得到第系值
private static String getGraphDetailInfo(CTAxDataSource cat)
{
StringBuilder infos = new StringBuilder();
if (null != cat && null != cat.getStrRef())
{
for (CTStrVal val : cat.getStrRef().getStrCache().getPtList())
{
infos.append("ser ID:" + val.getIdx() + " V:" + val.getV());
}
}
return infos.toString();
}
/**
* 通过图表类型
*
* @param chart
* @return
*/
private static String getGraphType(XSLFChart chart)
{
String graphTye = "noSupport";
CTPlotArea plot = chart.getCTChart().getPlotArea();
if (null != plot && plot.getBarChartList().size() > 0)
{
graphTye = "bar";
} else if (null != plot && plot.getPieChartList().size() > 0)
{
graphTye = "pie";
} else if (null != plot && plot.getLineChartList().size() > 0)
{
graphTye = "line";
} else if (null != plot && plot.getAreaChartList().size() > 0)
{
graphTye = "area";
}
return graphTye;
}
// 刷新圆饼图
private static boolean refreshPieGraph(XSLFChart chart, GraphData graphData)
{
boolean result = true;
// 把图表绑定到Excel workbook中
try
{
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet();
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTPieChart pieChart = plotArea.getPieChartArray(0);
// 获取图表的系列
CTPieSer ser = pieChart.getSerArray(0);
// Series Text
CTSerTx tx = ser.getTx();
tx.getStrRef().getStrCache().getPtArray(0).setV(graphData.getTitle());
sheet.createRow(0).createCell(1).setCellValue(graphData.getTitle());
String titleRef = new CellReference(sheet.getSheetName(), 0, 1, true, true).formatAsString();
tx.getStrRef().setF(titleRef);
// Category Axis Data
CTAxDataSource cat = ser.getCat();
// 获取图表的值
CTNumDataSource val = ser.getVal();
refreshGraphContent(sheet, cat, val, graphData);
// 更新嵌入的workbook
POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();
try
{
wb.write(xlsOut);
xlsOut.close();
} catch (IOException e)
{
e.printStackTrace();
result = false;
} finally
{
if (wb != null)
{
try
{
wb.close();
} catch (IOException e)
{
e.printStackTrace();
result = false;
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
return result;
}
// 刷新柱状图
private static boolean refreshBarGraph(XSLFChart chart, GraphData graphData)
{
boolean result = true;
// 把图表绑定到Excel workbook中
try
{
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet();
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTBarChart pieChart = plotArea.getBarChartArray(0);
// 获取图表的系列
CTBarSer ser = pieChart.getSerArray(0);
// Series Text
CTSerTx tx = ser.getTx();
tx.getStrRef().getStrCache().getPtArray(0).setV(graphData.getTitle());
sheet.createRow(0).createCell(1).setCellValue(graphData.getTitle());
String titleRef = new CellReference(sheet.getSheetName(), 0, 1, true, true).formatAsString();
tx.getStrRef().setF(titleRef);
// Category Axis Data
CTAxDataSource cat = ser.getCat();
// 获取图表的值
CTNumDataSource val = ser.getVal();
refreshGraphContent(sheet, cat, val, graphData);
// 更新嵌入的workbook
POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();
try
{
wb.write(xlsOut);
xlsOut.close();
} catch (IOException e)
{
e.printStackTrace();
result = false;
} finally
{
if (wb != null)
{
try
{
wb.close();
} catch (IOException e)
{
e.printStackTrace();
result = false;
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
return result;
}
// 刷新线性图
private static boolean refreshLineGraph(XSLFChart chart, GraphData graphData)
{
boolean result = true;
// 把图表绑定到Excel workbook中
try
{
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet();
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTLineChart pieChart = plotArea.getLineChartArray(0);
// 获取图表的系列
CTLineSer ser = pieChart.getSerArray(0);
// Series Text
CTSerTx tx = ser.getTx();
tx.getStrRef().getStrCache().getPtArray(0).setV(graphData.getTitle());
sheet.createRow(0).createCell(1).setCellValue(graphData.getTitle());
String titleRef = new CellReference(sheet.getSheetName(), 0, 1, true, true).formatAsString();
tx.getStrRef().setF(titleRef);
// Category Axis Data
CTAxDataSource cat = ser.getCat();
// 获取图表的值
CTNumDataSource val = ser.getVal();
refreshGraphContent(sheet, cat, val, graphData);
// 更新嵌入的workbook
POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();
try
{
wb.write(xlsOut);
xlsOut.close();
} catch (IOException e)
{
e.printStackTrace();
result = false;
} finally
{
if (wb != null)
{
try
{
wb.close();
} catch (IOException e)
{
e.printStackTrace();
result = false;
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
return result;
}
// 刷新面积图
private static boolean refreshAreaGraph(XSLFChart chart, GraphData graphData)
{
boolean result = true;
// 把图表绑定到Excel workbook中
try
{
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet();
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTAreaChart pieChart = plotArea.getAreaChartArray(0);
// 获取图表的系列
CTAreaSer ser = pieChart.getSerArray(0);
// Series Text
CTSerTx tx = ser.getTx();
tx.getStrRef().getStrCache().getPtArray(0).setV(graphData.getTitle());
sheet.createRow(0).createCell(1).setCellValue(graphData.getTitle());
String titleRef = new CellReference(sheet.getSheetName(), 0, 1, true, true).formatAsString();
tx.getStrRef().setF(titleRef);
// Category Axis Data
CTAxDataSource cat = ser.getCat();
// 获取图表的值
CTNumDataSource val = ser.getVal();
refreshGraphContent(sheet, cat, val, graphData);
// 更新嵌入的workbook
POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();
try
{
wb.write(xlsOut);
xlsOut.close();
} catch (IOException e)
{
e.printStackTrace();
result = false;
} finally
{
if (wb != null)
{
try
{
wb.close();
} catch (IOException e)
{
e.printStackTrace();
result = false;
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
return result;
}
// 刷新图表内容
private static void refreshGraphContent(Sheet sheet, CTAxDataSource cat, CTNumDataSource val, GraphData graphData)
{
CTStrData strData = cat.getStrRef().getStrCache();
CTNumData numData = val.getNumRef().getNumCache();
// strData.set
strData.setPtArray((CTStrVal[]) null); // unset old axis text
numData.setPtArray((CTNumVal[]) null); // unset old values
// set model
long idx = 0;
int rownum = 1;
for (SeriesData seriesData : graphData.getSerList())
{
CTNumVal numVal = numData.addNewPt();
numVal.setIdx(idx);
numVal.setV(seriesData.getSerVal() + "");
CTStrVal sVal = strData.addNewPt();
sVal.setIdx(idx);
sVal.setV(seriesData.getSerName());
idx++;
Row row = sheet.createRow(rownum++);
row.createCell(0).setCellValue(seriesData.getSerName());
row.createCell(1).setCellValue(seriesData.getSerVal());
}
numData.getPtCount().setVal(idx);
strData.getPtCount().setVal(idx);
String numDataRange = new CellRangeAddress(1, rownum - 1, 1, 1).formatAsString(sheet.getSheetName(), true);
val.getNumRef().setF(numDataRange);
String axisDataRange = new CellRangeAddress(1, rownum - 1, 0, 0).formatAsString(sheet.getSheetName(), true);
cat.getStrRef().setF(axisDataRange);
}
}
3. 测试类:
package com.caoyong.ppt;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFChart;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* PPT图表测试类
*
* @author cy
*
*/
public class PPTGraphDemo
{
public static void main(String[] args)
{
String basePath = System.getProperty("user.dir") + File.separator + "testFile";
String templateFile = basePath + File.separator + "template.pptx";
String destFile = basePath + File.separator + "dest.pptx";
System.out.println("templateFile" + templateFile + " destFile:" + destFile);
String result = createNewPPT(templateFile, destFile);
System.out.println(result);
}
public static String createNewPPT(String templateFile, String destFile)
{
String result = "success";
XMLSlideShow pptx = null;
try
{
// 打开模板ppt
pptx = new XMLSlideShow(new FileInputStream(templateFile));
PPTGrapthUtils.judgeGraphSheetType(pptx);
for (XSLFSlide slide : pptx.getSlides())
{
for (POIXMLDocumentPart part : slide.getRelations())
{
if (part instanceof XSLFChart)
{
PPTGrapthUtils.updateGraph((XSLFChart) part, getGraphData());
}
}
}
// 内嵌excel的获取,添加数据简单示例
List
for (PackagePart part : embeds)
{
String type = part.getContentType();
System.out.println("Type:" + type);
// excel2003:application/vnd.ms-excel,记得不全了,可以自已试下.
// excel2007:aplication/vnd.openxmlformats-officedocument.package
Workbook wb;
if ("application/vnd.openxmlformats-officedocument.package".equalsIgnoreCase(type))
{
wb = new XSSFWorkbook(part.getInputStream());
} else
{
// 2003
wb = new HSSFWorkbook(part.getInputStream());
}
// 到这一步就可以获取excel的内容了.
// 注意图表也生成一个对应的excel,但只有一个sheet页且名称为sheet1
// 故模板中自已内嵌的模板最好sheet页名字不要用sheet1,这样就可以直接过滤掉图表的excel.
Iterator
Sheet sheet;
while(iter.hasNext())
{
sheet = iter.next();
if (sheet.getSheetName().equals("特定sheet页"))
{
// 创建行添加数据就行了,如行模板中有标题,可以从第1行开始添加数据
Row r = sheet.createRow(0);
r.createCell(0);
// ...
}
}
// excel中添加数据后,保存输出流
wb.write(part.getOutputStream());
// 关闭
wb.close();
}
// 保存文件
OutputStream out = new FileOutputStream(destFile);
pptx.write(out);
out.close();
} catch (IOException | OpenXML4JException e)
{
result = e.toString();
} finally
{
if (pptx != null)
{
try
{
pptx.close();
} catch (IOException e)
{
result = e.toString();
}
}
}
return result;
}
private static GraphData getGraphData()
{
List
SeriesData seriesData = new SeriesData("优", 10);
dataList.add(seriesData);
seriesData = new SeriesData("中", 150);
dataList.add(seriesData);
seriesData = new SeriesData("及格", 80);
dataList.add(seriesData);
seriesData = new SeriesData("不及格", 20);
dataList.add(seriesData);
GraphData graphData = new GraphData("成绩情况", dataList);
return graphData;
}
}
控制台输出:
模板截图:
输出后PPT: