word、pdf文档内容提取工具类

word、pdf文档内容提取工具类

1.依赖

xml 复制代码
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>5.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.5</version> <!-- 如果有 DOCX 相关 -->
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>3.0.5</version>
</dependency>

2.代码

java 复制代码
import cn.hutool.core.util.StrUtil;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Locale;
/**
* @Description 文档提取工具类
* @Date 2025/9/29 17:32
*/

public class DocumentTextExtractUtil {

    public static String extractText(InputStream inputStream, String fileType) throws IOException {
        if (inputStream == null) return "";
        if (StrUtil.isBlank(fileType)) throw new IllegalArgumentException("文件类型不能为空");


        String ft = normalizeFileType(fileType);
        byte[] data = toByteArray(inputStream);


        return switch (ft) {
            case "pdf" -> extractPdfText(data);
            case "docx" -> extractDocxText(data);
            case "doc" -> extractDocText(data);
            default -> new String(data, StandardCharsets.UTF_8);
        };
    }


    private static String normalizeFileType(String fileType) {
        String ft = fileType.trim().toLowerCase(Locale.ROOT);
        if (ft.startsWith(".")) ft = ft.substring(1);
        if (ft.contains("/")) {
            ft = ft.substring(ft.indexOf('/') + 1);
            if (ft.contains("+")) ft = ft.substring(0, ft.indexOf('+'));
        }
        return ft;
    }



    private static String extractPdfText(byte[] data) throws IOException {
        try (PDDocument doc = Loader.loadPDF(data)) { // 3.x 用 Loader.loadPDF
            PDFTextStripper stripper = new PDFTextStripper();
            stripper.setSortByPosition(true);
            String text = stripper.getText(doc);
            return text == null ? "" : text.trim();
        }
    }


    private static String extractDocxText(byte[] data) throws IOException {
        try (XWPFDocument doc = new XWPFDocument(new ByteArrayInputStream(data))) {
            StringBuilder sb = new StringBuilder();
            List<XWPFParagraph> paragraphs = doc.getParagraphs();
            for (XWPFParagraph p : paragraphs) {
                String t = p.getText();
                if (t != null && !t.isEmpty()) {
                    sb.append(t).append('\n');
                }
            }
            return sb.toString().trim();
        }
    }


    private static String extractDocText(byte[] data) throws IOException {
        try (HWPFDocument doc = new HWPFDocument(new ByteArrayInputStream(data))) {
            WordExtractor extractor = new WordExtractor(doc);
            String[] paragraphs = extractor.getParagraphText();
            StringBuilder sb = new StringBuilder();
            if (paragraphs != null) {
                for (String p : paragraphs) {
                    if (p == null) continue;
                    String clean = p.replaceAll("\\u0000", "").trim();
                    if (!clean.isEmpty()) sb.append(clean).append('\n');
                }
            }
            return sb.toString().trim();
        }
    }

    private static byte[] toByteArray(InputStream in) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
        byte[] buf = new byte[8192];
        int r;
        while ((r = in.read(buf)) != -1) {
            baos.write(buf, 0, r);
        }
        return baos.toByteArray();
    }
}

3.如何使用

java 复制代码
try (InputStream textStream = new ByteArrayInputStream(content)) {
                String text = DocumentTextExtractUtil.extractText(textStream, fileType.toLowerCase());
            } catch (Exception e) {
                log.warn("文本提取失败,文件: {},类型: {}", fileName, fileType, e);
            }
相关推荐
gc_229921 小时前
学习C#调用OpenXml操作word文档的基本用法(38:学习特殊符号类-2)
word·openxml·特殊符号
AZaLEan__1 天前
多源 BFS
java·开发语言·算法
程序员卷卷狗1 天前
Java转Go面试速记:Go基础22问,一篇理清高频易错点一篇理清高频易错点
java·面试·golang
zzzzz3691 天前
快速搭建SpringAi项目 集成智能问答,RAG,FUINCTION_CALLING等功能
java·ai编程
笨蛋不要掉眼泪1 天前
Java并发编程 :深入剖析LinkedBlockingQueue
java·开发语言·网络·并发
未若君雅裁1 天前
算法复杂度与数据结构:Java 集合篇的第一块基石
java·数据结构·算法
致Great1 天前
Claude Code 上线 Dynamic Workflows:一句话调度 1000 个子智能体并行干活
java·linux·服务器
一个做软件开发的牛马1 天前
Java 常用类:String不可变、新时间API与包装类陷阱
java·后端
yurenpai(27届找实习中)1 天前
redis_点评(25.附件店铺—把数据库里的店铺按【类型分组】,批量导入Redis 的 GEO 地理位置结构)
java·redis·缓存
云烟成雨TD1 天前
Spring AI Alibaba 1.x 系列【66】Graph 长期记忆
java·人工智能·spring