如何从MS Word中提取文本?

3

我想打开一个Word文档,提取文档中的所有文本,并使用Win32::OLE将其显示给用户。

#usr/bin/perl
#OLEWord.pl

#Use string and print warnings
use strict;use warnings;
#Using OLE + OLE constants for Variants and OLE enumeration for Enumerations
use Win32::OLE;
use Win32::OLE::Const 'Microsoft Word';

$Win32::OLE::Warn = 3;

#set the file to be opened
my $file = '/work/Test.docx';

#Create a new instance of Win32::OLE for the Word application, die if could not open the application
my $MSWord = Win32::OLE->new('Word.Application','Quit') and "Opened Word" or die     "Unable to open document ", Win32::OLE->LastError(); 
#Set the screen to Visible, so that you can see what is going on
$MSWord->{'Visible'} = 1;
#open the request file or die and print warning message
my $Doc = $MSWord->Documents->Open('C:\work\Test.docx') or die "Could not open ", $file, " Error:", Win32::OLE->LastError();

#$MSWord->ActiveDocument->SaveAs({Filename => 'AlteredTest.docx', 
                            #FileFormat => wdFormatDocument});
                            
                            
sub ShowObjs {
my $obj = shift;
foreach (sort keys %$obj) {
print "Keys: $_ - $obj->{$_}\n"; }
 }

 my $paragraphs = $Doc->Paragraphs;
 ShowObjs($paragraphs);

 #  Get and print the Text inside the opened file
 my $paragraphs = $Doc->Paragraphs;
 my $txt = $Doc->Range->Text;
 print $txt;
                            
 $MSWord->ActiveDocument->Close;
 $MSWord->Quit;

我遇到了这个错误代码:

来自 "Microsoft Word" 的 OLE 异常:

命令失败

Win32::OLE(0.1709) 在 OLEWord.pl 的第20行, 在 "Open" 方法/属性获取中出现错误 ox800a1066。

更新: 我可以正常打开 Word 应用程序,只有当我尝试打开文件时才会出现问题。

你确定文件扩展名是“doc”吗?打开失败让我觉得文件扩展名应该是docx,而不是doc。 - mrk
我把文件改成了docx格式,但仍然没有。 - Shahab
我能够使用上述脚本打开Word文件(doc和docx),但在$txt = $Word->Paragraphs...处失败。您是否有打开该文件的权限,而且该文件没有在其他地方被Word打开? - mrk
是的,我创建了测试文件,但我也不确定如何从Word文档中获取文本。 - Shahab
2
确保文件可访问。尝试使用绝对路径。 - jira
2个回答

4

我有几个使用Win32::OLE的脚本,用于将DOC转换为各种输出格式。它们通常以以下方式开始:

use Win32::OLE;
use Win32::OLE::Const 'Microsoft Word';
my $wr = Win32::OLE->new('Word.Application')
    or die "Failure - word. \n";

$wr->{DisplayAlerts} = wdAlertsNone;
$wr->{Visible} = 0;

my $Doc = $wr->Documents->Open({
    FileName           => $input_file_path,
    ConfirmConversions => 0,
    AddToRecentFiles   => 0,
    Revert             => 0,
    ReadOnly           => 1,
    OpenAndRepair      => 0,
}) or exit;

...

请注意,$input_file_path 必须包含您文件的绝对路径。您还可以启用 VisibleDisplayAlerts 以查看 Word 可能给出的任何错误。 编辑: 您可以使用 in 枚举器遍历段落:
use Win32::OLE qw(in);

...

my $paragraphs = $Doc->Paragraphs;
for my $par (in $paragraphs) {
    print $par->Range->Text();
}

或者您也可以使用Word自带的导出功能,将文档保存为支持的格式之一:

$Doc->SaveAs({
    FileName   => 'c:\\work\\Test.txt',
    FileFormat => wdFormatEncodedText,
});

后一种方法的优点是尽可能保留格式,这样可以更好地呈现项目符号、编号等内容。

好的,所以它在打开文件时是有效的,但现在我遇到了这个错误:尝试释放未引用的标量:SV 0xb8b3c4,Perl解释器:0x3f3d6c。 - Shahab
@Shahab - 你能否展示一下你正在使用的代码吗?你可以更新你的问题。 - bvr
@Shahab - 请查看我的更新答案,了解段落遍历和导出选项。使用 ShowObjs 函数时,请记住 Win32::OLE 只是 OLE 调用的薄包装器,因此您不能将其视为常规哈希。奇怪的错误是通常的结果。 - bvr
嗯,我喜欢将其保存为文本文件的想法。 - Shahab

1

Win32::OLE 在交互方面可能有些奇怪。如果任何事情触发了提示,您可能会收到这样的消息。通常情况下,它可能是想以只读方式打开文件,并弹出对话框,但这些对话框可能会在 Win32::OLE 的默认初始化下出现问题。

如果是这种情况,请调用

Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE);

在做任何事情之前,例如实例化任何对象(即,在 Win32::OLE->new 之前),可能会有诀窍。


你使用的是哪个版本的Word、Windows和Perl? - Stuart Watt
Word 2010,Windows XP和Perl 5.12 - Shahab
问题是我可以通过脚本成功打开Word。问题现在是尝试在Word打开后打开文件。 - Shahab
嗯,这不是一个容易的问题。与此同时,我在CPAN上维护Text::Extract::Word,它也可以从Word(经典的.doc,但不是.docx)文件中提取文本,但不运行Word或OLE来完成它。 - Stuart Watt
这是一个奇怪的问题,因为我可以打开Excel并修改和打印文本,只是Word出了问题。 - Shahab

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