avatar

Charlie的博客

学习进步 学习进步 学习进步

  • 首页
  • 后端
  • 前端
  • 移动端
  • 操作系统
Home Java通过FreeMarker生成docx word文档
文章

Java通过FreeMarker生成docx word文档

Posted 2021-04-19 Updated 2024-11- 18
By Administrator
11~14 min read
1
2
3
4
5
6
public static void main(String[] args) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("title","放肆-Vae");
        data.put("content","你的放肆烧燃起怒火,我的放肆如大雨滂沱;你的放肆掀风起云涌,我的放肆平沧海澜波。");
        GenerateDocxUtil.freemarkerDocxTest("/Users/weichenxu/Downloads/worddocx/temp/",data,"/Users/weichenxu/Downloads/worddocx/file/放肆.docx");
    }
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
public class GenerateDocxUtil {
    private static Logger logger = LoggerFactory.getLogger(GenerateDocxUtil.class);
    public static void freemarkerDocxTest(String rootPath, Map<String,Object> dataMap, String docxPath) throws Exception{
        //配置freemarker模板
        Configuration configuration = new Configuration();
        String fileDirectory = rootPath;
        configuration.setDirectoryForTemplateLoading(new File(fileDirectory));
        String temName =  "tem1.xml";
        String docxZipPath = rootPath + "tem1.zip";
        Template template = configuration.getTemplate(temName);

        //通过模板生成的xml临时文件 方法结束后删除该临时文件
        String outFilePath = rootPath + UUID.randomUUID().toString().replace("-","") + ".xml";
        //指定输出word xml文件的路径
        File docXmlFile = new File(outFilePath);
        FileOutputStream fos = new FileOutputStream(docXmlFile);
        Writer out = new BufferedWriter(new OutputStreamWriter(fos),10240);
        template.process(dataMap,out);
        if(out != null){
            out.close();
        }

        //以下代码 主要用来加密已经生成的xml文件,把xml文件正式转换成加密的word文档
        //包装输入流
        ZipInputStream zipInputStream =  wrapZipInputStream(new FileInputStream(new File(docxZipPath)));
        //包装输出流
        ZipOutputStream zipOutputStream =  wrapZipOutputStream(new FileOutputStream(new File(docxPath)));
        //正式加密替换成docx格式文档
        List<String> itemNameList = new ArrayList<>();
        itemNameList.add("word/document.xml");
	//如果需要替换图片添加此行代码,"word/media/image1.png"为解压出来docx模板后,模板中对应图片的完整路径及名称,如果你添加的图片为jpg格式,那么图片名称会是"image1.jpg"或"image1.jpeg",各位自己视情况修改,如需替换多张图片就举一反三,往list插入多个元素,我相信你们可以理解的
	itemNameList.add("word/media/image1.png");

        List<InputStream> itemInputStreamList = new ArrayList<>();
        itemInputStreamList.add(new FileInputStream(new File(outFilePath)));
	//这里添加你想替换的图片
	itemInputStreamList.add(new FileInputStream(new File(${图片路径})));

        replaceItemList(zipInputStream, zipOutputStream, itemNameList, itemInputStreamList);
        new File(outFilePath).delete();
        logger.info("Word-docx文档生成完成");
    }

    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;
    }

    public static void replaceItemList(ZipInputStream zipInputStream, ZipOutputStream zipOutputStream, List<String> itemNameList, List<InputStream> itemInputStreamList){
        if(null == zipInputStream){return;}
        if(null == zipOutputStream){return;}
        ZipEntry entryIn;
        try {
            while((entryIn = zipInputStream.getNextEntry())!=null){
                String entryName =  entryIn.getName();
                ZipEntry entryOut = new ZipEntry(entryName);
                zipOutputStream.putNextEntry(entryOut);
                byte [] buf = new byte[8*1024];
                int len;

                if(itemNameList.indexOf(entryName) != -1){
                    // 使用替换流
                    while((len = (itemInputStreamList.get(itemNameList.indexOf(entryName)).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 {
            //e.printStackTrace();
            for (InputStream itemInputStream:itemInputStreamList) {
                close(itemInputStream);
            }
            close(zipInputStream);
            close(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();
            }
        }
    }
}

后端
Java
License:  CC BY 4.0
Share

Further Reading

Apr 28, 2024

Java Lambda表达式:让你的代码像喝了红牛一样飞起来!

在Java的世界里,Lambda表达式就像是代码界的瑞士军刀,自Java 8以来,它就一直在帮助我们编写更短、更聪明、更具可读性的代码。如果你还在使用那些老旧的冗长代码,那么现在是时候开启Lambda表达式的大门,让你的代码量减半,效率加倍!

Apr 27, 2024

快速了解MyBatis-Plus:带来便捷、高效的持久层开发体验

在现代软件开发中,高效的持久层操作是保障系统性能和可维护性的重要组成部分。MyBatis-Plus 作为 MyBatis 的增强工具,为 Java 开发者提供了更便捷、高效的持久层开发体验。本文将深入介绍 MyBatis-Plus 的特性和用法

Jan 12, 2023

Java获取N天前、N周前、N月前的日期

Java通过Calendar获取N天前(后)、N周前(后)、N月前(后)的日期。

OLDER

CentOS通过yum安装JDK

NEWER

原生HTML+CSS适配深色模式/暗色模式

Recently Updated

  • iptables规则持久化
  • Win11的OOBE阶段启用Administrator账户并跳过账户创建步骤
  • 复刻iOS圆环时间选择器
  • 打造可滑动切换的顶部TabBar
  • Java Lambda表达式:让你的代码像喝了红牛一样飞起来!

Trending Tags

iOS HTML macOS Redis Java JS Swift Windows Linux JDK

Contents

©2025 Charlie的博客. Some rights reserved.

Using the Halo theme Chirpy