如何从.doc和.docx文件中提取纯文本?

60

有没有人可以推荐一些方法,以便从.doc.docx中提取纯文本?

我找到了这个,想知道是否有其他建议?


1
这是一个完美的适合软件推荐。应该转移到那里。 - demongolem
如果我们有“软件推荐”,为什么不将其转移至此处呢?我也搜索了类似任务的软件,但没有找到最佳答案。但是我可以推荐pandoc作为最佳解决方案,它甚至可以正确地转换表格。因此,我建议重新开启问题。 - Hubbitus
显然你不是在使用Mac电脑,但如果你是的话,你可以在命令行中使用"textutil"快速获取各种专有文档类型的纯文本。 - dave
1
这个问题正在Meta上讨论。请点击链接查看:https://meta.stackoverflow.com/questions/383134/should-how-to-extract-just-plain-text-from-doc-docx-files-be-migrated - TylerH
@Taryn:能否解释一下为什么这个问题是不相关的,但是https://dev59.com/4l3Va4cB1Zd3GeqPBpTz不是? - slashmais
6个回答

79

如果您想要纯文本格式(我的要求),那么您所需要的只是

unzip -p some.docx word/document.xml | sed -e 's/<[^>]\{1,\}>//g; s/[^[:print:]]\{1,\}//g'

我在命令行玩转网站找到了这个方法。

它会解压docx文件并获取实际文档,然后去除所有xml标签。显然,所有格式都会丢失。


30
我喜欢这个命令,但通常在最终版本中保留换行符仍然很有用。因此,我使用了下面的命令:unzip -p document.docx word/document.xml | sed -e 's/<\/w:p>/\n/g; s/<[^>]\{1,\}>//g; s/[^[:print:]\n]\{1,\}//g'请注意额外的sed参数,用实际的换行符替换XML表示的换行符,并将最后一个sed参数编辑为不删除换行符。这使得上面的命令能更好地适用于比较Word文档。 - Jeff McJunkin
感谢Rob!@Jeff:我同意,但是在实践中以下命令对我更有效:unzip -p document.docx word/document.xml | sed -e 's/</w:p>/ /g; s/<[^>]{1,}>/ /g; s/[^[:print:]]{1,}/ /g' - Tom G
这在处理非 ASCII 字符时如何表现?特别是更为奥妙的字符集? - einpoklum
@einpoklum 命令的第一部分获取原始 XML,所以这将很好地工作。第二部分获取所有非 XML 标签字符串,并用新行分隔它们。只要 sed 不会在奇怪的字符集上出错,你就应该没问题。如果你发现不是这种情况,请回复此帖。 - rob
this doesn't preserve newline - mending3
显示剩余4条评论

47

LibreOffice

一个选项是以无界面模式运行libreoffice/openoffice(请确保所有其他的LibreOffice实例都已关闭):

libreoffice --headless --convert-to "txt:Text (encoded):UTF8" mydocument.doc

更多详细信息请参见此链接:http://ask.libreoffice.org/en/question/2641/convert-to-command-line-parameter/

有关LibreOffice过滤器的列表,请参见http://cgit.freedesktop.org/libreoffice/core/tree/filter/source/config/fragments/filters

由于OpenOffice命令行语法有点太复杂了,因此有一个方便的包装器可以使该过程更加容易:unoconv

Apache POI

另一个选择是Apache POI - 一个得到良好支持的Java库,与antiword不同的是,它可以读取、创建和转换.doc.docx.xls.xlsx.ppt.pptx文件。

这里是将 .doc.docx 文档转换为纯文本的最简单 Java 代码:

import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.poi.POITextExtractor;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.xmlbeans.XmlException;

public class WordToTextConverter {
    public static void main(String[] args) {
        try {
            convertWordToText(args[0], args[1]);
        } catch (ArrayIndexOutOfBoundsException aiobe) {
            System.out.println("Usage: java WordToTextConverter <word_file> <text_file>");
        }
    }

    public static void convertWordToText(String src, String desc) {
        try {
            FileInputStream fs = new FileInputStream(src);
            final POITextExtractor extractor = ExtractorFactory.createExtractor(fs);
            FileWriter fw = new FileWriter(desc);
            fw.write(extractor.getText());
            fw.flush();
            fs.close();
            fw.close();

        } catch (IOException | OpenXML4JException | XmlException e) {
            e.printStackTrace();
        }
    }
}


# Maven dependencies (pom.xml):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>my.wordconv</groupId>
<artifactId>my.wordconv.converter</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>3.17</version>
    </dependency>
</dependencies>
</project>

注意:您需要将apache poi库添加到类路径中。在ubuntu/debian上,可以使用sudo apt-get install libapache-poi-java命令安装这些库——它们将安装在/usr/share/java下。对于其他系统,您需要download该库并解压缩存档到一个文件夹中,您应该使用该文件夹代替/usr/share/java。如果您使用maven/gradle(推荐选项),则应像代码片段中所示那样包含org.apache.poi dependencies
相同的代码将同时适用于.doc.docx,因为所需的转换器实现将通过检查二进制流来选择。
编译上面的类(假设它在默认包中,并且apache poi jars位于/usr/share/java下):
javac -cp /usr/share/java/*:. WordToTextConverter.java

运行转换:

java -cp /usr/share/java/*:. WordToTextConverter doc.docx doc.txt 

一个可克隆的Gradle项目,它拉取所有必要的依赖项并生成包含gradle installDist命令的包装脚本。


1
如果你要加入Java选项,我想提一下“我的”docx4j(它也处理pptx、xlsx)。对于文本提取,你可以使用https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/TextUtils.java。 - JasonPlutext
1
请参考LibreOffice问答社区中关于如何在运行LibreOffice实例的同时并行运行命令行转换的问题1686:http://ask.libreoffice.org/en/question/1686/how-to-not-connect-to-a-running-instance/ - Mihai Capotă
2
当我尝试使用LibreOffice转换一些docx文件时,出现了一个奇怪的错误“错误:请重新验证输入参数...”,但当我切换到“--convert-to“txt:Text(encoded):UTF8”时,该错误消失了,所以我建议您这样做(即使您没有非ASCII字符)。 - yoniLavi
3
不需要卸载现有的GUI安装版本 - 在这种情况下,该二进制文件只是不在$PATH中可用;你仍然可以在macOS上调用它,例如:/Applications/LibreOffice.app/Contents/MacOS/soffice --headless --help - ccpizza
2
@senderle:好的,brew cask info libreoffice指向 https://github.com/Homebrew/homebrew-cask/blob/master/Casks/libreoffice.rb 公式,你可以在那里看到它还在 /usr/local/bin/soffice 下放置了一个包装脚本。知道具体发生了什么是很有用的,以防公式被删除,或者你需要比 brew 提供的更新版本。 - ccpizza
显示剩余2条评论

16

试试Apache Tika。 它使用基于Java的库(包括Apache POI)支持大多数文档格式(所有MS Office格式,OpenOffice / LibreOffice格式,PDF等)。 使用起来非常简单:

java -jar tika-app-1.4.jar --text ./my-document.doc

10

1
我们已经多次使用过(上面提到的)Antiword,但它无法处理docx格式的文件。根据其网页信息:“Antiword可以将Word 2、6、7、97、2000、2002和2003版本的二进制文件转换为纯文本和PostScript文件。” - Arpad Horvath -- Слава Україні

5

我认为wv比catdoc或antiword更好。它可以处理.docx并转换为文本或html格式。这里是我在.bashrc文件中添加的一个函数,用于在终端临时查看文件。根据需要进行更改。

# open word in less (ie worl document.doc)
worl() {
    DOC=$(mktemp /tmp/output.XXXXXXXXXX)
    wvText $1 $DOC
    less $DOC
    rm $DOC
}

2
对于使用OSX的用户,您可以执行brew install wv && brew install elinks - Sean Allred
非常好用,支持 .doc 和 .docx。 - Steve Childs

1
我最近处理了这个问题,发现OpenOffice / LibreOffice 命令行工具在生产环境中不可靠(处理了数千个文档,同时处理了几十个文档)。 最终,我构建了一个轻量级的包装器 DocRipper,它比较快速,可以从 .doc,.docx 和 .pdf 中获取所有文本内容而无需格式化。 DocRipper 使用 Antiword、grep 和 pdftotext 来提取文本并返回它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接