首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java 批量提取 Word 文档中的图片并保存到本地

Java 批量提取 Word 文档中的图片并保存到本地

原创
作者头像
用户12416476
发布于 2026-11-06 16:18:19
发布于 2026-11-06 16:18:19
420
举报

在处理 Word 文档时,有时需要将其中的图片单独提取出来,例如整理技术文档中的截图、收集报告中的插图,或将图片用于其他系统。如果文档只有几张图片,可以手动右键保存;但对于包含大量图片的 Word 文件,逐张操作就比较麻烦了。

本文介绍如何使用 Java 批量提取 Word 文档中的图片,并将它们保存到指定文件夹。整个过程不需要安装 Microsoft Word,也不需要手动解压 DOCX 文件,同时可以处理正文、表格等位置的图片。

一、安装所需依赖

要使用 Java 提取 Word 文档中的图片,需要先添加相应的文档处理依赖。这里选择Spire.Doc for Java,它可以直接读取 Word 文档并获取其中的图片,无需安装 Microsoft Word。

如果使用 Maven 项目,可以在 ​​pom.xml​​ 文件中添加以下仓库和依赖:

代码语言:javascript
复制
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.doc</artifactId>
        <version>14.10.6</version>
    </dependency>
</dependencies>

二、使用 Java 提取 Word 文档中的图片

实现思路并不复杂:首先加载 Word 文件,然后遍历文档中的对象,找到图片后获取其字节数据,最后将图片保存到本地。

第一步:导入所需的类

首先导入 Word 文档处理、文件读写以及图片格式识别所需的类。

代码语言:javascript
复制
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.fields.*;
import com.spire.doc.interfaces.*;

import javax.imageio.*;
import javax.imageio.stream.ImageInputStream;
import java.io.*;
import java.nio.file.*;
import java.util.*;

其中,​​Document​​ 用于加载 Word 文档,​​DocPicture​​ 表示文档中的图片对象,Java NIO 用于创建文件夹和保存图片。

第二步:加载 Word 文档并创建输出文件夹

使用 ​​Document.loadFromFile()​​ 方法读取需要处理的 Word 文件,并指定图片保存位置。

代码语言:javascript
复制
// 加载 Word 文档
Document document = new Document();
document.loadFromFile("示例文档.docx");

// 创建图片输出文件夹
Path outputDir = Paths.get("提取的图片");
Files.createDirectories(outputDir);

这里使用相对路径,输入文件默认位于程序的工作目录中。如果文件保存在其他位置,也可以指定完整路径。

​​Files.createDirectories()​​ 会在文件夹不存在时自动创建目录。

第三步:遍历 Word 文档中的图片

Word 文档中的内容并不只有普通段落,还可能包含表格、页眉页脚以及其他嵌套对象。

为了尽可能找到文档中的常规图片,可以使用队列遍历文档对象树,并通过 ​​DocumentObjectType.Picture​​ 判断当前对象是否为图片。

代码语言:javascript
复制
// 创建队列,将文档加入队列
Queue<ICompositeObject> queue = new LinkedList<>();
queue.add(document);

int imageIndex = 1;

while (!queue.isEmpty()) {
    ICompositeObject parent = queue.poll();

    for (int i = 0; i < parent.getChildObjects().getCount(); i++) {
        IDocumentObject child = parent.getChildObjects().get(i);

        if (child.getDocumentObjectType() == DocumentObjectType.Picture) {
            // 获取图片对象
            DocPicture picture = (DocPicture) child;

            // 获取图片字节数据
            byte[] imageBytes = picture.getImageBytes();

            // 后续将图片保存到本地
        } else if (child instanceof ICompositeObject) {
            // 将嵌套对象加入队列,继续遍历
            queue.add((ICompositeObject) child);
        }
    }
}

与只遍历普通段落相比,这种方式还可以查找表格等嵌套结构中的图片。

其中,​​getImageBytes()​​ 用于获取图片的字节数据,后续可以直接将这些数据写入文件,而不必重新生成图片。

第四步:将图片保存到本地

获取图片数据后,可以使用 ​​Files.write()​​ 将其保存到指定目录。

需要注意,提取图片时不应直接将所有文件命名为 ​​.jpg​​ 或 ​​.png​​,因为 Word 文档中可能同时包含多种图片格式。

这里使用 Java 的 ​​ImageIO​​ 识别常见图片格式,再为文件设置对应的扩展名。

代码语言:javascript
复制
// 识别图片格式
String extension = getImageExtension(imageBytes);

// 生成图片文件名
String fileName = "图片_" + imageIndex + "." + extension;

// 将图片保存到指定目录
Files.write(outputDir.resolve(fileName), imageBytes);

imageIndex++;

​​getImageExtension()​​ 是下面完整示例中定义的辅助方法,只负责识别格式,不会修改或重新编码图片数据。

三、完整 Java 代码

将前面的步骤组合起来,可以得到一个完整的 Word 图片提取程序。

代码语言:javascript
复制
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.fields.*;
import com.spire.doc.interfaces.*;

import javax.imageio.*;
import javax.imageio.stream.ImageInputStream;
import java.io.*;
import java.nio.file.*;
import java.util.*;

public class ExtractImagesFromWord {

    public static void main(String[] args) throws IOException {

        // 加载 Word 文档
        Document document = new Document();
        document.loadFromFile("示例文档.docx");

        // 创建图片输出文件夹
        Path outputDir = Paths.get("提取的图片");
        Files.createDirectories(outputDir);

        // 创建队列并加入文档根对象
        Queue<ICompositeObject> queue = new LinkedList<>();
        queue.add(document);

        int imageIndex = 1;

        // 遍历 Word 文档中的对象
        while (!queue.isEmpty()) {
            ICompositeObject parent = queue.poll();

            for (int i = 0; i < parent.getChildObjects().getCount(); i++) {
                IDocumentObject child = parent.getChildObjects().get(i);

                // 判断当前对象是否为图片
                if (child.getDocumentObjectType() == DocumentObjectType.Picture) {

                    DocPicture picture = (DocPicture) child;

                    // 获取图片字节数据
                    byte[] imageBytes = picture.getImageBytes();

                    // 识别图片格式
                    String extension = getImageExtension(imageBytes);

                    // 生成图片文件名
                    String fileName = "图片_" + imageIndex + "." + extension;

                    // 保存图片
                    Files.write(outputDir.resolve(fileName), imageBytes);

                    imageIndex++;

                } else if (child instanceof ICompositeObject) {
                    // 继续遍历嵌套对象
                    queue.add((ICompositeObject) child);
                }
            }
        }

        // 释放文档资源
        document.dispose();

        System.out.println("图片提取完成,共保存 "
                + (imageIndex - 1) + " 张图片。");
    }

    // 识别图片格式,避免使用错误的扩展名
    private static String getImageExtension(byte[] bytes) throws IOException {

        try (ImageInputStream stream = ImageIO.createImageInputStream(
                new ByteArrayInputStream(bytes))) {

            Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);

            if (readers.hasNext()) {
                ImageReader reader = readers.next();

                try {
                    String format = reader.getFormatName()
                            .toLowerCase(Locale.ROOT);

                    if (format.equals("jpeg")) return "jpg";
                    if (format.equals("tiff")) return "tif";

                    return format;
                } finally {
                    reader.dispose();
                }
            }
        }

        // 无法识别时,保存为二进制文件
        return "bin";
    }
}

运行结果

假设输入的 Word 文档中包含多张 JPG、PNG 和 GIF 图片。

执行程序后,会在指定的输出文件夹中得到类似以下文件:

代码语言:javascript
复制
提取的图片/
    图片_1.png
    图片_2.jpg
    图片_3.png
    图片_4.gif

控制台输出:

代码语言:javascript
复制
图片提取完成,共保存 4 张图片。

图片会按照遍历过程中发现的顺序依次编号,避免因文件名相同而相互覆盖。

由于代码直接保存获取到的图片字节数据,没有进行缩放、压缩或格式转换,因此不会因额外的图像编码而降低图片质量。

四、常见问题

1. 这段代码支持 DOC 和 DOCX 文件吗?

支持。Spire.Doc for Java 可以读取 ​​.doc​​ 和 ​​.docx​​ 格式的 Word 文档。

只需要在 ​​loadFromFile()​​ 方法中指定相应的文件路径,例如:

代码语言:javascript
复制
document.loadFromFile("示例文档.doc");

其他图片提取逻辑不需要修改。

2. 为什么某些提取的图片是 BIN 格式?

Java 内置的 ​​ImageIO​​ 可以识别 JPG、PNG、GIF、BMP 等常见图片格式,但并不支持所有图像类型。

例如,Word 文档中可能包含 EMF、WMF 等矢量图像,而 Java 默认的图片读取器可能无法识别这些格式。

对于无法识别的图片,示例程序会使用 ​​.bin​​ 扩展名保存图片数据,避免将它们错误地命名为 JPG 或 PNG。

如果需要识别这些特殊格式,可以根据图片文件头进一步判断其真实类型。

3. 为什么有些图形没有被提取?

Word 文档中的图片和图形并不完全相同。

普通插入图片通常属于 ​​DocPicture​​ 对象,而文本框、图表、SmartArt 及某些形状可能使用其他对象类型存储。

本文主要提取 ​​DocPicture​​ 类型的图片。如果需要导出 Word 中的图表、形状或其他绘图对象,则需要针对这些对象进行额外处理。

总结

使用 Java 提取 Word 文档中的图片,可以省去逐张复制、保存的操作,尤其适合处理包含大量插图的报告、产品手册和技术文档。

本文通过遍历 Word 文档对象,定位图片并获取其字节数据,再将图片批量保存到本地。整个过程不需要 Microsoft Word,也不涉及图片格式转换,适合用于文档图片整理和自动化处理。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、安装所需依赖
  • 二、使用 Java 提取 Word 文档中的图片
    • 第一步:导入所需的类
    • 第二步:加载 Word 文档并创建输出文件夹
    • 第三步:遍历 Word 文档中的图片
    • 第四步:将图片保存到本地
  • 三、完整 Java 代码
    • 运行结果
  • 四、常见问题
    • 1. 这段代码支持 DOC 和 DOCX 文件吗?
    • 2. 为什么某些提取的图片是 BIN 格式?
    • 3. 为什么有些图形没有被提取?
  • 总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档