项目中遇到一个需求是生成PPT文件,但是一般来说,PPT会比较复杂,我们的做法是先用WPS或者Powerpoint制作好模板PPT文件(模板文件里使用文本占位符${placeholder}来表示要替换的地方),然后读取模板文件,生成实际需要的PPT文件。
如图,使用文本占位符:
代码如下:
public void generatePPT() {
// 读取模板ppt
Path path = Paths.get(pptTemplateFile);
XMLSlideShow templatePPT = new XMLSlideShow(Files.newInputStream(path));
// 生成的PPT
XMLSlideShow ppt0 = new XMLSlideShow(Files.newInputStream(path));
List<XSLFSlide> slides0 = templatePPT.getSlides();
// ppt0也是从模板复制过来的,先删除里面所有的页面,然后再一个一个的添加
for (int j = slides0.size() - 1; j >= 0; j--) {
ppt0.removeSlide(j);
}
List<XSLFSlide> slides = templatePPT.getSlides();
// 要替换的模板PPT的第几页
XSLFSlide slide = slides.get(8);
XSLFSlide slide1 = ppt0.createSlide();
slide1.importContent(slide);
// 替换文本内容
String className = "五年级4班";
replaceSlideTextContent(slide1, "${className}", className, 22.0, Color.WHITE);
byte[] imageData = ...;//准备要替换的图片
PictureData pictureData = ppt0.addPicture(imageData, XSLFPictureData.PictureType.JPEG);
replaceSlidePicture(slide1, "${classCourseQR}", pictureData);
// 其他页面可以继续一页一页的添加
}
// 用图片替换占位符
private void replaceSlidePicture(XSLFSlide slide, String pattern, PictureData pictureData) {
List<XSLFShape> shapes = slide.getShapes();
for (int i = 0; i < shapes.size(); i++) {
Rectangle2D anchor = shapes.get(i).getAnchor();
if (shapes.get(i) instanceof XSLFTextBox) {
XSLFTextBox txShape = (XSLFTextBox) shapes.get(i);
if (txShape.getText().contains(pattern)) {
XSLFPictureShape xslfPictureShape = slide.createPicture(pictureData);
xslfPictureShape.setAnchor(anchor);
slide.removeShape(txShape);
}
}
}
}
// 用文本替换占位符,可以设置字体大小和颜色
private void replaceSlideTextContent(XSLFSlide slide, String pattern, String content, Double fontSize, Color textColor) {
List<XSLFShape> shapes = slide.getShapes();
for (int i = 0; i < shapes.size(); i++) {
if (shapes.get(i) instanceof XSLFTextBox) {
XSLFTextBox txShape = (XSLFTextBox) shapes.get(i);
if (txShape.getText().contains(pattern)) {
// 替换文字内容.用TextRun获取替换的文本来设置样式
txShape.setText(txShape.getText().replace(pattern, content));
setSlideTextFont(txShape.getTextParagraphs(), fontSize, textColor);
}
}
}
}
private void setSlideTextFont(List<XSLFTextParagraph> textParagraphs, Double fontSize, Color textColor) {
if (textParagraphs.isEmpty()) {
return;
}
textParagraphs.forEach(textParagraph -> {
List<XSLFTextRun> textRuns = textParagraph.getTextRuns();
textRuns.get(0).setFontSize(fontSize);
textRuns.get(0).setFontColor(textColor);
textRuns.get(0).setFontFamily("微软雅黑");
});
}

文章评论