java基于freemark生成docx文档

之前的一平文档介绍了基于freemark生成doc的技术,但是生成的doc底层还是xml文件,在转化为pdf后,pdf内容全部为xml,参考网上的生成docx教程,自己尝试下,记录如下:

1、新建一个docx文档

新建一个docx文档:test.docx,内容还是使用占位符。

2、修改后缀为zip,把里面word目录下的document.xml作为模板。

3、生成docx

准备文档的数据,替换模板中的占位符,并把替换后包含数据的模板替换掉zip中的document.xml。

    public static void main(String[] args) throws Exception{
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("date","2019年8月22日");

        Configuration configuration = new Configuration();
        configuration.setClassForTemplateLoading(DocUtil.class, "/template/");
        Template template = configuration.getTemplate("document.xml");

        String outFilePath = "D:\\data.xml";
        File docFile = new File(outFilePath);
        FileOutputStream fos = new FileOutputStream(docFile);
        Writer out = new BufferedWriter(new OutputStreamWriter(fos),10240);
        template.process(dataMap,out);
        out.close();


        ZipInputStream zipInputStream = ZipUtils.wrapZipInputStream(new FileInputStream(new File("D:\\test.zip")));
        ZipOutputStream zipOutputStream = ZipUtils.wrapZipOutputStream(new FileOutputStream(new File("D:\\test.docx")));
        String itemname = "word/document.xml";
        ZipUtils.replaceItem(zipInputStream, zipOutputStream, itemname, new FileInputStream(new File("D:\\data.xml")));
    }
public class ZipUtils {
    /**
     * 替换某个 item,
     *
     * @param zipInputStream  zip文件的zip输入流
     * @param zipOutputStream 输出的zip输出流
     * @param itemName        要替换的 item 名称
     * @param itemInputStream 要替换的 item 的内容输入流
     */
    public static void replaceItem(ZipInputStream zipInputStream, ZipOutputStream zipOutputStream,
                                   String itemName, InputStream itemInputStream) {
        //
        if (null == zipInputStream) {
            return;
        }
        if (null == zipOutputStream) {
            return;
        }
        if (null == itemName) {
            return;
        }
        if (null == itemInputStream) {
            return;
        }
        //
        ZipEntry entryIn;
        try {
            while ((entryIn = zipInputStream.getNextEntry()) != null) {
                String entryName = entryIn.getName();
                ZipEntry entryOut = new ZipEntry(entryName);
                // 只使用 name
                zipOutputStream.putNextEntry(entryOut);
                // 缓冲区
                byte[] buf = new byte[8 * 1024];
                int len;

                if (entryName.equals(itemName)) {
                    // 使用替换流
                    while ((len = (itemInputStream.read(buf))) > 0) {
                        zipOutputStream.write(buf, 0, len);
                    }
                } else {
                    // 输出普通Zip流
                    while ((len = (zipInputStream.read(buf))) > 0) {
                        zipOutputStream.write(buf, 0, len);
                    }
                }
                // 关闭此 entry
                zipOutputStream.closeEntry();

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            close(itemInputStream);
            close(zipInputStream);
            close(zipOutputStream);
        }
    }

    /**
     * 包装输入流
     */
    public static ZipInputStream wrapZipInputStream(InputStream inputStream) {
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        return zipInputStream;
    }

    /**
     * 包装输出流
     */
    public static ZipOutputStream wrapZipOutputStream(OutputStream outputStream) {
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        return zipOutputStream;
    }

    private static void close(InputStream inputStream) {
        if (null != inputStream) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void close(OutputStream outputStream) {
        if (null != outputStream) {
            try {
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

正确生成docx文档:

参考:

https://blog.csdn.net/juncai91/article/details/70146364

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值