解析Java中的大型docx文件

问题描述:

我有一个200页的docx文件需要解析。但我需要的数据包含在前20页左右。 Apache POI是否有办法检索文档的一部分?似乎使用Apache POI从docx文件中获取数据的唯一方法是使用getParagraphs或getText(),并且当我仅需要前几页时,我并不真的需要大量的字符串或段落列表。有什么建议么?解析Java中的大型docx文件

+1

阅读这篇文章的评论。它有你的问题的答案: https://*.com/questions/44300740/how-to-read-docx-using-apache-poi-in-page-by-page-mode – Waqas

不适用于POI。

如果你想在缓冲模式阅读,你可以做什么是你的docx文件转换为XML ,然后由线读取它行,提取你所需要的文本。 (相当低的水平)

DOCX文件已压缩XML,您可以用WinRAR打开并检查。

这样做了200页的文件,似乎不值得的,除非你有很少的内存。

由于*.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(); 

} 
}