Как извлечь текст из MS 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;

Я получаю этот код ошибки:

Исключение OLE из Microsoft Word:

Команда не выполнена

Win32 :: OLE (0.1709) ошибка ox800a1066 в МЕТОД / PROPERTYGET Открыть в OLEWord.pl строке 20

Обновление: я могу открыть приложение Word нормально, проблема возникает только тогда, когда я пытаюсь открыть файл.


person Shahab    schedule 15.07.2011    source источник
comment
Вы уверены, что расширение файла - «док»? Ошибка открытия заставляет меня думать, что расширение файла - docx, а не doc.   -  person mrk    schedule 15.07.2011
comment
Я изменил файл на docx и все равно нет   -  person Shahab    schedule 15.07.2011
comment
Я могу открывать файлы Word (doc и docx) с помощью приведенного выше сценария (но получаю сбои на $txt = $Word->Paragraphs...). У вас есть разрешение на открытие файла, а файл еще не открыт в Word?   -  person mrk    schedule 15.07.2011
comment
Да, я создал файл для тестирования, и в том, в чем я тоже не уверен, как получить текст из слова docuemtn   -  person Shahab    schedule 15.07.2011
comment
Убедитесь, что файл доступен. Попробуйте использовать абсолютный путь.   -  person jira    schedule 16.07.2011


Ответы (2)


У меня есть несколько скриптов для преобразования DOC в различные выходные форматы с использованием Win32 :: OLE. Обычно они начинаются так:

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 должен содержать абсолютный путь к вашему файлу. Вы также можете включить Visible и DisplayAlerts, чтобы увидеть любую ошибку, которую 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,
});

Преимущество последнего метода заключается в том, что по возможности сохраняется форматирование, что дает лучшие результаты для маркеров, нумерации и т. Д.

person bvr    schedule 16.07.2011
comment
хорошо, значит, он работал при открытии файла, но теперь я получаю эту ошибку: Попытка освободить скаляр без ссылок: SV 0xb8b3c4, интерпретатор Perl: 0x3f3d6c.? - person Shahab; 18.07.2011
comment
@Shahab - не могли бы вы показать код, который вы используете? Вы можете обновить свой вопрос. - person bvr; 18.07.2011
comment
@Shahab - см. Мой обновленный ответ о параметрах обхода абзацев и экспорта. С функцией ShowObjs - помните, что Win32::OLE - это просто тонкая оболочка для вызовов OLE, поэтому вы не можете рассматривать это как обычные хэши. Обычный результат - странные ошибки. - person bvr; 18.07.2011
comment
Хм, мне нравится идея сохранить его как текстовый файл - person Shahab; 19.07.2011

Win32::OLE может быть немного забавным в общении. если что-то вызывает запрос, вы можете получить подобное сообщение. Обычно может случиться так, что он хочет открыть файл, например, только для чтения, и установить диалог, но эти диалоги могут прерваться при инициализации по умолчанию Win32::OLE.

Если это так, позвоните

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

прежде, чем вы сделаете что-либо вроде создания экземпляров любых объектов (т.е. до Win32::OLE->new), может помочь.

person Stuart Watt    schedule 15.07.2011
comment
Какую версию Word, Windows и Perl вы используете? - person Stuart Watt; 15.07.2011
comment
Word 2010, Windows XP и Perl 5.12 - person Shahab; 15.07.2011
comment
Дело в том, что я могу нормально открыть Word через скрипт. Теперь проблема заключается в попытке открыть файл после открытия Word. - person Shahab; 15.07.2011
comment
Хммм, непростой. А пока я поддерживаю Text :: Extract :: Word на CPAN, который также извлекает текст из файлов Word (классический .doc, но не .docx), но не запускаю Word или OLE для этого. - person Stuart Watt; 15.07.2011
comment
хм, это странная проблема, потому что я могу открыть Excel, изменить и распечатать текст, это просто слово - person Shahab; 15.07.2011