maven导入
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
<version>1.0.6</version>
</dependency>
代码如下
package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
public class Demo {
public static void main(String[] args) throws Exception {
System.out.println("begin!");
//word模板地址、文字图片合成后的word地址、手写签名图片、合成pdf写入的地址
String sourceFile = "D:\\Users\\os-zhangh002\\Desktop\\template.docx";
String targetFile = "D:\\Users\\os-zhangh002\\Desktop\\test2.docx";
String imgFile = "D:\\Users\\os-zhangh002\\Desktop\\1111111.png";
String pdfFile = "D:\\Users\\os-zhangh002\\Desktop\\tangqiao.pdf";
String companySealFile = "D:\\Users\\os-zhangh002\\Desktop\\si.png";
//word中设置的文字变量 man、number、companyName、day、YY、MM、DD (将word中这些变量替换成map中的value值)
//word中设置的手写签名图片变量 SS (将word中此变量替换成手写签名图片)
//word中设置的手写签名图片变量 ZZ (将word中此变量替换成公司签章图片)
Map<String, String> map = new HashMap<>();
map.put("man", "os-zhangh002");
map.put("number", "123456789123456789");
map.put("companyName", "开发人员所属公司");
map.put("day", "2022年3月23日");
map.put("YY", "2022");
map.put("MM", "03");
map.put("DD", "23");
docEdit(sourceFile, targetFile, imgFile, map, companySealFile);
doc2pdf(targetFile, pdfFile);
System.out.println(pdfFile);
}
/**
* word 模板处理:变量文字替换、图片添加
*
* @param sourceFile
* @param targetFile
* @param imgFile
* @param map
*/
public static void docEdit(String sourceFile, String targetFile, String imgFile, Map map, String companySealFile) {
XWPFDocument doc;
try {
doc = new XWPFDocument(POIXMLDocument.openPackage(sourceFile));
Iterator<XWPFParagraph> itPara = doc.getParagraphsIterator();
while (itPara.hasNext()) {
XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
List<XWPFRun> runs = paragraph.getRuns();
for (int i = 0; i < runs.size(); i++) {
String oneparaString = runs.get(i).getText(runs.get(i).getTextPosition());
System.out.println(oneparaString);
//遍历XWPFRun时文字处理
for (Object key : map.keySet()) {
if (key.equals(oneparaString)) {
oneparaString = oneparaString.replace((String) key, (String) map.get(key));
runs.get(i).setText(oneparaString, 0);
}
}
//遍历XWPFRun时手写签名图片处理
if ("SS".equals(oneparaString)) {
FileInputStream is = new FileInputStream(imgFile);
oneparaString = oneparaString.replace("SS", "");
runs.get(i).setText(oneparaString, 0);
runs.get(i).addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(40), Units.toEMU(40));
is.close();
}
//遍历XWPFRun时公司签章浮印处理
if ("ZZ".equals(oneparaString)) {
FileInputStream is = new FileInputStream(companySealFile);
runs.get(i).addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(40), Units.toEMU(40));
oneparaString = oneparaString.replace("ZZ", "");
runs.get(i).setText(oneparaString, 0);
is.close();
CTDrawing drawing1 = runs.get(i).getCTR().getDrawingArray(0);
CTGraphicalObject graphicalobject1 = drawing1.getInlineArray(0).getGraphic();
//拿到新插入的图片替换添加CTAnchor 设置浮动属性 删除inline属性
CTAnchor anchor1 = getAnchorWithGraphic(graphicalobject1, "seal",
Units.toEMU(200), Units.toEMU(200),//图片宽高大小
Units.toEMU(40), Units.toEMU(-30), true);//相对当前位置:左右偏移、上下偏移
drawing1.setAnchorArray(new CTAnchor[]{anchor1});//添加浮动属性
drawing1.removeInline(0);//删除行内属性
}
}
}
FileOutputStream fos = new FileOutputStream(targetFile);
doc.write(fos);
fos.close();
//写成word格式
doc.write(new FileOutputStream(targetFile));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* word 转 pdf
*
* @param docFileName
* @param targetFile
* @throws Exception
*/
public static void doc2pdf(String docFileName, String targetFile) throws Exception {
String docPath = docFileName;
String pdfPath = targetFile;
XWPFDocument document;
InputStream doc = new FileInputStream(docPath);
document = new XWPFDocument(doc);
PdfOptions options = PdfOptions.create();
OutputStream out = new FileOutputStream(pdfPath);
PdfConverter.getInstance().convert(document, out, options);
doc.close();
out.close();
}
public static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject,
String deskFileName, int width, int height,
int leftOffset, int topOffset, boolean behind) {
String anchorXML =
"<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
+ "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
+ "<wp:simplePos x=\"0\" y=\"0\"/>"
+ "<wp:positionH relativeFrom=\"column\">"
+ "<wp:posOffset>" + leftOffset + "</wp:posOffset>"
+ "</wp:positionH>"
+ "<wp:positionV relativeFrom=\"paragraph\">"
+ "<wp:posOffset>" + topOffset + "</wp:posOffset>" +
"</wp:positionV>"
+ "<wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>"
+ "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
+ "<wp:wrapNone/>"
+ "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" + deskFileName + "\"/><wp:cNvGraphicFramePr/>"
+ "</wp:anchor>";
CTDrawing drawing = null;
try {
drawing = CTDrawing.Factory.parse(anchorXML);
} catch (XmlException e) {
e.printStackTrace();
}
CTAnchor anchor = drawing.getAnchorArray(0);
anchor.setGraphic(ctGraphicalObject);
return anchor;
}
}