接下來完成生成自定義數據的證書圖片的第二部:將docx格式的模板的字段替換為自定義數據
本文具體代碼和實例在 https://github.com/xuhaojin/certificate-generator
代碼如下:
package com.x.certificate.doc; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.IRunBody; 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.XmlCursor; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; import com.google.common.collect.Lists; import com.x.certificate.doc.domain.CertificateData; import com.x.certificate.doc.domain.CertificateField; /** * 復制證書doc模板文件,並將內容修改為自定義數據 * @author xuhaojin * @version [版本號, 2020年3月15日] */ public class DocOperator { public static File toCumstomDoc(String templatePath, String outputPath, CertificateData certificateData) throws IOException, XmlException { XWPFDocument document = new XWPFDocument(new FileInputStream(templatePath)); Set<String> keys = certificateData.getKeys(); for (XWPFParagraph paragraph : document.getParagraphs()) { XmlCursor cursor = paragraph.getCTP().newCursor(); cursor.selectPath( "declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//*/w:txbxContent/w:p/w:r"); List<XmlObject> xmlObjects = toXmlObjects(cursor); for (XmlObject xmlObject : xmlObjects) { CTR ctr = CTR.Factory.parse(xmlObject.xmlText()); XWPFRun bufferrun = new XWPFRun(ctr, (IRunBody) paragraph); String text = bufferrun.getText(0); String conformingKey = containsKey(text, keys); if (conformingKey != null) { CertificateField fieldInfo = certificateData.getValue(conformingKey); text = text.replace(toTemplateKey(conformingKey), fieldInfo.getContent()); bufferrun.setFontSize(fieldInfo.getFontSize()); bufferrun.setFontFamily(fieldInfo.getFontFamily()); bufferrun.setText(text, 0); bufferrun.setBold(fieldInfo.getIsBold()); } xmlObject.set(bufferrun.getCTR()); } } FileOutputStream out = new FileOutputStream(outputPath); document.write(out); out.close(); document.close(); return new File(outputPath); } public static List<XmlObject> toXmlObjects(XmlCursor docXmlCursor) { List<XmlObject> xmlObjects = Lists.newArrayList(); while (docXmlCursor.hasNextSelection()) { docXmlCursor.toNextSelection(); xmlObjects.add(docXmlCursor.getObject()); } return xmlObjects; } public static String containsKey(String text, Set<String> keys) { String conforming = null; if (StringUtils.isEmpty(text)) { return conforming; } for (String key : keys) { if (text.contains(key)) { conforming = key; break; } } return conforming; } public static String toTemplateKey(String key) { if (StringUtils.isEmpty(key)) { return null; } return "${" + key + "}"; } public static String addBlankSpace(String text) { StringBuffer sb = new StringBuffer(); if (text == null) { return null; } char[] chars = text.toCharArray(); String regex = "[\u4E00-\u9FA5]{1}"; for (char aChar : chars) { String str = aChar + ""; if (StringUtils.isBlank(str)) { continue; } sb.append(aChar); if (str.matches(regex)) { sb.append(" "); } } return sb.toString(); } public static void main(String[] args) throws IOException, XmlException { String templatePath = "C:\\Users\\a1579\\Desktop\\template.docx"; String outputPath = "C:\\Users\\a1579\\Desktop\\custom.docx"; CertificateData data = new CertificateData(); data.put(new CertificateField("持證人", addBlankSpace("張三"), 34)); data.put(new CertificateField("證書中文信息", "祝賀您完成\"直升機飛行員崗位資質\"培訓課程。特發此證!", 18)); data.put(new CertificateField("證書英文信息", "Congratulations on completion of training program of \"Helicopter Pilot Qualification\"", 15)); data.put(new CertificateField("證書編號", "100224512", 18)); data.put(new CertificateField("證書簽名", addBlankSpace("李四"), 25)); data.put(new CertificateField("證書日期", "2020年3月21日", 15)); toCumstomDoc(templatePath, outputPath, data); } }
其中主要引用的poi的jar包,引用如下:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>25.1-jre</version> </dependency>
證書模板docx為:
通過證書生成的自定義docx證書為:
這樣帶有自定義數據的docx格式證書就生成好了