docx4j之word模板

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.hys</groupId>
  <artifactId>docx4j</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
  	<dependency>
		  <groupId>org.docx4j</groupId>
		  <artifactId>docx4j</artifactId>
			<version>3.3.6</version>
	</dependency>
	
	<dependency>
	    <groupId>org.docx4j</groupId>
	    <artifactId>docx4j-export-fo</artifactId>
	    <version>3.3.6</version>
	</dependency>
	
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-api</artifactId>
		<version>1.7.21</version>
	</dependency>
	
  </dependencies>
</project>

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<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
		List<Object> result = new ArrayList<Object>();
		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<Object> 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<Object> paragraphs = getAllElementFromObject(template.getMainDocumentPart(), P.class);
 
		P toReplace = null;
		for (Object p : paragraphs) {
			List<Object> 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<Map<String, String>> textToAdd,
			WordprocessingMLPackage template) throws Docx4JException, JAXBException {
		List<Object> tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class);
 
		// 1. find the table
		Tbl tempTable = getTemplateTable(tables, placeholders[0]);
		List<Object> 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<String, String> 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<Object> tables, String templateKey) throws Docx4JException, JAXBException {
		for (Iterator<Object> 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<String, String> 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);
	}
}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值