上一篇
Java中打开创建的DOCX文件,常用Apache POI或docx4j库,通过加载文档对象模型实现读取与解析
Java中创建并打开.docx文件通常依赖于第三方库,其中最常用的是 Apache POI 和 docx4j,以下是详细的实现步骤、代码示例及注意事项:
使用Apache POI操作DOCX文件
添加依赖
若通过Maven管理项目,需在pom.xml中引入以下坐标:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version> <!-推荐稳定版 -->
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.8</version>
</dependency>
此依赖包含处理OOXML格式(如DOCX)的核心类。
创建新DOCX文档
以下是生成简单Word文档的完整示例:
import org.apache.poi.xwpf.usermodel.;
import java.io.FileOutputStream;
import java.io.IOException;
public class CreateDocxExample {
public static void main(String[] args) throws IOException {
// 创建空白文档对象
XWPFDocument document = new XWPFDocument();
// 添加标题段落
XWPFParagraph titlePara = document.createParagraph();
XWPFRun titleRun = titlePara.createRun();
titleRun.setText("Hello, World!");
titleRun.setBold(true); // 设置加粗效果
titleRun.setFontSize(20); // 字号调整为20磅
// 添加正文内容
XWPFParagraph bodyPara = document.createParagraph();
XWPFRun bodyRun = bodyPara.createRun();
bodyRun.setText("这是由Java程序生成的第二个段落。");
// 写入本地文件系统
try (FileOutputStream out = new FileOutputStream("output.docx")) {
document.write(out);
System.out.println("文档已成功保存至output.docx");
}
}
}
运行后会在项目根目录生成名为output.docx的文件,可用Microsoft Word或其他支持该格式的软件打开。
读取现有DOCX文件
如果需要解析已有文档的内容,可以使用如下逻辑:
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import java.io.FileInputStream;
import java.util.List;
public class ReadDocxExample {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("example.docx");
XWPFDocument doc = new XWPFDocument(fis); // 加载文档
// 遍历所有段落并打印文本内容
List<XWPFParagraph> paragraphs = doc.getParagraphs();
for (XWPFParagraph para : paragraphs) {
System.out.println(para.getText());
}
fis.close(); // 确保流被正确关闭
}
}
该代码会逐行输出文档中的每个段落文本。
替代方案:docx4j库的使用
对于更复杂的场景(如深度定制样式或兼容旧版OOXML规范),可选择docx4j:
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.convert.Converter;
import java.io.File;
public class Docx4jDemo {
public static void main(String[] args) throws Exception {
WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage();
// 向包内添加元素...(此处省略具体实现)
// 保存为物理文件
wordPackage.save(new File("docx4j_output.docx"));
// 可选:转换为HTML预览
Converter.getInstance().convert(wordPackage, new File("html_preview.html"));
}
}
此库适合需要精细控制XML结构的情况,但学习曲线较陡。
常见问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
NoClassDefFoundError |
未正确导入POI相关JAR包 | 检查Maven依赖是否生效/手动添加LIB路径 |
| 乱码或格式丢失 | 未指定编码方式 | 使用UTF-8编码写入,避免特殊字符截断 |
| 图片无法显示 | 未启用二进制部件支持 | 改用XWPFPictureData类处理嵌入式图片 |
| 表格布局错乱 | 未正确设置单元格合并属性 | 调用CTTblWidth类精确定义列宽百分比 |
最佳实践建议
- 资源释放优先:始终用
try-with-resources语句管理FileOutputStream/InputStream,防止内存泄漏。 - 版本兼容性测试:不同版本的Office对OOXML的支持存在差异,建议目标为Office 2016+时使用POI 5.x系列。
- 性能优化:批量写入大文件时采用缓冲机制,例如分段提交数据而非单次全量操作。
- 安全加固:禁用宏功能时可修改文档属性中的
vbaProject标签以降低反面脚本风险。
FAQs
Q1: 为什么生成的DOCX文件在Word中打开时提示“受保护标记”?
A: 这是由于默认启用了修订跟踪功能,可通过以下代码禁用:
document.getProperties().getRevisionProperties().setRevisionMarked(false);
修改后重新保存即可正常显示。
Q2: 如何设置中文字体以避免系统默认英文字体?
A: 需显式指定字体族名称并嵌入字形文件:
Font font = new Font("宋体", Font.PLAIN, 12); // Windows系统常见中文字体名包括"SimSun"(简黑)、"FangSong"(仿宋)等
fontCharMap.put(new Integer(CharacterSetMapper.UNICODE_BLOCK), font); // 注册到全局映射表
注意不同操作系统下的字体名称可能存在差异,建议动态检测可用字体列表
