在 Java 專案中需要從 Office 文件或 PDF 擷取純文字時,常見的解決方案有四種:Jacob (COM Bridge)、Apache POI、PDFBox、Apache Tika。本文逐一介紹其原理、適用場景與程式碼範例。
原理:Jacob (Java-COM Bridge) 呼叫 Windows 上已安裝的 Microsoft Word/Excel COM 自動化介面,將文件另存為 HTML/XML 再解析。
優點:相容性最好,支援所有 Word/Excel 版本功能(含複雜排版、巨集)。
缺點:僅限 Windows、需安裝 Office、啟動程序慢、佔用大量記憶體、需處理 dll 部署(32/64 位元對應)。
Maven 依賴:com.jacob:jacob:1.20(需額外放置 jacob.dll 至 java.library.path)。
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class JacobWordExtractor {
public static String extractText(String wordFilePath) {
ActiveXComponent word = new ActiveXComponent("Word.Application");
word.setProperty("Visible", new Variant(false));
Dispatch docs = word.getProperty("Documents").toDispatch();
Dispatch doc = Dispatch.call(docs, "Open", wordFilePath).toDispatch();
// 另存為純文字或 HTML 再解析
String tempHtml = System.getProperty("java.io.tmpdir") + "/temp.html";
Dispatch.call(doc, "SaveAs", tempHtml, new Variant(8)); // wdFormatHTML = 8
Dispatch.call(doc, "Close", new Variant(false));
word.invoke("Quit", new Variant[]{});
// 解析 tempHtml 取得純文字(略)
return parseHtmlToText(tempHtml);
}
}
優點:純 Java、跨平台、不需安裝 Office、社群活躍、支援 .doc/.docx/.xls/.xlsx。
缺點:對複雜排版(文字框、浮水印、特殊字型)支援有限、大檔案記憶體壓力大(建議使用 SAX 模式 XSSFReader)。
Maven 依賴:org.apache.poi:poi:5.3.0 (HSSF .doc/.xls)、org.apache.poi:poi-ooxml:5.3.0 (XSSF .docx/.xlsx)。
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.io.FileInputStream;
public class PoiDocxExtractor {
public static String extractText(String docxPath) throws Exception {
try (FileInputStream fis = new FileInputStream(docxPath);
XWPFDocument doc = new XWPFDocument(fis);
XWPFWordExtractor extractor = new XWPFWordExtractor(doc)) {
return extractor.getText();
}
}
// 舊版 .doc 使用 HWPFDocument + WordExtractor
}
優點:純 Java、跨平台、支援 PDF 1.7、可處理加密 PDF、可擷取文字座標。
缺點:中文支援需額外字型設定、複雜版面(多欄、表格)擷取順序可能錯亂、大檔案耗時。
Maven 依賴:org.apache.pdfbox:pdfbox:3.0.0。
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import java.io.File;
public class PdfBoxExtractor {
public static String extractText(String pdfPath) throws Exception {
try (PDDocument doc = PDDocument.load(new File(pdfPath))) {
PDFTextStripper stripper = new PDFTextStripper();
stripper.setSortByPosition(true); // 按位置排序
// 中文需設定字型:stripper.setFont(new PDType0Font(...));
return stripper.getText(doc);
}
}
}
優點:單一 API 擷取所有格式(Office、PDF、HTML、Email、圖片 OCR 等)、自動偵測 MIME 類型、支援中繼資料擷取。
缺點:間接層增加少許開銷、底層仍依賴 POI/PDFBox 等,問題同前。
Maven 依賴:org.apache.tika:tika-core:2.9.0, org.apache.tika:tika-parsers-standard-package:2.9.0。
import org.apache.tika.Tika;
import java.io.File;
public class TikaExtractor {
public static String extractText(String filePath) throws Exception {
Tika tika = new Tika();
return tika.parseToString(new File(filePath));
}
}
| 場景 | 推薦工具 | 理由 |
|---|---|---|
| Windows 伺服器、需完美還原 Word 複雜排版 | Jacob | 直接使用 Word 引擎轉換 |
| 跨平台、純 Java、處理 .docx/.xlsx 為主 | Apache POI | 標準純 Java 方案,生態完善 |
| 跨平台、PDF 文字擷取、需座標資訊 | PDFBox | PDF 專用,功能最全 |
| 需支援多種格式、不想管理多套庫 | Apache Tika | 統一介面,自動偵測格式 |
| 大量大檔案、記憶體敏感 | POI SAX / PDFBox 非序列化模式 | 串流處理,避免載入整份文件 |
PDType0Font.load(doc, new File("msyh.ttf")));POI .docx 通常正常,.doc 需確認編碼。PDDocument, XWPFDocument, ActiveXComponent (呼叫 Quit)。