本文整合 Apache POI(處理 Office 97-2003 格式)與 PDFBox,提供四種常見文件格式的文字擷取完整代碼,適合建立全文檢索、文件轉檔、內容分析等系統。
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import java.io.InputStream;
public Document getWordDocument(Index index, String url, String title, InputStream is) throws DocCenterException {
try {
WordExtractor ex = new WordExtractor(is);
String bodyText = ex.getText();
if (bodyText != null && !bodyText.isEmpty()) {
index.AddIndex(url, title, bodyText);
}
} catch (Exception e) {
throw new DocCenterException("無法從 Word 文件提取內容", e);
}
return null;
}
注意:hwpf 僅支援 .doc(二進位格式),.docx 請改用 org.apache.poi.xwpf.extractor.XWPFWordExtractor。
import org.apache.poi.hssf.usermodel.*;
import java.io.InputStream;
import java.lang.StringBuffer;
public Document getExcelDocument(Index index, String url, String title, InputStream is) throws DocCenterException {
StringBuffer content = new StringBuffer();
try {
HSSFWorkbook wb = new HSSFWorkbook(is);
for (int s = 0; s < wb.getNumberOfSheets(); s++) {
HSSFSheet sheet = wb.getSheetAt(s);
if (sheet == null) continue;
for (int r = 0; r <= sheet.getLastRowNum(); r++) {
HSSFRow row = sheet.getRow(r);
if (row == null) continue;
for (short c = 0; c <= row.getLastCellNum(); c++) {
HSSFCell cell = row.getCell(c);
if (cell != null) {
content.append(cell.getStringCellValue());
}
}
}
}
if (content.length() > 0) index.AddIndex(url, title, content.toString());
} catch (Exception e) {
throw new DocCenterException("無法從 Excel 文件提取內容", e);
}
return null;
}
注意:.xlsx 請改用 XSSFWorkbook;儲存格型別判斷建議用 cell.getCellType() 後再取值。
import org.apache.poi.hslf.*;
import org.apache.poi.hslf.model.*;
import java.io.InputStream;
public Document getPptDocument(Index index, String url, String title, InputStream is) throws DocCenterException {
StringBuffer content = new StringBuffer();
try {
SlideShow ss = new SlideShow(new HSLFSlideShow(is));
Slide[] slides = ss.getSlides();
for (Slide slide : slides) {
TextRun[] runs = slide.getTextRuns();
for (TextRun run : runs) content.append(run.getText());
content.append(slide.getTitle());
}
index.AddIndex(url, title, content.toString());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
注意:.pptx 請改用 org.apache.poi.xslf 套件。
import org.pdfbox.cos.COSDocument;
import org.pdfbox.pdfparser.PDFParser;
import org.pdfbox.pdmodel.PDDocument;
import org.pdfbox.pdmodel.PDDocumentInformation;
import org.pdfbox.util.PDFTextStripper;
import java.io.InputStream;
import java.io.IOException;
public Document getPdfDocument(Index index, String url, String title, InputStream is) throws DocCenterException {
COSDocument cosDoc = null;
PDDocument pdDoc = null;
try {
PDFParser parser = new PDFParser(is);
parser.parse();
cosDoc = parser.getDocument();
if (cosDoc.isEncrypted()) throw new DocCenterException("加密 PDF 無法處理");
PDFTextStripper stripper = new PDFTextStripper();
String text = stripper.getText(new PDDocument(cosDoc));
index.AddIndex(url, title, text);
// 讀取中繼資料標題
pdDoc = new PDDocument(cosDoc);
PDDocumentInformation info = pdDoc.getDocumentInformation();
if (info.getTitle() != null && !info.getTitle().isEmpty()) {
title = info.getTitle();
}
} catch (IOException e) {
throw new DocCenterException("無法處理 PDF 文件", e);
} finally {
closeQuietly(cosDoc);
closeQuietly(pdDoc);
}
return null;
}
private void closeQuietly(COSDocument doc) {
if (doc != null) try { doc.close(); } catch (IOException ignored) {}
}
private void closeQuietly(PDDocument doc) {
if (doc != null) try { doc.close(); } catch (IOException ignored) {}
}
try-with-resources 管理資源。XWPFWordExtractor (.docx) + WordExtractor (.doc)WorkbookFactory.create(is) 自動偵測 .xls/.xlsxSlideShowFactory.create(is) 自動偵測 .ppt/.pptxPDFTextStripper 支援排序、區域擷取等進階功能。掌握 POI 與 PDFBox 的核心 API,即可快速建立企業級文件內容擷取管線。實務上建議封裝為統一介面 DocumentExtractor,依副檔名自動派發對應實作,並加入例外處理、日誌、編碼偵測等健壯性機制。