Java:Apache POI:我可以从MS Word(.doc)文件中获取干净的文本吗?

当我使用Apache POI时,我(以编程方式)从MS Word文件获取的字符串与我使用MS Word打开文件时可以看到的文本不同。

使用以下代码时:

File someFile = new File("some\\path\\MSWFile.doc"); InputStream inputStrm = new FileInputStream(someFile); HWPFDocument wordDoc = new HWPFDocument(inputStrm); System.out.println(wordDoc.getText()); 

输出是一行包含许多“无效”字符(是的,“盒子”),以及许多不需要的字符串,如“ FORMTEXT ”,“ HYPERLINK \l "_Toc##########" ”( ‘#’是数字数字),“ PAGEREF _Toc########## \h 4 ”等。

以下代码“修复”了单行问题,但维护了所有无效字符和不需要的文本:

 File someFile = new File("some\\path\\MSWFile.doc"); InputStream inputStrm = new FileInputStream(someFile); WordExtractor wordExtractor = new WordExtractor(inputStrm); for(String paragraph:wordExtractor.getParagraphText()){ System.out.println(paragraph); } 

我不知道我是否使用了错误的方法来提取文本,但这就是我在查看POI的快速指南时所提出的 。 如果我是,那么正确的方法是什么?

如果输出正确,是否有一种标准的方法来摆脱不需要的文本,或者我是否必须编写自己的filter?

有两个选项,一个直接在Apache POI中提供,另一个通过Apache Tika(内部使用Apache POI)提供。

第一个选项是使用WordExtractor ,但在调用时将其包装在对stripFields(String)调用中。 这将删除文本中包含的基于文本的字段,例如你见过的HYPERLINK。 您的代码将变为:

 NPOIFSFileSystem fs = new NPOIFSFileSytem(file); WordExtractor extractor = new WordExtractor(fs.getRoot()); for(String rawText : extractor.getParagraphText()) { String text = extractor.stripFields(rawText); System.out.println(text); } 

另一种选择是使用Apache Tika 。 Tika为各种文件提供文本提取和元数据,因此相同的代码也适用于.doc,.docx,.pdf和许多其他文件。 要获得干净,纯文本的文档文档(如果您愿意,也可以获得XHTML),您可以执行以下操作:

 TikaConfig tika = TikaConfig.getDefaultConfig(); TikaInputStream stream = TikaInputStream.get(file); ContentHandler handler = new BodyContentHandler(); Metadata metadata = new Metadata(); tika.getParser().parse(input, handler, metadata, new ParseContext()); String text = handler.toString(); 

该类可以读取Java中的.doc和.docx文件。 为此,我使用tika-app-1.2.jar:

 /* * This class is used to read .doc and .docx files * * @author Developer * */ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.URL; import org.apache.tika.detect.DefaultDetector; import org.apache.tika.detect.Detector; import org.apache.tika.io.TikaInputStream; import org.apache.tika.metadata.Metadata; import org.apache.tika.parser.AutoDetectParser; import org.apache.tika.parser.ParseContext; import org.apache.tika.parser.Parser; import org.apache.tika.sax.BodyContentHandler; import org.xml.sax.ContentHandler; class TextExtractor { private OutputStream outputstream; private ParseContext context; private Detector detector; private Parser parser; private Metadata metadata; private String extractedText; public TextExtractor() { context = new ParseContext(); detector = new DefaultDetector(); parser = new AutoDetectParser(detector); context.set(Parser.class, parser); outputstream = new ByteArrayOutputStream(); metadata = new Metadata(); } public void process(String filename) throws Exception { URL url; File file = new File(filename); if (file.isFile()) { url = file.toURI().toURL(); } else { url = new URL(filename); } InputStream input = TikaInputStream.get(url, metadata); ContentHandler handler = new BodyContentHandler(outputstream); parser.parse(input, handler, metadata, context); input.close(); } public void getString() { //Get the text into a String object extractedText = outputstream.toString(); //Do whatever you want with this String object. System.out.println(extractedText); } public static void main(String args[]) throws Exception { if (args.length == 1) { TextExtractor textExtractor = new TextExtractor(); textExtractor.process(args[0]); textExtractor.getString(); } else { throw new Exception(); } } } 

编译:

 javac -cp ".:tika-app-1.2.jar" TextExtractor.java 

跑步:

 java -cp ".:tika-app-1.2.jar" TextExtractor SomeWordDocument.doc 

试试这个,对我有用,纯粹是一个POI解决方案。 您将不得不寻找HWPFDocument对应物。 确保您正在阅读的文档早于Word 97,否则像我一样使用XWPFDocument。

 InputStream inputstream = new FileInputStream(m_filepath); //read the file XWPFDocument adoc= new XWPFDocument(inputstream); //and place it in a xwpf format aString = new XWPFWordExtractor(adoc).getText(); //gets the full text 

现在,如果你想要某些部分,你可以使用getparagraphtext但不要使用文本提取器,直接在这样的段落上使用它

 for (XWPFParagraph p : adoc.getParagraphs()) { System.out.println(p.getParagraphText()); }