Java 使用 Freemarker 生成 Word 和 PDF 文件详解

在企业级应用开发中,生成各种格式的文档(如 Word 和 PDF)是非常常见的需求。Freemarker 是一个强大的模板引擎,可以用来生成各种文本格式的文件。本文将详细介绍如何在 Java 中使用 Freemarker 生成 Word 和 PDF 文件,并提供一些常见问题的解决方案。💡

图片[1]-Java 使用 Freemarker 生成 Word 和 PDF 文件详解-连界优站

什么是 Freemarker?

Freemarker 是一个用 Java 编写的模板引擎,主要用于生成文本输出,如 HTML、XML、SQL 语句等。它允许开发者将数据模型和视图逻辑分离,从而提高代码的可维护性和灵活性。📚

环境准备

在开始之前,确保你的开发环境中已经安装了以下组件:

  • Java Development Kit (JDK):确保 JDK 已安装并配置好环境变量。
  • Maven:用于管理项目依赖。
  • Apache POI:用于生成 Word 文件。
  • iText:用于生成 PDF 文件。

添加依赖

在你的 pom.xml 文件中添加以下依赖:

<dependencies>
    <!-- Freemarker -->
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.31</version>
    </dependency>

    <!-- Apache POI for Word -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.2</version>
    </dependency>

    <!-- iText for PDF -->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itext7-core</artifactId>
        <version>7.1.15</version>
    </dependency>
</dependencies>

生成 Word 文件

准备模板

首先,创建一个 Freemarker 模板文件 template.docx,内容如下:

<#list users as user>
    姓名: ${user.name}
    年龄: ${user.age}
    邮箱: ${user.email}
    <#if user.isVIP>
        VIP 用户
    </#if>
    <br/>
</#list>

生成 Word 文件的 Java 代码

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WordGenerator {

    public static void main(String[] args) {
        try {
            // 初始化 Freemarker 配置
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
            cfg.setDirectoryForTemplateLoading(new File("templates"));

            // 加载模板
            Template template = cfg.getTemplate("template.docx");

            // 准备数据模型
            Map<String, Object> dataModel = new HashMap<>();
            List<User> users = List.of(
                new User("张三", 30, "zhangsan@example.com", true),
                new User("李四", 25, "lisi@example.com", false)
            );
            dataModel.put("users", users);

            // 生成 HTML 内容
            StringWriter writer = new StringWriter();
            template.process(dataModel, writer);
            String htmlContent = writer.toString();

            // 创建 Word 文档
            XWPFDocument document = new XWPFDocument();
            XWPFParagraph paragraph = document.createParagraph();
            paragraph.createRun().setText(htmlContent);

            // 保存 Word 文件
            FileOutputStream out = new FileOutputStream("output.docx");
            document.write(out);
            out.close();

            System.out.println("Word 文件生成成功");
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }
    }

    static class User {
        String name;
        int age;
        String email;
        boolean isVIP;

        public User(String name, int age, String email, boolean isVIP) {
            this.name = name;
            this.age = age;
            this.email = email;
            this.isVIP = isVIP;
        }
    }
}

生成 PDF 文件

准备模板

创建一个 Freemarker 模板文件 template.html,内容如下:

<html>
<body>
<#list users as user>
    <p>姓名: ${user.name}</p>
    <p>年龄: ${user.age}</p>
    <p>邮箱: ${user.email}</p>
    <#if user.isVIP>
        <p>VIP 用户</p>
    </#if>
    <br/>
</#list>
</body>
</html>

生成 PDF 文件的 Java 代码

import com.itextpdf.html2pdf.HtmlConverter;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PdfGenerator {

    public static void main(String[] args) {
        try {
            // 初始化 Freemarker 配置
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
            cfg.setDirectoryForTemplateLoading(new File("templates"));

            // 加载模板
            Template template = cfg.getTemplate("template.html");

            // 准备数据模型
            Map<String, Object> dataModel = new HashMap<>();
            List<User> users = List.of(
                new User("张三", 30, "zhangsan@example.com", true),
                new User("李四", 25, "lisi@example.com", false)
            );
            dataModel.put("users", users);

            // 生成 HTML 内容
            StringWriter writer = new StringWriter();
            template.process(dataModel, writer);
            String htmlContent = writer.toString();

            // 将 HTML 转换为 PDF
            HtmlConverter.convertToPdf(htmlContent, new FileOutputStream("output.pdf"));

            System.out.println("PDF 文件生成成功");
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }
    }

    static class User {
        String name;
        int age;
        String email;
        boolean isVIP;

        public User(String name, int age, String email, boolean isVIP) {
            this.name = name;
            this.age = age;
            this.email = email;
            this.isVIP = isVIP;
        }
    }
}

常见问题与解决方案

问题 1:模板文件未找到

现象:在运行代码时,报错提示模板文件未找到。

解决方案

  • 确保模板文件路径正确,并且文件存在于指定路径中。
  • 检查 cfg.setDirectoryForTemplateLoading(new File("templates")) 中的路径是否正确。
cfg.setDirectoryForTemplateLoading(new File("path/to/templates"));

问题 2:生成的 Word 文件格式不正确

现象:生成的 Word 文件打开时格式不正确,或者部分内容丢失。

解决方案

  • 确保生成的 HTML 内容格式正确,没有语法错误。
  • 使用 XWPFDocument 时,确保每一段内容都正确添加到段落中。

问题 3:生成的 PDF 文件内容为空

现象:生成的 PDF 文件内容为空,没有任何数据。

解决方案

  • 确保生成的 HTML 内容不为空。
  • 检查 HtmlConverter.convertToPdf 方法的调用是否正确。
HtmlConverter.convertToPdf(htmlContent, new FileOutputStream("output.pdf"));

总结

通过本文的介绍,相信你已经掌握了在 Java 中使用 Freemarker 生成 Word 和 PDF 文件的方法。这些技巧不仅可以提高你的开发效率,还可以帮助你在企业级应用中更好地满足各种文档生成的需求。在实际应用中,遇到问题时不要慌张,多利用调试工具,逐步排查问题。💡


注:本文提供的代码示例已在最新版本的 Java 和相关依赖库中进行了测试,确保可以正常运行。

© 版权声明
THE END
喜欢就支持一下吧
点赞5赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容