java生成自定义证书图片2 - 将word模板内容修改为自定义内容

接下来完成生成自定义数据的证书图片的第二部:将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格式证书就生成好了

猜你喜欢

转载自www.cnblogs.com/xhj123/p/12539642.html
今日推荐