pom.xml
4.0.0
com.hys
docx4j
0.0.1-SNAPSHOT
org.docx4j
docx4j
3.3.6
org.docx4j
docx4j-export-fo
3.3.6
org.slf4j
slf4j-api
1.7.21
java代码
package com.docx4j.template;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.docx4j.Docx4J;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.P;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Text;
import org.docx4j.wml.Tr;
public class WordTemplate {
//加载模板
public static WordprocessingMLPackage getTemplate(String name) throws Docx4JException, FileNotFoundException {
WordprocessingMLPackage template = WordprocessingMLPackage.load(new FileInputStream(new File(name)));
return template;
}
//获取占位符
public static List getAllElementFromObject(Object obj, Class> toSearch) {
List result = new ArrayList();
if (obj instanceof JAXBElement) obj = ((JAXBElement>) obj).getValue();
if (obj.getClass().equals(toSearch))
result.add(obj);
else if (obj instanceof ContentAccessor) {
List> children = ((ContentAccessor) obj).getContent();
for (Object child : children) {
result.addAll(getAllElementFromObject(child, toSearch));
}
}
return result;
}
//替换占位符
public static void replacePlaceholder(WordprocessingMLPackage template, String name, String placeholder ) {
List texts = getAllElementFromObject(template.getMainDocumentPart(), Text.class);
for (Object text : texts) {
Text textElement = (Text) text;
if (textElement.getValue().equals(placeholder)) {
textElement.setValue(name);
}
}
}
//保存文档
public static void writeDocxToStream(WordprocessingMLPackage template, String target) throws Exception {
File f = new File(target);
//template.save(f);
OutputStream os = new FileOutputStream(f);
convertDocxToPDF(template, os);
}
/**
* docx文档转换为PDF
*
* @param mlPackage docx文档
* @param os PDF文档存储路径
* @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等
*/
public static void convertDocxToPDF(WordprocessingMLPackage mlPackage, OutputStream os) throws Exception {
try {
Mapper fontMapper = new IdentityPlusMapper();
fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
fontMapper.put("宋体",PhysicalFonts.get("SimSun"));
fontMapper.put("微软雅黑",PhysicalFonts.get("Microsoft Yahei"));
fontMapper.put("黑体",PhysicalFonts.get("SimHei"));
fontMapper.put("楷体",PhysicalFonts.get("KaiTi"));
fontMapper.put("新宋体",PhysicalFonts.get("NSimSun"));
fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
fontMapper.put("宋体扩展",PhysicalFonts.get("simsun-extB"));
fontMapper.put("仿宋",PhysicalFonts.get("FangSong"));
fontMapper.put("仿宋_GB2312",PhysicalFonts.get("FangSong_GB2312"));
fontMapper.put("幼圆",PhysicalFonts.get("YouYuan"));
fontMapper.put("华文宋体",PhysicalFonts.get("STSong"));
fontMapper.put("华文中宋",PhysicalFonts.get("STZhongsong"));
mlPackage.setFontMapper(fontMapper);
FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(mlPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);//FLAG_EXPORT_PREFER_XSL
}catch(Exception ex){
ex.printStackTrace();
}finally {
IOUtils.closeQuietly(os);
}
}
public void replaceParagraph(String placeholder, String textToAdd, WordprocessingMLPackage template, ContentAccessor addTo) {
// 1. get the paragraph
List paragraphs = getAllElementFromObject(template.getMainDocumentPart(), P.class);
P toReplace = null;
for (Object p : paragraphs) {
List texts = getAllElementFromObject(p, Text.class);
for (Object t : texts) {
Text content = (Text) t;
if (content.getValue().equals(placeholder)) {
toReplace = (P) p;
break;
}
}
}
// we now have the paragraph that contains our placeholder: toReplace
// 2. split into seperate lines
String as[] = StringUtils.splitPreserveAllTokens(textToAdd, '\n');
for (int i = 0; i < as.length; i++) {
String ptext = as[i];
// 3. copy the found paragraph to keep styling correct
P copy = (P) XmlUtils.deepCopy(toReplace);
// replace the text elements from the copy
List> texts = getAllElementFromObject(copy, Text.class);
if (texts.size() > 0) {
Text textToReplace = (Text) texts.get(0);
textToReplace.setValue(ptext);
}
// add the paragraph to the document
addTo.getContent().add(copy);
}
// 4. remove the original one
((ContentAccessor)toReplace.getParent()).getContent().remove(toReplace);
}
private void replaceTable(String[] placeholders, List> textToAdd,
WordprocessingMLPackage template) throws Docx4JException, JAXBException {
List tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class);
// 1. find the table
Tbl tempTable = getTemplateTable(tables, placeholders[0]);
List rows = getAllElementFromObject(tempTable, Tr.class);
// first row is header, second row is content
if (rows.size() == 2) {
// this is our template row
Tr templateRow = (Tr) rows.get(1);
for (Map replacements : textToAdd) {
// 2 and 3 are done in this method
addRowToTable(tempTable, templateRow, replacements);
}
// 4. remove the template row
tempTable.getContent().remove(templateRow);
}
}
public Tbl getTemplateTable(List tables, String templateKey) throws Docx4JException, JAXBException {
for (Iterator iterator = tables.iterator(); iterator.hasNext();) {
Object tbl = iterator.next();
List> textElements = getAllElementFromObject(tbl, Text.class);
for (Object text : textElements) {
Text textElement = (Text) text;
if (textElement.getValue() != null && textElement.getValue().equals(templateKey))
return (Tbl) tbl;
}
}
return null;
}
public static void addRowToTable(Tbl reviewtable, Tr templateRow, Map replacements) {
Tr workingRow = (Tr) XmlUtils.deepCopy(templateRow);
List> textElements = getAllElementFromObject(workingRow, Text.class);
for (Object object : textElements) {
Text text = (Text) object;
String replacementValue = (String) replacements.get(text.getValue());
if (replacementValue != null)
text.setValue(replacementValue);
}
reviewtable.getContent().add(workingRow);
}
public static void main(String[] args) throws Exception {
String templatefile = "E:/dianziqianzhang/gh.docx";
String target = "E:/dianziqianzhang/target.pdf";
WordprocessingMLPackage template = getTemplate(templatefile);
replacePlaceholder(template, "张三", "{name}");
writeDocxToStream(template, target);
}
}