2017-08-17 115 views
0

我有一個200頁的docx文件需要解析。但我需要的數據包含在前20頁左右。 Apache POI是否有辦法檢索文檔的一部分?似乎使用Apache POI從docx文件中獲取數據的唯一方法是使用getParagraphs或getText(),並且當我僅需要前幾頁時,我並不真的需要大量的字符串或段落列表。有什麼建議麼?解析Java中的大型docx文件

+1

閱讀這篇文章的評論。它有你的問題的答案: https://stackoverflow.com/questions/44300740/how-to-read-docx-using-apache-poi-in-page-by-page-mode – Waqas

回答

0

不適用於POI。

如果你想在緩衝模式閱讀,你可以做什麼是你的docx文件轉換爲XML ,然後由線讀取它行,提取你所需要的文本。 (相當低的水平)

DOCX文件已壓縮XML,您可以用WinRAR打開並檢查。

這樣做了200頁的文件,似乎不值得的,除非你有很少的內存。

0

由於*.docx只是一個ZIP存檔我們還可以打開它爲FileSystemFileSystems得到,然後再處理它的內容完全獨立的第三方庫。

這是使用StAX一個非常簡單的例子。

import java.io.*; 
import java.nio.file.*; 

import javax.xml.stream.*; 
import javax.xml.stream.events.*; 

import javax.xml.namespace.QName; 

public class UnZipAndReadOOXMLFileSystem { 

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

    Path source = Paths.get("source.docx"); 

    FileSystem fs = FileSystems.newFileSystem(source, null); 

    Path document = fs.getPath("/word/document.xml"); 

    XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(Files.newInputStream(document)); 

    StringBuffer content = new StringBuffer(); 

    String contentSearched = "the content we are searching for"; 

    boolean inParagraph = false; 
    String paragraphText = ""; 
    while(reader.hasNext()) { 
    XMLEvent event = (XMLEvent)reader.next(); 
    if(event.isStartElement()){ 
    StartElement startElement = (StartElement)event; 
    QName startElementName = startElement.getName(); 
    if(startElementName.getLocalPart().equalsIgnoreCase("p")) { //start element of paragraph 
    inParagraph = true; 
    content.append("<p>"); 
    paragraphText = ""; 
    } 
    } else if (event.isCharacters() && inParagraph) { //characters in elements of this paragraph 
    String characters = event.asCharacters().getData(); 
    paragraphText += characters; // can be splitted into different run elements 
    } else if (event.isEndElement() && inParagraph) { 
    EndElement endElement = (EndElement)event; 
    QName endElementName = endElement.getName(); 
    if(endElementName.getLocalPart().equalsIgnoreCase("p")) { //end element of paragraph 
    inParagraph = false; 
    content.append(paragraphText); 
    content.append("</p>\r\n"); 
    //here you can check the paragraphText and exit the while if you found what you are searching for 
    if (paragraphText.contains(contentSearched)) break; 
    } 
    } 
    } 

    System.out.println(content); 

    fs.close(); 

} 
}