Spring Boot 和 Freemarker 实现 Word 文档的动态导出

概述

在企业级应用中,经常需要将数据导出为 Word 文档,以便用户可以方便地查看、编辑或打印这些数据。Spring Boot 以其简洁性和易用性著称,而 Freemarker 是一款强大的模板引擎,能够灵活地生成各种类型的文本输出。结合这两种技术,我们可以快速实现一个功能完备且易于维护的 Word 文档导出功能。

准备工作

技术栈

  • Spring Boot: 用于构建应用和服务。
  • Freemarker: 作为模板引擎来生成文档。
  • Apache POI: 用于处理 Word 文件。
  • Maven: 构建工具。

开发环境

  • IDE: IntelliJ IDEA 或 Eclipse
  • JDK: 1.8 或更高版本
  • Maven: 3.6.0 或更高版本

创建项目

  1. 初始化项目:
  2. 使用 Spring Initializr 创建一个新的 Spring Boot 项目。
  3. 添加 spring-boot-starter-web 依赖项。
  4. 添加 spring-boot-starter-freemarker 依赖项。
  5. 添加依赖:
  6. 在 pom.xml 中添加 Apache POI 的相关依赖,以便能够处理 .docx 文件。
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
    <!-- Apache POI for Word document handling -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.2</version>
    </dependency>
</dependencies>

设计模板

  1. 创建模板文件:
  2. 在 src/main/resources/templates 目录下创建一个 .ftl 文件,例如 report.ftl。
  3. 使用 Freemarker 的标签语法设计模板。
  4. 模板示例:
  5. 一个简单的报告模板可能包含一些文本和表格数据。
<!DOCTYPE document PUBLIC "-//OOXML//DTD Document//EN" "document.dtd">
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:body>
        <w:p>
            <w:r>
                <w:t>Welcome, ${username}!</w:t>
            </w:r>
        </w:p>
        <w:tbl>
            <w:tr>
                <w:tc>
                    <w:p>
                        <w:r>
                            <w:t>Data Label</w:t>
                        </w:r>
                    </w:p>
                </w:tc>
                <w:tc>
                    <w:p>
                        <w:r>
                            <w:t>Data Value</w:t>
                        </w:r>
                    </w:p>
                </w:tc>
            </w:tr>
            <#list data as item>
            <w:tr>
                <w:tc>
                    <w:p>
                        <w:r>
                            <w:t>${item.label}</w:t>
                        </w:r>
                    </w:p>
                </w:tc>
                <w:tc>
                    <w:p>
                        <w:r>
                            <w:t>${item.value}</w:t>
                        </w:r>
                    </w:p>
                </w:tc>
            </w:tr>
            </#list>
        </w:tbl>
    </w:body>
</w:document>

高级功能

处理样式和复杂布局

在实际应用中,Word 文档通常需要更加复杂的样式和布局。虽然 Freemarker 本身不直接支持 Word 的样式标签,但我们可以借助 Apache POI 库来处理样式和复杂布局。

  1. 创建样式:
  2. 使用 Apache POI 的 XWPFStyles API 来定义样式,并将其应用于文档中的元素。
  3. 插入图片:
  4. 使用 XWPFDocument 的 addPicture 方法来插入图片到文档中。
  5. 处理列表和表格:
  6. 使用 Freemarker 的循环标签来生成列表和表格,再通过 Apache POI 的 API 来控制表格的具体样式和结构。

示例代码

为了演示如何处理样式,我们将添加一些基本的样式到我们的 Word 文档中。

Java

深色版本

1import org.apache.poi.xwpf.usermodel.*;
2import org.springframework.beans.factory.annotation.Autowired;
3import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
4import org.springframework.web.bind.annotation.GetMapping;
5import org.springframework.web.bind.annotation.RequestMapping;
6import org.springframework.web.bind.annotation.RestController;
7import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
8
9import freemarker.template.Configuration;
10import freemarker.template.Template;
11import freemarker.template.TemplateException;
12
13import javax.servlet.http.HttpServletResponse;
14import java.io.IOException;
15import java.io.OutputStreamWriter;
16import java.nio.charset.StandardCharsets;
17import java.util.HashMap;
18import java.util.List;
19import java.util.Map;
20
21@RestController
22@RequestMapping("/export")
23public class ReportExportController {
24
25    @Autowired
26    private FreeMarkerConfigurer configurer;
27
28    @GetMapping("/word")
29    public void exportWord(HttpServletResponse response) throws IOException, TemplateException {
30        // 设置响应头
31        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
32        response.setHeader("Content-Disposition", "attachment; filename=report.docx");
33
34        // 获取模板
35        Configuration cfg = configurer.getConfiguration();
36        Template template = cfg.getTemplate("report.ftl");
37
38        // 数据模型
39        Map<String, Object> model = new HashMap<>();
40        List<User> users = getUserData(); // 从数据库或其他来源获取数据
41        model.put("title", "User Report");
42        model.put("users", users);
43
44        // 渲染模板
45        String processedHtml = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
46
47        // 创建 Word 文档
48        XWPFDocument document = new XWPFDocument();
49
50        // 添加样式
51        XWPFStyles styles = document.createStyles();
52        XWPFStyle style = styles.createStyle("MyHeading");
53        style.setCustomStyle(true);
54        style.setStyleId("Heading1");
55        style.addBasedOnStyle("Heading1");
56        style.setFontFamily("Arial");
57        style.setFontSize(16);
58        style.setBold(true);
59        style.setUnderline(XWPFUnderlinePatterns.SINGLE);
60
61        // 将 HTML 转换为 XWPFParagraphs
62        XHTMLOptions options = XHTMLOptions.create()
63                .setIgnoreStylesIfUnused(false)
64                .setFragment(true)
65                .setUseXWPFTable(true)
66                .setDefaultStyles(styles)
67                .setInsertNewParagraphForBlockLevelTags(true);
68
69        XHTMLConverter.getInstance().convert(processedHtml, document, options);
70
71        // 写入响应流
72        try (OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8)) {
73            document.write(writer);
74        }
75    }
76
77    private List<User> getUserData() {
78        // 返回用户数据
79        return null;
80    }
81}

注意事项

  • 兼容性:
    • 确保生成的 Word 文档在不同的 Office 版本中都能正确显示。
  • 性能考量:
    • 如果要导出的数据量很大,考虑分批次处理或使用异步任务。
  • 安全性:
    • 在处理用户提交的数据时,确保对数据进行适当的验证和清理,防止潜在的安全问题。

总结

通过以上步骤,我们已经了解了如何利用 Spring Boot 和 Freemarker 生成带有样式的 Word 文档。这种方案既简单又高效,非常适合需要频繁生成报告的应用场景。如果需要更高级的功能,如图表生成或者复杂的页面布局,可以进一步探索 Apache POI 的其他功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值