本文目录导读:

在Java中生成Word文档有多种实现方式,主要分为基于模板(如docx4j、Apache POI)和基于代码生成(如iText、Apache POI)两大类,以下是几种主流方案的对比和示例:
Apache POI(推荐,纯Java实现)
Maven依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
示例代码:创建简单Word文档
import org.apache.poi.xwpf.usermodel.*;
import java.io.FileOutputStream;
public class WordGenerator {
public static void main(String[] args) throws Exception {
// 创建文档
XWPFDocument document = new XWPFDocument();
// 添加段落
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("Hello, Word Document!");
run.setBold(true);
run.setFontSize(18);
// 添加表格
XWPFTable table = document.createTable(3, 3);
table.getRow(0).getCell(0).setText("Name");
table.getRow(0).getCell(1).setText("Age");
table.getRow(0).getCell(2).setText("City");
table.getRow(1).getCell(0).setText("Alice");
table.getRow(1).getCell(1).setText("28");
table.getRow(1).getCell(2).setText("New York");
// 保存文档
FileOutputStream out = new FileOutputStream("example.docx");
document.write(out);
out.close();
document.close();
System.out.println("Word文档生成成功!");
}
}
docx4j(适合复杂模板)
Maven依赖
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-JAXB-MOXy</artifactId>
<version>8.3.9</version>
</dependency>
示例代码:基于模板填充
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import java.io.File;
public class Docx4jExample {
public static void main(String[] args) throws Exception {
// 加载模板
WordprocessingMLPackage wordMLPackage =
WordprocessingMLPackage.load(new File("template.docx"));
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
// 替换占位符(模板中使用 ${name} 等占位符)
String content = documentPart.getContent().toString();
content = content.replace("${name}", "张三");
content = content.replace("${date}", "2024-01-01");
// 重新设置内容
documentPart.setContent(
org.docx4j.XmlUtils.unmarshalString(content)
);
// 保存
wordMLPackage.save(new File("output.docx"));
System.out.println("模板填充完成!");
}
}
iText(主要针对PDF,但也可生成Word)
Maven依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.2.5</version>
<type>pom</type>
</dependency>
示例代码
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
public class ITextExample {
public static void main(String[] args) throws Exception {
// 注意:iText主要生成PDF,此示例仅供参考
PdfWriter writer = new PdfWriter("example.docx");
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
// 添加内容
document.add(new Paragraph("Hello, Document!"));
// 添加表格
Table table = new Table(3);
table.addCell("Name");
table.addCell("Age");
table.addCell("City");
table.addCell("Alice");
table.addCell("28");
table.addCell("New York");
document.add(table);
document.close();
System.out.println("文档生成成功!");
}
}
FreeMarker + docx模板(企业级推荐方案)
Maven依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
模板示例 (template.xml)
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t>Hello, ${name}!</w:t>
</w:r>
</w:p>
<w:tbl>
<w:tr>
<w:tc><w:p><w:r><w:t>${field1}</w:t></w:r></w:p></w:tc>
<w:tc><w:p><w:r><w:t>${field2}</w:t></w:r></w:p></w:tc>
</w:tr>
</w:tbl>
</w:body>
</w:document>
Java代码
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class FreeMarkerDocxExample {
public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
cfg.setClassForTemplateLoading(FreeMarkerDocxExample.class, "/templates");
Template template = cfg.getTemplate("template.xml");
Map<String, Object> data = new HashMap<>();
data.put("name", "李四");
data.put("field1", "Value1");
data.put("field2", "Value2");
// 注意:生成的xml文件需要重命名为.docx
Writer out = new OutputStreamWriter(
new FileOutputStream("output.docx"), "UTF-8");
template.process(data, out);
out.close();
System.out.println("模板生成成功!");
}
}
方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Apache POI | 纯Java实现,功能强大,支持各种Word元素 | 文档结构复杂时代码量较大 | 需要动态创建复杂Word文档 |
| docx4j | 模板功能强大,支持变量替换 | 学习曲线稍陡 | 基于模板的文档生成 |
| iText | 成熟稳定,PDF生成优秀 | 对Word支持有限 | 需要同时处理PDF和简单Word |
| FreeMarker+docx | 模板灵活,性能好 | 需要手动处理docx解压 | 大量模板化的文档生成 |
最佳实践建议
- 简单文档:使用Apache POI直接创建
- 复杂模板:使用docx4j或FreeMarker + docx模板
- 批量生成:推荐FreeMarker方案,性能最好
- 跨平台:优先选择Apache POI,纯Java实现
- 报表类:建议配合JasperReports使用
选择方案时要考虑:
- 文档复杂度
- 是否需要模板支持
- 性能要求(批量生成时尤其重要)
- 维护成本和学习曲线