You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Apache POI的XWPFWordExtractor提取含文本框的DOCX全量文本?

解决DOCX文本框文本提取问题

默认的XWPFWordExtractor只会提取文档正文段落的文本,而文本框属于DOCX中的浮动形状元素,不在其默认扫描范围内,所以会被忽略。要提取全部文本,需要手动遍历文档中的所有形状并提取其中的内容,再和正文文本合并。

完整代码示例

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShape;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;

import java.io.InputStream;
import java.util.StringJoiner;

public class DocxTextExtractor {

    public static String extractFullText(InputStream inputStream) throws Exception {
        XWPFDocument doc = new XWPFDocument(inputStream);
        StringJoiner fullText = new StringJoiner("\n");

        // 提取正文文本
        XWPFWordExtractor mainExtractor = new XWPFWordExtractor(doc);
        fullText.add(mainExtractor.getText().trim());

        // 提取所有段落中的文本框内容
        for (XWPFParagraph paragraph : doc.getParagraphs()) {
            CTP ctp = paragraph.getCTP();
            if (ctp.getAnchorList() != null) {
                for (CTAnchor anchor : ctp.getAnchorList()) {
                    extractShapeText(anchor.getSp(), fullText);
                }
            }
        }

        // 可选:提取页眉页脚中的文本框内容
        for (XWPFHeader header : doc.getHeaders()) {
            extractTextFromHeaderFooter(header, fullText);
        }
        for (XWPFFooter footer : doc.getFooters()) {
            extractTextFromHeaderFooter(footer, fullText);
        }

        doc.close();
        return fullText.toString().trim();
    }

    private static void extractShapeText(CTShape shape, StringJoiner textJoiner) {
        if (shape.getTxBody() != null) {
            // 将形状内的文本主体转换为临时段落,复用XWPFWordExtractor提取文本
            XWPFDocument tempDoc = new XWPFDocument();
            XWPFParagraph tempPara = tempDoc.createParagraph();
            tempPara.getCTP().set(shape.getTxBody().getPArray(0));
            XWPFWordExtractor tempExtractor = new XWPFWordExtractor(tempDoc);
            String shapeText = tempExtractor.getText().trim();
            if (!shapeText.isEmpty()) {
                textJoiner.add(shapeText);
            }
            try {
                tempDoc.close();
            } catch (Exception e) {
                // 忽略关闭异常
            }
        }
    }

    private static void extractTextFromHeaderFooter(XWPFHeaderFooter headerFooter, StringJoiner textJoiner) {
        for (XWPFParagraph paragraph : headerFooter.getParagraphs()) {
            CTP ctp = paragraph.getCTP();
            if (ctp.getAnchorList() != null) {
                for (CTAnchor anchor : ctp.getAnchorList()) {
                    extractShapeText(anchor.getSp(), textJoiner);
                }
            }
        }
    }
}

代码说明

  • 主方法extractFullText:先提取常规正文文本,再遍历所有段落的锚点元素(文本框的载体),提取其中的文本内容;同时支持可选提取页眉页脚内的文本框内容。
  • extractShapeText方法:通过临时创建XWPFDocument和段落,复用POI的文本提取逻辑,避免手动解析复杂的XML结构。
  • 针对DOCX结构:文本框在DOCX中是以锚点(CTAnchor)形式绑定到段落上的,所以需要遍历每个段落的锚点列表来找到文本框。

注意:该代码适配POI 5.2.3版本,不同版本的XML Schema类可能存在细微差异,请根据实际版本调整。

内容的提问来源于stack exchange,提问作者Lako12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 12:23:19