文章目录
springboot之Docx4j操作pptx
一、引入依赖(清仔细阅读注释的部分 避免走弯路)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.docx4j/docx4j -->
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>6.1.2</version>
<exclusions>
<exclusion>
<groupId>org.plutext</groupId>
<artifactId>jaxb-svg11</artifactId>
</exclusion>
</exclusions>
<!--<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</exclusion>
</exclusions>-->
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.istack/istack-commons-runtime -->
<dependency>
<groupId>com.sun.istack</groupId>
<artifactId>istack-commons-runtime</artifactId>
<version>3.0.10</version>
</dependency>
<!--如果项目是运行在大于jdk8的情况下 需要添加一下两个依赖-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.4.0-b180830.0438</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
</dependencies>
二、两种方式获取pptx文件
1、直接创建pptx文件
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import java.io.File;
public class CreatePptx {
public static void main(String[] args) throws Docx4JException {
// Create skeletal package
PresentationMLPackage presentationMlPackage = PresentationMLPackage.createPackage();
String outputfilepath = System.getProperty("user.dir") + "/CreatePptx.pptx";
presentationMlPackage.save(new File(outputfilepath));
}
}
2、从模版读取
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import java.io.File;
public class ReadFromTemplate {
public static void main(String[] args) throws Docx4JException {
String inputfilepath = System.getProperty("user.dir") + "/template/read-from-template.pptx";
PresentationMLPackage presentationMlPackage = PresentationMLPackage.load(new File(inputfilepath));
String outputfilepath = System.getProperty("user.dir") + "/out-pptx/read-from-template.pptx";
presentationMlPackage.save(new File(outputfilepath));
}
}
三、添加一段文字
文字的样式 位置等等取决于
SAMPLE_SHAPE
字符串 至于这个字符串怎么获取 怎么去设置看上去是不是就很头大 没关系后面会教大家怎么制作这样的字符串
import org.docx4j.XmlUtils;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.PresentationML.MainPresentationPart;
import org.docx4j.openpackaging.parts.PresentationML.SlideLayoutPart;
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
import org.pptx4j.jaxb.Context;
import org.pptx4j.pml.Shape;
import java.io.File;
public class CreateHelloWorld {
public static void main(String[] args) throws Exception {
// Where will we save our new .ppxt?
String outputfilepath = System.getProperty("user.dir") + "/out-pptx/pptx-test.pptx";
// Create skeletal package, including a MainPresentationPart and a SlideLayoutPart
PresentationMLPackage presentationMLPackage = PresentationMLPackage.createPackage();
// Need references to these parts to create a slide
// Please note that these parts *already exist* - they are
// created by createPackage() above. See that method
// for instruction on how to create and add a part.
MainPresentationPart pp = (MainPresentationPart)presentationMLPackage.getParts().getParts().get(
new PartName("/ppt/presentation.xml"));
SlideLayoutPart layoutPart = (SlideLayoutPart)presentationMLPackage.getParts().getParts().get(
new PartName("/ppt/slideLayouts/slideLayout1.xml"));
// OK, now we can create a slide
SlidePart slidePart = new SlidePart(new PartName("/ppt/slides/slide1.xml"));
slidePart.setContents( SlidePart.createSld() );
pp.addSlide(0, slidePart);
// Slide layout part
slidePart.addTargetPart(layoutPart);
// Create and add shape
Shape sample = ((Shape)XmlUtils.unmarshalString(SAMPLE_SHAPE, Context.jcPML) );
slidePart.getContents().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame().add(sample);
// All done: save it
presentationMLPackage.save(new File(outputfilepath));
System.out.println("\n\n done .. saved " + outputfilepath);
}
private static String SAMPLE_SHAPE =
"<p:sp xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">"
+ "<p:nvSpPr>"
+ "<p:cNvPr id=\"4\" name=\"Title 3\" />"
+ "<p:cNvSpPr>"
+ "<a:spLocks noGrp=\"1\" />"
+ "</p:cNvSpPr>"
+ "<p:nvPr>"
+ "<p:ph type=\"title\" />"
+ "</p:nvPr>"
+ "</p:nvSpPr>"
+ "<p:spPr />"
+ "<p:txBody>"
+ "<a:bodyPr />"
+ "<a:lstStyle />"
+ "<a:p>"
+ "<a:r>"
+ "<a:rPr lang=\"en-US\" smtClean=\"0\" />"
+ "<a:t>Hello World</a:t>"
+ "</a:r>"
+ "<a:endParaRPr lang=\"en-US\" />"
+ "</a:p>"
+ "</p:txBody>"
+ "</p:sp>";
}
四、插入图片
import cn.hutool.core.util.RandomUtil;
import org.apache.commons.io.FileUtils;
import org.docx4j.XmlUtils;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.PresentationML.MainPresentationPart;
import org.docx4j.openpackaging.parts.PresentationML.SlideLayoutPart;
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.pptx4j.Pptx4jException;
import org.pptx4j.jaxb.Context;
import org.pptx4j.pml.Pic;
import javax.xml.bind.JAXBException;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
public class InsertPicture {
public static void main(String[] args) throws Exception {
String inputfilepath = System.getProperty("user.dir") + "/template/img-template.pptx";
PresentationMLPackage presentationMlPackage = PresentationMLPackage.load(new File(inputfilepath));
//博主就长图片里面这样
String imgPath = System.getProperty("user.dir") + "/img/WechatIMG66.jpeg";
createImageChartSlide(presentationMlPackage,imgPath);
System.out.println("\n\n saving .. \n\n");
String outputfilepath = System.getProperty("user.dir") + "/out-pptx/img-test.pptx";
presentationMlPackage.save(new File(outputfilepath));
System.out.println("\n\n done .. \n\n");
}
/**
* 创建对比分析图
*/
private static void createImageChartSlide(PresentationMLPackage presentationMlPackage,String imgPath) throws Pptx4jException, JAXBException, InvalidFormatException {
//两种方式
//直接获取已经知道的某个页面
SlidePart slidePart =
presentationMlPackage.getMainPresentationPart().getSlide(0);
//创建一个新的页面
/*SlidePart slidePart = createCommonSlide(presentationMlPackage,"/ppt/slides/slide1.xml");*/
try {
createImage(presentationMlPackage, slidePart, FileUtils.readFileToByteArray(new File(imgPath)), RandomUtil.randomNumbers(5), 0, 0, 7560000, 10692000);
} catch (IOException | JAXBException e) {
e.printStackTrace();
}
}
/**
* @param presentationMlPackage
* @param slidePart 添加图片所在的页面
* @param data 图片byte
* @param x 坐标轴
* @param y 坐标轴
* @param cx 宽
* @param cy 高
*/
private static void createImage(PresentationMLPackage presentationMlPackage,
SlidePart slidePart, byte[] data, String id, long x,
long y, long cx, long cy) throws JAXBException {
BinaryPartAbstractImage p_w_picpathPart = null;
try {
p_w_picpathPart = BinaryPartAbstractImage.createImagePart( presentationMlPackage, slidePart, data);
} catch (Exception e) {
e.printStackTrace();
}
if (p_w_picpathPart == null){
return;
}
HashMap<String,Object> mappings = new HashMap<>();
mappings.put("id1", id);
mappings.put("name", "");
mappings.put("descr", "");
mappings.put("rEmbedId", p_w_picpathPart.getSourceRelationship().getId());
// 注意,下面是图片位置的坐标
mappings.put("offx", Long.toString(x)); //坐标轴
mappings.put("offy", Long.toString(y));//坐标轴
mappings.put("extcx", Long.toString(cx));//图片宽
mappings.put("extcy", Long.toString(cy));//图片高
Object o = XmlUtils.unmarshallFromTemplate(p_w_picpathXml, mappings, Context.jcPML, Pic.class);
slidePart.getJaxbElement().getCSld().getSpTree() .getSpOrGrpSpOrGraphicFrame().add(o);
}
/**
* 图片XML
*/
private static final String p_w_picpathXml = "<p:pic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" "
+ "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" "
+ "xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">"
+ "<p:nvPicPr><p:cNvPr id=\"${id1}\" name=\"${name}\" descr=\"${descr}\"/>"
+ "<p:cNvPicPr><a:picLocks noChangeAspect=\"1\"/></p:cNvPicPr><p:nvPr/></p:nvPicPr>"
+ "<p:blipFill><a:blip r:embed=\"${rEmbedId}\" cstate=\"print\"/><a:stretch><a:fillRect/>"
+ "</a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x=\"${offx}\" y=\"${offy}\"/>"
+ "<a:ext cx=\"${extcx}\" cy=\"${extcy}\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/>"
+ "</a:prstGeom></p:spPr></p:pic>";
static SlidePart createCommonSlide(PresentationMLPackage presentationMLPackage, String partName) throws InvalidFormatException, JAXBException {
MainPresentationPart pp = (MainPresentationPart) presentationMLPackage.getParts().getParts().get(
new PartName("/ppt/presentation.xml"));
SlideLayoutPart layoutPart = (SlideLayoutPart) presentationMLPackage.getParts().getParts().get(
new PartName("/ppt/slideLayouts/slideLayout1.xml"));
return PresentationMLPackage.createSlidePart(pp, layoutPart,
new PartName(partName));
}
}
五、插入表格
样式类似于这样
import org.docx4j.dml.CTPoint2D;
import org.docx4j.dml.CTRegularTextRun;
import org.docx4j.dml.CTSRgbColor;
import org.docx4j.dml.CTSolidColorFillProperties;
import org.docx4j.dml.CTTable;
import org.docx4j.dml.CTTableCell;
import org.docx4j.dml.CTTableCellProperties;
import org.docx4j.dml.CTTableCol;
import org.docx4j.dml.CTTableGrid;
import org.docx4j.dml.CTTableProperties;
import org.docx4j.dml.CTTableRow;
import org.docx4j.dml.CTTextBody;
import org.docx4j.dml.CTTextCharacterProperties;
import org.docx4j.dml.CTTextParagraph;
import org.docx4j.dml.Graphic;
import org.docx4j.dml.GraphicData;
import org.docx4j.dml.TextFont;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
import org.pptx4j.pml.CTGraphicalObjectFrame;
import javax.xml.bind.JAXBElement;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CreateTable {
public static void main(String[] args) throws Exception {
String inputfilepath = System.getProperty("user.dir") + "/template/table-template.pptx";
PresentationMLPackage presentationMlPackage = PresentationMLPackage.load(new File(inputfilepath));
//获取数据
List<List<List<String>>> rowData = new ArrayList<>();
for (int i = 0; i < 5; i++) {
rowData.add(getData());
}
SlidePart slidePart = presentationMlPackage.getMainPresentationPart().getSlide(0);
//往当前页面中添加表格
createTablePackage(presentationMlPackage, slidePart, getData(), 457200, 1054400);
String outfilepath = System.getProperty("user.dir") + "/out-pptx/table.pptx";
presentationMlPackage.save(new File(outfilepath));
}
public static List<List<String>> getData() {
List<List<String>> rowDatas = new ArrayList<>();
List<String> totalAyTitle = Arrays.asList("Column1", "Column2", "Column3", "Column4", "Column1", "Column2", "Column3", "Column4", "Column1", "Column2", "Column3", "Column4");
rowDatas.add(totalAyTitle);
for (int i = 0; i < 15; i++) {
rowDatas.add(Arrays.asList("A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D"));
}
return rowDatas;
}
/**
* 参考文章 https://blog.csdn.net/weixin_33858249/article/details/89902487
*
* @param presentationMLPackage
* @param rowDatas 数据
* @param AyX 坐标轴x
* @param AyY 坐标轴y
* @throws Exception
*/
public static void createTablePackage(PresentationMLPackage presentationMLPackage, SlidePart slidePart, List<List<String>> rowDatas, int AyX, int AyY) throws Exception {
createStTableSlide(presentationMLPackage, slidePart, rowDatas, AyX, AyY);
}
/**
* 创建表格
*/
private static void createStTableSlide(
PresentationMLPackage presentationMLPackage, SlidePart slidePart, List<List<String>> rowDatas, int AyX, int AyY) throws Exception {
createTable(slidePart, rowDatas, AyX, AyY);
}
/**
* @param slidePart
* @param rowDatas
* @param x
* @param y
*/
private static void createTable(SlidePart slidePart, List<List<String>> rowDatas, int x, int y) {
org.docx4j.dml.ObjectFactory objectFactory = new org.docx4j.dml.ObjectFactory();
org.pptx4j.pml.ObjectFactory graphicObjectFactory = new org.pptx4j.pml.ObjectFactory();
CTGraphicalObjectFrame graphicFrame = graphicObjectFactory.createCTGraphicalObjectFrame();
org.pptx4j.pml.CTGraphicalObjectFrameNonVisual nvGraphicFramePr = graphicObjectFactory.createCTGraphicalObjectFrameNonVisual();
org.docx4j.dml.CTNonVisualDrawingProps cNvPr = objectFactory.createCTNonVisualDrawingProps();
org.docx4j.dml.CTNonVisualGraphicFrameProperties cNvGraphicFramePr = objectFactory.createCTNonVisualGraphicFrameProperties();
org.docx4j.dml.CTGraphicalObjectFrameLocking graphicFrameLocks = objectFactory.createCTGraphicalObjectFrameLocking();
org.docx4j.dml.CTTransform2D xfrm = objectFactory.createCTTransform2D();
// 设置表格的位置
CTPoint2D ctPoint = objectFactory.createCTPoint2D();
ctPoint.setX(x);
ctPoint.setY(y);
xfrm.setOff(ctPoint);
Graphic graphic = objectFactory.createGraphic();
GraphicData graphicData = objectFactory.createGraphicData();
// 设置表格样式1
CTTable ctTable = objectFactory.createCTTable();
CTTableProperties ctTablePr = objectFactory.createCTTableProperties();
ctTablePr.setFirstRow(true);
ctTablePr.setBandRow(true);
ctTable.setTblPr(ctTablePr);
JAXBElement<CTTable> tbl = objectFactory.createTbl(ctTable);
CTTableGrid ctTableGrid = objectFactory.createCTTableGrid();
graphicFrame.setNvGraphicFramePr(nvGraphicFramePr);
nvGraphicFramePr.setCNvPr(cNvPr);
cNvPr.setName("1");
nvGraphicFramePr.setCNvGraphicFramePr(cNvGraphicFramePr);
cNvGraphicFramePr.setGraphicFrameLocks(graphicFrameLocks);
graphicFrameLocks.setNoGrp(true);
nvGraphicFramePr.setNvPr(graphicObjectFactory.createNvPr());
graphicFrame.setXfrm(xfrm);
xfrm.setExt(objectFactory.createCTPositiveSize2D());
graphicFrame.setGraphic(graphic);
graphic.setGraphicData(graphicData);
graphicData
.setUri("http://schemas.openxmlformats.org/drawingml/2006/table");
graphicData.getAny().add(tbl);
ctTable.setTblGrid(ctTableGrid);
int rowCells = rowDatas.get(0).size();
int cellWidth = 6645600 / rowCells;
for (int i = 0; i < rowCells; i++) {
ctTableGrid.getGridCol().add(createCol(cellWidth, objectFactory));
}
for (int j = 0; j < rowDatas.size(); j++) {
if ((j + 1) % 5 == 0 || j == 0) {
ctTable.getTr().add(createRow(rowDatas.get(j), objectFactory, "EFF4FF"));
} else {
ctTable.getTr().add(createRow(rowDatas.get(j), objectFactory, "FFFFFF"));
}
}
slidePart.getJaxbElement().getCSld().getSpTree()
.getSpOrGrpSpOrGraphicFrame().add(graphicFrame);
}
/**
* @param width
* @return
*/
private static CTTableCol createCol(int width, org.docx4j.dml.ObjectFactory objectFactory) {
CTTableCol gridCol = objectFactory.createCTTableCol();
gridCol.setW(width);
return gridCol;
}
/**
* @param datas
* @return
*/
private static CTTableRow createRow(List<String> datas, org.docx4j.dml.ObjectFactory objectFactory, String sRgb) {
CTTableRow ctTableRow = objectFactory.createCTTableRow();
for (String data : datas) {
ctTableRow.getTc().add(createCell(data, objectFactory, sRgb));
}
return ctTableRow;
}
/**
* @param value
* @return
*/
private static CTTableCell createCell(String value, org.docx4j.dml.ObjectFactory objectFactory, String sRgb) {
CTTableCell ctTableCell = objectFactory.createCTTableCell();
// 单元格文字
CTTextBody ctTextBody = objectFactory.createCTTextBody();
ctTextBody.setBodyPr(objectFactory.createCTTextBodyProperties());
ctTextBody.setLstStyle(objectFactory.createCTTextListStyle());
CTTextParagraph ctTextPr = objectFactory.createCTTextParagraph();
CTRegularTextRun run = objectFactory.createCTRegularTextRun();
CTTextCharacterProperties ctTpr = objectFactory
.createCTTextCharacterProperties();
// 14号字体
ctTpr.setSz(1200);
TextFont font = objectFactory.createTextFont();
font.setTypeface("微软雅黑");
ctTpr.setLatin(font);
ctTpr.setEa(font);
run.setRPr(ctTpr);
// 设置内容,不能为null
run.setT(value == null ? "" : value);
ctTextPr.getEGTextRun().add(run);
ctTextPr.setEndParaRPr(objectFactory.createCTTextCharacterProperties());
ctTextBody.getP().add(ctTextPr);
ctTableCell.setTxBody(ctTextBody);
CTTableCellProperties ctTableCellProperties = objectFactory.createCTTableCellProperties();
CTSolidColorFillProperties ctSolidColorFillProperties = objectFactory.createCTSolidColorFillProperties();
CTSRgbColor ctsRgbColor = new CTSRgbColor();
// ctsRgbColor.setVal("EFF4FF");
//单元格的颜色
ctsRgbColor.setVal(sRgb);
ctSolidColorFillProperties.setSrgbClr(ctsRgbColor);
ctTableCellProperties.setSolidFill(ctSolidColorFillProperties);
ctTableCell.setTcPr(ctTableCellProperties);
return ctTableCell;
}
}
六、占位符替换
import org.apache.commons.io.FileUtils;
import org.docx4j.TraversalUtil;
import org.docx4j.TraversalUtil.CallbackImpl;
import org.docx4j.dml.CTBlip;
import org.docx4j.dml.CTBlipFillProperties;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.pptx4j.Pptx4jException;
import javax.xml.bind.JAXBException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class TemplateReplaceSimple {
public static void main(String[] args) throws Docx4JException, Pptx4jException, JAXBException, IOException {
// Input file
String inputfilepath = System.getProperty("user.dir") + "/template/template-replace.pptx";
String imgPath = System.getProperty("user.dir") + "/img/Snipaste_2023-10-16_13-40-23.png";
// String replacements
HashMap<String, String> mappings = new HashMap<String, String>();
mappings.put("colour", "red");
// Image replacements
List<ImageReplacementDetails> imageReplacements = new ArrayList<ImageReplacementDetails>();
ImageReplacementDetails example1 = new ImageReplacementDetails();
example1.slideIndex = 0; //图片所在页面
example1.imageRelId = "rId1"; //至于这个 我也不是特别理解 但是大致猜测如下 pptx中有几张图片
example1.replacementImageBytes = FileUtils.readFileToByteArray(new File(imgPath));
imageReplacements.add(example1);
PresentationMLPackage presentationMLPackage =
(PresentationMLPackage)OpcPackage.load(new File(inputfilepath));
// First, the text replacements
List<SlidePart> slideParts=
presentationMLPackage.getMainPresentationPart().getSlideParts();
for (SlidePart slidePart : slideParts) {
slidePart.variableReplace(mappings);
}
// Second, the image replacements.
// We have a design choice here.
// Either we can replace text placeholders with images,
// or we can replace existing images with new images, but keep the XML specifying size etc
// Here I opt for the latter, so what we need is the relId and image bytes.
for( ImageReplacementDetails ird : imageReplacements) {
// its a bit inefficient to potentially traverse a single slide
// multiple times, but I've done it this way to keep this example simple
SlidePart slidePart=
presentationMLPackage.getMainPresentationPart().getSlide(ird.slideIndex);
SlidePicFinder traverser = new SlidePicFinder();
new TraversalUtil(slidePart.getJaxbElement().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame(), traverser);
for(org.pptx4j.pml.Pic pic : traverser.pics) {
CTBlipFillProperties blipFill = pic.getBlipFill();
if (blipFill!=null) {
CTBlip blip = blipFill.getBlip();
if (blip.getEmbed()!=null) {
String relId = blip.getEmbed();
// is this the one we want?
if (relId.equals(ird.imageRelId)) {
Part part = slidePart.getRelationshipsPart().getPart(relId);
try {
BinaryPartAbstractImage imagePart = (BinaryPartAbstractImage)part;
// you'll need to ensure that you replace like with like,
// ie png for png, not eg jpeg for png!
imagePart.setBinaryData(ird.replacementImageBytes);
} catch (ClassCastException cce) {
System.out.println(part.getClass().getName());
}
} else {
System.out.println(relId + " isn't a match for this replacement. ");
}
} else {
System.out.println("No a:blip/@r:embed");
}
}
}
}
System.out.println("\n\n saving .. \n\n");
String outputfilepath = System.getProperty("user.dir") + "/out-pptx/OUT_VariableReplace.pptx";
presentationMLPackage.save(new File(outputfilepath));
System.out.println("\n\n done .. \n\n");
}
static class ImageReplacementDetails {
int slideIndex;
String imageRelId;
byte[] replacementImageBytes;
}
static class SlidePicFinder extends CallbackImpl {
List<org.pptx4j.pml.Pic> pics = new ArrayList<org.pptx4j.pml.Pic>();
public List<Object> apply(Object o) {
if (o instanceof org.pptx4j.pml.Pic) {
pics.add((org.pptx4j.pml.Pic) o);
System.out.println("added pic");
}
return null;
}
}
}
七、pptx to xml
此处将设计好的pptx模版转换成XML格式,可以通过截取某一段XML代码作为
三、添加一段文字
插入的内容 经测试,只要你在模版中的样式设计好,添加一段文字的样式也会是一摸一样的
注意:截取的一点XML 可能需要你加上类似于如下的头部标签:
xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">
可以参考
CreateHelloWorld
SAMPLE_SHAPE
字符串
import org.apache.commons.io.FileUtils;
import org.docx4j.convert.out.flatOpcXml.FlatOpcXmlCreator;
import org.docx4j.openpackaging.packages.OpcPackage;
import java.io.File;
public class ConvertOutFlatOpenPackage {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
String inputfilepath = System.getProperty("user.dir") + "/template/out-xml-template.pptx";
OpcPackage pptxPackage = OpcPackage.load(new File(inputfilepath));
FlatOpcXmlCreator worker = new FlatOpcXmlCreator(pptxPackage);
org.docx4j.xmlPackage.Package result = worker.get();
boolean suppressDeclaration = true;
boolean prettyprint = true;
String data =
org.docx4j.XmlUtils.
marshaltoString(result, suppressDeclaration, prettyprint,
org.docx4j.jaxb.Context.jcXmlPackage);
FileUtils.writeStringToFile(
new File(System.getProperty("user.dir") + "/out-pptx/pptx.xml"),
data);
}
}
八、页面删除
我有这样一个需求,模版pptx中有某些固定的页面,但是这些页面是需要根据用户的选择去显示的,所以我需要根据用户的选择删除那些不需要的页面。
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import org.docx4j.openpackaging.parts.PresentationML.MainPresentationPart;
import org.pptx4j.Pptx4jException;
import java.io.File;
public class RemoveSlide {
public static void main(String[] args) throws Docx4JException, Pptx4jException {
String inputfilepath = System.getProperty("user.dir") + "/template/remove.pptx";
PresentationMLPackage presentationMlPackage = PresentationMLPackage.load(new File(inputfilepath));
MainPresentationPart mainPresentationPart = presentationMlPackage.getMainPresentationPart();
//至于这里为什么是1 或者 是 rId3 是需要自己通过 ConvertOutFlatOpenPackage 方式转换成xml 然后自己去判断的
//方式1
mainPresentationPart.removeSlide(1);
//方式2
// Relationship rel = mainPresentationPart.getRelationshipsPart().getRelationshipByID("rId3");
// mainPresentationPart.removeSlide(rel);
System.out.println("\n\n saving .. \n\n");
String outputfilepath = System.getProperty("user.dir") + "/out-pptx/remove-later.pptx";
presentationMlPackage.save(new java.io.File(outputfilepath));
System.out.println("\n\n done .. \n\n");
}
}
九、在某个页面后面插入一个页面
import org.docx4j.XmlUtils;
import org.docx4j.dml.CTShapeProperties;
import org.docx4j.dml.CTTextParagraph;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.PresentationML.MainPresentationPart;
import org.docx4j.openpackaging.parts.PresentationML.SlideLayoutPart;
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
import org.pptx4j.Pptx4jException;
import org.pptx4j.jaxb.Context;
import org.pptx4j.pml.Shape;
import org.pptx4j.pml.Sld;
import org.pptx4j.pml.SldLayout;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class AddSlideIndex {
public static void main(String[] args) throws Docx4JException, Pptx4jException {
String inputfilepath = System.getProperty("user.dir") + "/template/add-slide.pptx";
PresentationMLPackage presentationMlPackage = PresentationMLPackage.load(new File(inputfilepath));
MainPresentationPart pp = presentationMlPackage.getMainPresentationPart();
SlideLayoutPart layoutPart = (SlideLayoutPart)presentationMlPackage.getParts().getParts().get(
new PartName("/ppt/slideLayouts/slideLayout1.xml"));
// OK, now we can create a slide
SlidePart slidePart = new SlidePart(new PartName("/ppt/slides/slide1.xml"));
int index = 1;
pp.addSlide(index, slidePart);
// Slide layout part
slidePart.addTargetPart(layoutPart);
// Copy certain placeholders from layout part
slidePart.setContents( extractFromLayout(layoutPart.getContents()) );
String outputfilepath = System.getProperty("user.dir") + "/out-pptx/add-slide.pptx";
presentationMlPackage.save(new java.io.File(outputfilepath));
}
private static Sld extractFromLayout(SldLayout sldLayout) {
// SlidePlaceholder.sldLayout = sldLayout;
Sld sld = Context.getpmlObjectFactory().createSld();
// Clone first
sld.setCSld(XmlUtils.deepCopy(sldLayout.getCSld(), Context.jcPML));
sld.setClrMapOvr(XmlUtils.deepCopy(sldLayout.getClrMapOvr(), Context.jcPML));
// Then delete stuff
sld.getCSld().setName(null);
// Remove p:sp, if cNvPr name contains "Date Placeholder", "Footer Placeholder", "Slide Number Placeholder"
// (and these are on the master?)
List<Shape> deletions = new ArrayList<Shape>();
for (Object o : sld.getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame()) {
//System.out.println(o.getClass().getName());
if (o instanceof Shape) {
Shape shape = (Shape)o;
if (shape.getNvSpPr()!=null
&& shape.getNvSpPr().getCNvPr()!=null
&& shape.getNvSpPr().getCNvPr().getName()!=null) {
String name = shape.getNvSpPr().getCNvPr().getName();
if (name.startsWith("Date Placeholder" )
|| name.startsWith( "Footer Placeholder" )
|| name.startsWith( "Slide Number Placeholder")) {
deletions.add(shape);
}
}
}
}
sld.getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame().removeAll(deletions);
// From remaining shapes ..
for (Object o : sld.getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame()) {
if (o instanceof Shape) {
Shape shape = (Shape)o;
shape.setSpPr(new CTShapeProperties());
if (shape.getTxBody()!=null) {
shape.getTxBody().setLstStyle(null);
for (CTTextParagraph p : shape.getTxBody().getP()) {
p.getEGTextRun().clear();
}
}
}
}
return sld;
}
}
注意事项
- 模版的样式(纸张大小、页边距等等 提前在WPS或者Office中设置好)