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

Xen*_*oRo 11 java text ms-word extraction apache-poi

使用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());
Run Code Online (Sandbox Code Playgroud)

输出是一行,有许多"无效"字符(是的,"盒子"),还有许多不需要的字符串,如" 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

小智 7

该类可以读取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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编译:

javac -cp ".:tika-app-1.2.jar" TextExtractor.java
Run Code Online (Sandbox Code Playgroud)

跑步:

java -cp ".:tika-app-1.2.jar" TextExtractor SomeWordDocument.doc
Run Code Online (Sandbox Code Playgroud)


Gag*_*arr 6

有两个选项,一个直接在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);
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用Apache Tika.Tika为各种文件提供文本提取和元数据,因此相同的代码也适用于.doc,.docx,.pdf和许多其他文件.要获得干净,纯文本的word文档(如果你愿意,也可以获得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();
Run Code Online (Sandbox Code Playgroud)

  • 第二个解决方案在我的测试中不起作用.TIKA-1.2从.doc文件返回FORMCHECKBOX和其他东西..docx文件工作正常. (2认同)