Java poi 生成PPT并插入Excel附件并以图片形式显示代
- 前言
- 月报需求
- POI写法
- Maven依赖
- JAVA代码
前言
网上找的都不好使,没办法逼得我自己写了一个。还搜到个的贴子说不知道好不好使的一个帖子收费19.9,一生气我申请了一个9.9的,我这个保证好使的。效果如下:
1.大图,里边有一张小图。
2.点击小图,弹出EXCEL
月报需求
我的原始需求是生成一个月报,里边是当月的统计图,图片是前台传过来的一张做好的统计图我直接插入PPT就行,但是统计图里的数据需要以EXCEL作为附件放到PPT了,研究了好久,网上例子基本用不了,最后自己研究的。网上有一个Free Office的例子,但是这个例子的依赖,我下载依赖如下。
这个依赖有好多问题:
- 依赖太大了,一个jar50M左右,我整个项目的其他依赖加一起没这个依赖大。
- 这个依赖刚下载下来的时候360杀毒弹出了一个提示,说是有病毒,所以我没敢用。因为这个程序是要在客户机房里跑的,客户定期扫描出问题可就废了。
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.office.free</artifactId>
<version>3.9.0</version>
</dependency>
POI写法
没找到网上的例子,只能回来继续研究POI的写法,最后终于是实现了功能,代码如下:注意看注释
Maven依赖
<!-- poi office -->
<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>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>5.0.0</version>
</dependency>
JAVA代码
import org.apache.poi.sl.usermodel.ObjectMetaData;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.awt.geom.Rectangle2D;
import java.io.*;
/**
* 我的需求是在PPT里生成一个统计图,然后统计图里的数据以Excel的形式作为附件放在图片下边.
*
* @author Lwb
*/
public class PoiOleXlsInPpt {
public static void main(String[] args) throws IOException {
final ByteArrayInputStream pptBytes;
try (XMLSlideShow ppt = new XMLSlideShow()) {
//这个是插入一个统计图的图片
File image = new File("C:\\123\\123.jpg");
ppt.setPageSize(new java.awt.Dimension(1024, 600));
XSLFSlide slide = ppt.createSlide();
byte[] picture = IOUtils.toByteArray(new FileInputStream(image));
XSLFPictureData idx = ppt.addPicture(picture, PictureData.PictureType.EMF);
XSLFPictureShape pic = slide.createPicture(idx);
//设置为止
pic.setAnchor(new java.awt.Rectangle(0, 0, 1024, 600));
//插入的第2个图片,这个是作为EXCEL的图片,注意是EMF格式,要不会有点小问题
/**
* 注意看第31行的注释,必须得是EMF格式,而且这个格式不能强转改后缀名是不行的
* 我用的方式是先自己创建一个PPT插入我要用的图片,然后用解压缩软件去打开PPT
* 里边就能看到插入的那张图片,把那张图片拷贝出来然后再在程序里使用那张图片,就好了。
* */
final PictureData picData = ppt.addPicture(new FileInputStream("C:\\123\\123.efm"), PictureData.PictureType.EMF);
//在PPT里插入一个对象,跟你在PPT里点 插入(菜单)-对象是一样的,然后选择以图标显示是一样的
final XSLFObjectShape oleShape = slide.createOleShape(picData);
//设置这个图片的位置
oleShape.setAnchor(new Rectangle2D.Double(300, 280, 60, 60));
//设置附件格式是EXCEL
try (OutputStream os = oleShape.updateObjectData(ObjectMetaData.Application.EXCEL_V12, null)) {
//创建EXCEL并写入object对象的输出流
fillOleData(os);
}
//以图标展示的属性必须设置
oleShape.getCTOleObject().setShowAsIcon(true);
final ByteArrayOutputStream bos = new ByteArrayOutputStream(50000);
ppt.write(bos);
pptBytes = new ByteArrayInputStream(bos.toByteArray());
org.apache.poi.xslf.usermodel.XSLFObjectShape a;
//创建PPT文件
File pptx = new File("C:\\123\\123.pptx");
FileOutputStream p = new FileOutputStream(pptx);
ppt.write(p);
}
//这个是测试的
// try (SlideShow<?, ?> ppt = SlideShowFactory.create(pptBytes)) {
// final ObjectShape<?, ?> oleShape = (ObjectShape<?, ?>) ppt.getSlides().get(0).getShapes().get(1);
// try (InputStream bis = oleShape.readObjectData()) {
// validateOleData(bis);
// }
// }
}
//创建EXCEL的函数
private static void fillOleData(final OutputStream out) throws IOException {
//创建EXCEL
Workbook wb = new XSSFWorkbook();
//创建sheet页并写了一行数据
wb.createSheet().createRow(0).createCell(0).setCellValue("test me");
//输出数据
wb.write(out);
}
}