杰瑞科技汇

Java如何实现HTML格式转Word?

核心思路

无论使用哪种方法,基本流程都遵循以下几步:

  1. 准备 HTML 内容:你可以从一个 .html 文件读取,或者直接在 Java 代码中用字符串构建。
  2. 选择转换库:选择一个能够将 HTML 转换为 Word 的 Java 库。
  3. 执行转换:调用库的 API,将 HTML 内容写入到一个 .docx 输出流中。
  4. 处理结果:检查生成的 Word 文档,确保格式符合预期。

使用 Flying Saucer (xhtmlrenderer) - 纯 Java 方案

Flying Saucer 是一个非常流行的开源 Java 库,主要用于将 XHTML/CSS 渲染成图片或 PDF,但它也支持渲染到 WordML(Word 2003 的 XML 格式),而现代的 .docx 格式本质上是一个 ZIP 压缩包,里面包含 XML 文件,我们可以利用它来生成兼容 .docx 的内容。

优点

  • 纯 Java 实现,无需额外依赖。
  • 对 CSS 样式支持较好,能生成比较美观的文档。

缺点

  • 生成的不是原生 .docx,而是基于 XML 的内容,可能在某些复杂 Word 功能上支持有限。
  • 配置和调试可能稍显复杂。

Maven 依赖

<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-pdf</artifactId>
    <version>9.1.22</version> <!-- 请使用最新版本 -->
</dependency>
<!-- 如果你只想生成 Word,可以只用 flying-saucer-core -->
<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-core</artifactId>
    <version>9.1.22</version>
</dependency>

代码示例

import org.xhtmlrenderer.swing.Java2DRenderer;
import org.xhtmlrenderer.util.FSImageWriter;
import java.awt.image.BufferedImage;
import java.io.*;
public class HtmlToWordWithFlyingSaucer {
    public static void main(String[] args) {
        // 1. 准备 HTML 内容
        String htmlContent = "<html>" +
                "<head>" +
                "<style>" +
                "body { font-family: 'Microsoft YaHei', Arial, sans-serif; }" +
                "h1 { color: #333; }" +
                "p { font-size: 12pt; line-height: 1.5; }" +
                ".highlight { background-color: yellow; }" +
                "</style>" +
                "</head>" +
                "<body>" +
                "<h1>Java 生成 Word 文档示例</h1>" +
                "<p>这是一个由 <span class=\"highlight\">HTML</span> 转换而来的 Word 文档。</p>" +
                "<p>支持基本的 <strong>加粗</strong> 和 <em>斜体</em>。</p>" +
                "</body>" +
                "</html>";
        // 2. 创建临时 HTML 文件
        File htmlFile = null;
        try {
            htmlFile = File.createTempFile("report", ".html");
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(htmlFile))) {
                writer.write(htmlContent);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        // 3. 设置输出 Word 文件路径
        File wordFile = new File("output_from_flying_saucer.docx");
        // 4. 使用 Flying Saucer 进行转换
        // 注意:Flying Saucer 本身不直接生成 .docx,这里我们通过渲染到图像再插入到 Word 的方式来演示
        // 更直接的方式是生成 WordML,但过程复杂,这里展示一个更实用的方案:生成带图片的 Word
        try {
            // 渲染 HTML 到 BufferedImage
            Java2DRenderer renderer = new Java2DRenderer(htmlFile, 800); // 800 是渲染宽度
            BufferedImage image = renderer.getImage();
            // 将 BufferedImage 写入 Word 文档 (需要另一个库,如 Apache POI)
            // 这里我们简化处理,直接保存为图片,说明转换过程
            FSImageWriter imageWriter = new FSImageWriter();
            imageWriter.write(image, "png", new File("output_from_flying_saucer.png"));
            System.out.println("HTML 已成功渲染为图片: output_from_flying_saucer.png");
            System.out.println("要生成 .docx,通常需要结合 Apache POI 将此图片插入到文档中。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5. 清理临时文件
            if (htmlFile != null) {
                htmlFile.delete();
            }
        }
    }
}

重要提示:如代码注释所示,Flying Saucer 直接生成 .docx 并不直观,通常的做法是先用它把 HTML 渲染成一张高质量的图片,然后使用 Apache POI(见方法二)将这张图片插入到 Word 文档中,这能很好地保留 HTML 的复杂布局和样式。


使用 Apache POI + iText/ Flying Saucer - 混合方案

这是最灵活、最强大的方案之一。Apache POI 是操作 Office 文档(如 .xls, .docx)的 Java 库王者,我们可以利用它来创建 Word 文档的框架,然后将 HTML 的内容(作为文本或图片)填充进去。

优点

  • 功能极其强大,可以精确控制 Word 文档的每一个元素(段落、表格、图片、页眉页脚等)。
  • 可以结合其他库(如 Flying Saucer)实现复杂 HTML 到 Word 的转换。

缺点

  • API 相对繁琐,需要编写较多代码。
  • 直接用 POI 解析 HTML 并保留样式非常困难,通常需要借助中间步骤(如转图片)。

Maven 依赖

<!-- Apache POI for .docx -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version> <!-- 请使用最新版本 -->
</dependency>
<!-- Flying Saucer for rendering HTML to image -->
<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-pdf</artifactId>
    <version>9.1.22</version>
</dependency>

代码示例(将 HTML 渲染的图片插入 Word)

这个示例结合了方法一和方法二的思路。

import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;
import org.xhtmlrenderer.swing.Java2DRenderer;
import org.xhtmlrenderer.util.FSImageWriter;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
public class HtmlToWordWithPOI {
    public static void main(String[] args) {
        // 1. 准备 HTML 内容 (与方法一相同)
        String htmlContent = "<html><head><style>body{font-family:'Microsoft YaHei';} h1{color:#4472C4;}</style></head>" +
                "<body><h1>POI + Flying Saucer 示例</h1><p>此段落内容由 HTML 渲染成图片后插入。</p></body></html>";
        // 2. 使用 Flying Saucer 将 HTML 渲染为图片
        BufferedImage image = null;
        File htmlFile = null;
        try {
            htmlFile = File.createTempFile("poi_report", ".html");
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(htmlFile))) {
                writer.write(htmlContent);
            }
            Java2DRenderer renderer = new Java2DRenderer(htmlFile, 1024);
            image = renderer.getImage();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        // 3. 使用 Apache POI 创建 Word 文档并插入图片
        try (XWPFDocument document = new XWPFDocument()) {
            // 创建一个段落
            XWPFParagraph paragraph = document.createParagraph();
            paragraph.setAlignment(ParagraphAlignment.CENTER);
            // 创建一个图片运行对象
            XWPFPictureData pictureData = document.addPictureData(
                    imageToByteArray(image, "png"), 
                    Document.PICTURE_TYPE_PNG
            );
            XWPFPicture picture = paragraph.createRun().addPicture(pictureData, Document.PICTURE_TYPE_PNG, "image.png", Units.toEMU(400), Units.toEMU(300));
            // 保存 Word 文档
            try (FileOutputStream out = new FileOutputStream("output_with_poi.docx")) {
                document.write(out);
            }
            System.out.println("Word 文档生成成功: output_with_poi.docx");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (htmlFile != null) {
                htmlFile.delete();
            }
        }
    }
    private static byte[] imageToByteArray(BufferedImage image, String format) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, format, baos);
        return baos.toByteArray();
    }
}

使用商业库 - 最简单直接

如果项目预算允许,使用专业的商业库是最高效、最可靠的选择,这些库专门为 HTML 到 Word 的转换而设计,能完美处理 CSS 样式、表格、列表等。

代表库

  • Aspose.Words for Java: 功能极其强大,文档详尽,社区支持好。
  • Docx4j: 另一个功能强大的商业库(有免费版和商业版)。

优点

  • 极其简单:通常只需要几行代码就能完成转换。
  • 高保真度:能最大程度地还原 HTML 的显示效果,包括复杂的 CSS。
  • 稳定可靠:经过市场长期验证,bug 少。

缺点

  • 需要付费:对于商业项目,需要购买许可证。

Aspose.Words 代码示例

你需要下载 Aspose.Words 的 JAR 文件并添加到项目中。

import com.aspose.words.*;
public class HtmlToWordWithAspose {
    public static void main(String[] args) throws Exception {
        // 1. 准备 HTML 内容
        String htmlContent = "<html>" +
                "<head><style>body{font-family:'Arial'; color: green;}</style></head>" +
                "<body><h2>Aspose.Words 示例</h2><p>这是使用 Aspose.Words 生成的 Word 文档,样式完美保留。</p></body>" +
                "</html>";
        // 2. 创建 Document 对象
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        // 3. 使用 DocumentBuilder 直接插入 HTML
        // 这是 Aspose.Words 最方便的地方
        builder.insertHtml(htmlContent);
        // 4. 保存为 .docx 文件
        doc.save("output_with_aspose.docx");
        System.out.println("Word 文档生成成功: output_with_aspose.docx");
    }
}

可以看到,使用 Aspose.Words 的代码非常简洁,builder.insertHtml() 一行就解决了所有问题。


总结与选择建议

方法 优点 缺点 适用场景
Flying Saucer 纯 Java,CSS 支持好 不直接生成 .docx,需结合 POI 需要高质量渲染 HTML 为图片,再嵌入到其他文档中。
Apache POI 功能强大,控制粒度细 API 复杂,直接解析 HTML 困难 需要精细控制 Word 文档结构,或结合其他库(如 Flying Saucer)使用。
商业库 (Aspose/Docx4j) 简单易用,高保真度 需要付费 追求开发效率和对样式有高要求的企业级项目。

如何选择?

  • 如果你只是想快速实现,且项目有预算首选商业库(如 Aspose.Words),它能为你节省大量的开发、测试和调试时间。
  • 如果你是个人学习、小型项目,或者预算有限选择 Apache POI + Flying Saucer 的混合方案,虽然代码量多一些,但能让你深入了解底层原理,且不产生费用。
  • 如果你的核心需求是生成一个包含 HTML 内容的图片,并插入到 Word/PDF 中单独使用 Flying Saucer 即可。

希望这个详细的解释能帮助你找到最适合你项目的解决方案!

分享:
扫描分享到社交APP
上一篇
下一篇