好的,当然可以。以下是整理成 Markdown 格式的解决方案,非常适合用于博客记录。
Java 导出包含内嵌图片的 Word 文档解决方案
本文介绍几种在 Java 中导出 Word 文档并将图片完全内嵌到文件中的可靠方案,确保文档在任何环境下打开都能正常显示图片。
核心目标
将图片数据完全写入 Word 文档的文件结构中,生成一个自包含的 .docx 文件,不依赖任何外部图片链接。
方案一:Apache POI (XWPF) - 推荐方案
这是最常用、最原生的 Java 方案,适用于生成标准的 .docx 格式文档。
优点
- 免费开源
- 控制力强
- 生成标准格式文档
- 社区活跃,资料丰富
Maven 依赖
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.4</version>
</dependency>
</dependencies>核心代码实现
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.IOUtils;
import java.io.*;
public class WordExportWithImage {
public static void main(String[] args) throws Exception {
// 1. 创建新文档
XWPFDocument document = new XWPFDocument();
// 2. 创建段落和文本运行
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("这是一个包含内嵌图片的文档:");
run.addCarriageReturn();
// 3. 读取图片文件
FileInputStream imageStream = new FileInputStream("path/to/your/image.jpg");
byte[] imageBytes = IOUtils.toByteArray(imageStream);
imageStream.close();
// 4. 将图片嵌入文档
run.addPicture(new ByteArrayInputStream(imageBytes),
XWPFDocument.PICTURE_TYPE_JPEG,
"image.jpg",
Units.toEMU(300), // 宽度
Units.toEMU(200)); // 高度
// 5. 保存文档
FileOutputStream out = new FileOutputStream("output_with_image.docx");
document.write(out);
out.close();
document.close();
System.out.println("包含内嵌图片的Word文档生成成功!");
}
}关键技术点
-
addPicture()方法将图片字节数据直接嵌入.docx文件 -
.docx本质是 ZIP 压缩包,图片被存储在包内的word/media/目录 - 使用
Units.toEMU()确保尺寸单位正确
方案二:模板技术 (Freemarker)
适用于格式复杂、内容动态的文档场景。
优点
- 样式与数据分离
- 开发效率高
- 易于维护
实现步骤
- 制作模板
- 用 Word 创建
.docx文件并设计样式 - 在图片位置插入占位符
{{imagePlaceholder}} - 另存为 XML 文件并修改模板语法
- Java 处理逻辑
- 读取图片并转换为 Base64 编码
- 使用 Freemarker 引擎渲染模板
- 将输出的 XML 重命名为
.docx后缀
// 简化的处理流程
String templatePath = "template.xml";
String imagePath = "path/to/image.jpg";
// 将图片转换为 Base64
byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath));
String base64Image = Base64.getEncoder().encodeToString(imageBytes);
// 准备数据模型
Map<String, Object> data = new HashMap<>();
data.put("imagePlaceholder", base64Image);
// 渲染模板并输出
Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
cfg.setDirectoryForTemplateLoading(new File("templates"));
Template template = cfg.getTemplate("word-template.xml");
try (Writer out = new FileWriter("output.docx")) {
template.process(data, out);
}方案三:Docx4j 库
功能更强大的专业级解决方案。
优点
- 对 Word 高级特性支持更好
- 功能丰富全面
缺点
- 学习曲线较陡峭
- 商业使用需注意许可证
代码示例
// 初始化
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
// 创建段落和文本运行
org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory();
P p = factory.createP();
R r = factory.createR();
// 嵌入图片
FileInputStream is = new FileInputStream(new File("path/to/image.jpg"));
byte[] bytes = IOUtils.toByteArray(is);
is.close();
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(
wordMLPackage, bytes
);
Inline inline = imagePart.createImageInline("image.jpg", "图片描述", 1, 2, false);
// 添加到文档
r.getContent().add(factory.createDrawing(inline));
p.getContent().add(r);
wordMLPackage.getMainDocumentPart().addObject(p);
// 保存文档
wordMLPackage.save(new File("output.docx"));方案对比
方案 | 易用性 | 灵活性 | 学习成本 | 适用场景 |
Apache POI | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | 大多数常规需求 |
模板技术 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 复杂格式、批量生成 |
Docx4j | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 企业级复杂需求 |
总结
对于大多数应用场景,推荐使用 Apache POI (XWPF) 方案,因为:
- 完全满足图片内嵌需求
- 代码简洁直观,易于维护
- 社区支持良好,文档齐全
- 生成的文档兼容性最好
无论选择哪种方案,都能实现图片完全内嵌到 Word 文档中,确保文档在任何环境下都能正常显示。
















