当前位置:   article > 正文

Java word动态数据填充并转为pdf最详细的讲解【附带源码项目】_java word 动态填充

java word 动态填充

Java Word数据动态填充,并将word转为pdf

适用范围:
1.已有word模板,word中的一些数据需要动态生成。
2.word转为pdf

本文章讲解的内容是一个完整的适用流程。就是首先是一个word模板,然后动态填充数据生成了一个新的word,填充数据之后最后转换成了pdf。
如果你只需要动态填充数据,得到一个新的word的话,适当修改下代码就可以了。说白了就是删代码,因为本身就用到了此功能。
如果你需要word转为pdf,适当修改下代码也是可以的。说白了还是删代码,因为本身也用到此功能。
发挥您的想象空间,此插件甚是强大。有问题联系我哦。代码注释里说了怎么找我…

话不多说,上干货,上代码…

Constants.java

package org.example.util;

/**
 * @author lucas
 * @program wtp-site
 * @description
 * @createDate 2020-03-04 23:05:31
 * 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
 * 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
 **/
public class Constants {


    /**
     * aspose需要的签名文件名称
     */
    public static String licensePath = "license.xml";

    /**
     * 模板,签名文件存放的路径(绝对路径哈,我这里是mac的绝对路径。)
     */
    public static String docXmlTemplatePath = "/Users/lisw/work/work-project/workTppdf/";
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

DocToPdf.java

package org.example.util;

import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;
/**
 * @author lucas
 * @program wtp-site
 * @description  word转pdf核心代码
 * @createDate 2020-03-04 23:05:31
 * 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
 * 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
 **/
public class DocToPdf {

    static String docTemplatePath = Constants.docXmlTemplatePath;
    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = new FileInputStream(docTemplatePath+Constants.licensePath);
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static  String DocToPdf(Map<String,Object> params,String documentXmlName,String documentDocName) throws Exception {
        try{
            if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
                return null;
            }

            String templateUUId = UUID.randomUUID().toString();
            String baseUrl=System.getProperty("java.io.tmpdir")+"/";
            String xml = baseUrl+templateUUId+".xml";
            XmlToDocx.toDocx(documentXmlName,docTemplatePath+documentDocName,xml,baseUrl+templateUUId+".docx",params);
            String docx = baseUrl+templateUUId+".docx";
            String pdf = baseUrl+templateUUId+".pdf";
            File file = new File(pdf); // 新建一个空白pdf文档
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(docx); // Address是将要被转化的word文档
            String osName = isWindows();
            String fonts [] = null;
            /**
             * 适配字体文件
             */
            if(osName.equals("linux")){
                fonts = new String[]{"/usr/share/fonts/chinese/","/usr/share/fonts/simsun/","/usr/share/fonts/black/","/usr/share/fonts/wingdings/"};
            }else if(osName.equals("mac")){
                fonts = new String[]{"/Users/fonts/chinese/","/Users/fonts/simsun/","/Users/fonts/black/","/Users/fonts/wingdings/"};
            }
            FontSettings.setFontsFolders(fonts, true);
            doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
            if(os!=null){
                os.close();
            }
            delete(xml,docx);//删除文件
            return pdf;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }

    }
    private static String isWindows() {
        String osName = System.getProperties().getProperty("os.name").toUpperCase();
        if(osName.indexOf("WINDOWS")!=-1){
            return "windows";
        }else if(osName.indexOf("MAC")!=-1){
            return "mac";
        }else{
            return "linux";
        }
    }
    public static void delete(String xmlPath,String wordPath){
        File file = new File(xmlPath);
        if(file.exists()){
            file.delete();
        }
        File wordFile = new File(wordPath);
        if(wordFile.exists()){
            wordFile.delete();
        }
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

XmlToDocx.java

package org.example.util;

import freemarker.template.TemplateException;

import java.io.*;
import java.util.Enumeration;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * @author lucas
 * @program wtp-site
 * @description word动态填充数据核心类
 * @createDate 2020-03-04 23:05:31
 * 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
 * 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
 **/
public class XmlToDocx {

    /**
     * @param xmlTemplate  xml的文件名
     * @param docxTemplate docx的路径和文件名
     * @param xmlTemp      填充完数据的临时xml
     * @param toFilePath   目标文件名
     * @param map          需要动态传入的数据
     * @throws IOException
     */
    public static void toDocx(String xmlTemplate, String docxTemplate, String xmlTemp, String toFilePath, Map map) {
        try {
            // 1.map是动态传入的数据
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
            Writer w1 = new OutputStreamWriter(new FileOutputStream(xmlTemp), "utf-8");
            // 2.把map中的数据动态由freemarker传给xml
            XmlTplUtil.process(xmlTemplate, map, w1);
            // 3.把填充完成的xml写入到docx中
            XmlToDocx xtd = new XmlToDocx();
            xtd.outDocx(new File(xmlTemp), docxTemplate, toFilePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param documentFile 动态生成数据的docunment.xml文件
     * @param docxTemplate docx的模板
     * @param toFilePath   需要导出的文件路径
     * @throws ZipException
     * @throws IOException
     */

    public void outDocx(File documentFile, String docxTemplate, String toFilePath) throws ZipException, IOException {

        try {
            File docxFile = new File(docxTemplate);
            ZipFile zipFile = new ZipFile(docxFile);
            Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
            ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(toFilePath));
            int len = -1;
            byte[] buffer = new byte[1024];
            while (zipEntrys.hasMoreElements()) {
                ZipEntry next = zipEntrys.nextElement();
                InputStream is = zipFile.getInputStream(next);
                // 把输入流的文件传到输出流中 如果是word/document.xml由我们输入
                zipout.putNextEntry(new ZipEntry(next.toString()));
                if ("word/document.xml".equals(next.toString())) {
                    InputStream in = new FileInputStream(documentFile);
                    while ((len = in.read(buffer)) != -1) {
                        zipout.write(buffer, 0, len);
                    }
                    in.close();
                } else {
                    while ((len = is.read(buffer)) != -1) {
                        zipout.write(buffer, 0, len);
                    }
                    is.close();
                }
            }
            zipout.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88

XmlTplUtil.java

package org.example.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;

/**
 * @author lucas
 * @program wtp-site
 * @description  word动态填充工具类
 * @createDate 2020-03-04 23:05:31
 * 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
 * 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
 **/
public class XmlTplUtil {

    private static XmlTplUtil tplm = null;
    private Configuration cfg = null;

    private XmlTplUtil() {
        cfg = new Configuration();
        try {
            cfg.setDirectoryForTemplateLoading(new File(Constants.docXmlTemplatePath));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static Template getTemplate(String name) throws IOException {
        if (tplm == null) {
            tplm = new XmlTplUtil();
        }
        Template template = tplm.cfg.getTemplate(name,"utf-8");
        return template;
    }

    /**
     * @param templatefile 模板文件
     * @param param        需要填充的内容
     * @param out          填充完成输出的文件
     * @throws IOException
     * @throws TemplateException
     */
    public static void process(String templatefile, Map param, Writer out) throws IOException, TemplateException {
        // 获取模板
        Template template = XmlTplUtil.getTemplate(templatefile);
        template.setOutputEncoding("utf-8");
        // 合并数据
        template.process(param, out);
        if (out != null) {
            out.close();
        }
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

App.java Main方法主类执行入口

package org.example;

import org.example.util.DocToPdf;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lucas
 * @program wtp-site
 * @description
 * @createDate 2020-03-04 23:05:31
 * 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
 * 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
 **/
public class App 
{
    /**
     * 注意事项
     * 1:如果转换之后有乱码现象,极大的概率是你的word当中用了系统不支持的字体。
     * 比如微软雅黑,你在本地windows上可能可以用,一旦你放到了服务器上面,Linux没有这个字体就会乱码。需要安装字体。
     * @param args
     * @throws Exception
     */
    public static void main( String[] args ) throws Exception {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("name","Lucas");
        String pdfPath = DocToPdf.DocToPdf(params, "document.xml", "template.docx");
        //pdfPath便是最后在系统磁盘里生成的绝对路径地址了,后续业务如果需要,可以读取这个路径进行把文件上传到云空间里或者其他地方。
        //如果上传到云空间了,记得把这个文件在系统磁盘删掉,避免占用系统磁盘。
        //有问题,公众号找我。我等你
        System.out.println("pdf已生成,路径是:"+pdfPath);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

截止到此,代码已经贴完了。不想看,就下附件,小意思…
注意事项:
1:使用前需要准备三个文件,第一个word模板文件(word格式,代码中文件名叫做template.docx),第二个签名文件(xml格式。我会给你,直接用就行了,代码中叫做license.xml),第三个word模板的源代码文件(xml格式,代码中文件名叫做document.xml)
2:word模版文件:找到你需要生成的word源文件,名字改为template.docx(不改文件名,你就改代码,改成你的文件名字)
3:word源代码文件:这个就需要点东西才能生成了,首先把你的word源文件复制一份哈,毕竟代码还是要用到的。然后将复制后的文件,后缀名改为zip,然后解压zip,找到word文件夹里面的document.xml,这个就是word的源代码文件啦。
4:Constants.java里面需要配置一下,你这些源文件所在的文件夹路径(切记切记切记)。

我的template.docx是这样的
在这里插入图片描述
我的document.xml是这样的
在这里插入图片描述
生成生后的pdf是这样的
在这里插入图片描述
动态数据填充完成,并且成功转换成了pdf。结束了。有问题代码中找我哦…

以下是项目工程哈,有一个aspose的jar包在maven里面是没有的,我也附带给你们了哈。

完整实例代码请关注微信公众号:程序员无名。回复“word”就可以领取了哦。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/617121
推荐阅读
相关标签
  

闽ICP备14008679号