<{{./BAN/TOPBAN}}> Media TT

Офисные Программы
Переход к OpenOffice: пакетное преобразование существующих документов

<{{./BAN/ARTIC5}}>
<{{./BAN/ARTICDN}}>
Широко известно, что при помощи OpenOffice 2.0, открытой альтернативы пакету Microsoft Office, можно открывать файлы, созданные в Microsoft Office, и затем сохранять их в родном формате OpenOffice — zip-архиве, содержащем документ в виде XML-файла, соответствующего стандарту OpenDocument от OASIS. Таким образом можно преобразовывать в новый формат существующие документы Word, таблицы Excel и презентации PowerPoint. (В статье Opening Open Formats with XSLT на XML.com приводится пример простого приложения, использующего эти возможности: XSL-шаблон, который извлекает заголовки слайдов и заметки из файла с презентацией и сохраняет их в отдельный файл, который вы могли бы использовать как план своего выступления.) Более того, OpenOffice позволяет экспортировать все эти виды файлов в формат PDF.

 

Если вы собираетесь преобразовывать ваши файлы в новый формат по одному, то вам придётся открыть и заполнить несколько диалоговых окон для каждого файла. Если вам требуется преобразовать несколько сотен файлов, то такой подход окажется затруднительным. Что же делать, если у вас есть большая куча документов Word, таблиц Excel и презентаций PowerPoint, и вам нужно загрузить XML-версии всех файлов в одну базу данных, которая поддерживала бы запросы к содержимому этих XML-документов? Например, если вы — это штат Массачусетс или фирма IBM?

 

Как и в продукте фирмы Microsoft, в OpenOffice есть макроязык. При запуске OpenOffice из командной строки Linux или Windows можно указывать, чтобы выполнился определённый макрос. Можно даже передать этому макросу в качестве параметра имя файла. Далее, если использовать ключ -invisible при запуске OpenOffice из командной строки, то его графический интерфейс (GUI) не будет отображаться. А если задействовать обе этих возможности вместе, то получится командная строка, которая преобразует файл Microsoft Office в файл OpenOffice (или в файл Acrobat) безо всякого GUI. Теперь, чтобы преобразовать сотню файлов, достаточно простого скрипта (например, на языке Perl), чтобы создать пакетный файл либо шелл-скрипт из сотни команд, каждая из которых преобразует один файл.

 

(Замечание: макросы, который вдохновили меня на создание этой статьи, явно были написаны для OpenOffice 1. x, — но тот макрос, который я из них собрал, был протестирован мной в OpenOffice 2.0 в Windows и в Linux.)

Создание макросов для преобразования

 

Все процедуры, которые понадобятся в ваших макросах, приведены ниже. Чтобы создать в OpenOffice модуль макросов и сохранить в него эти процедуры, выберите пункт меню Tools=>Macros и затем Organize Macros, OpenOffice.org Basic, Organizer, New. Создастся новый модуль макросов. Назовите его MyConversions и закройте диалоговое окно.

 

Новый модуль будет отображаться в дереве макросов под именем /My Macros/Standard/MyConversions, как показано ниже:

 

 

 

Выберите модуль MyConversions и нажмите кнопку Edit. В появившемся скрипте строчки Sub Main и End Main служат шаблоном для будущего макроса. Замените их следующим кодом, после чего сохраните модуль: ' За основу взят код с

http://www.oooforum.org/forum/viewtopic.phtml?t=3772

 

' Сохранить документ в формате Acrobat PDF.

Sub SaveAsPDF( cFile )

   cURL = ConvertToURL( cFile )

   ' Открыть документ. Мы предполагаем, что тип документа

   ' будет корректно распознан, и поэтому не указываем

   ' конкретный фильтр импорта.

   oDoc = StarDesktop.loadComponentFromURL( cURL, "_blank", 0, _

            Array(MakePropertyValue( "Hidden", True ),))

 

   cFile = Left( cFile, Len( cFile ) - 4 ) + ".pdf"

   cURL = ConvertToURL( cFile )

 

   ' Сохранить документ, используя фильтр экспорта.

   oDoc.storeToURL( cURL, Array(_

            MakePropertyValue( "FilterName", "writer_pdf_Export"

),)

 

   oDoc.close( True )

End Sub

 

' Сохранить документ в формате Microsoft Word.

Sub SaveAsDoc( cFile )

   ' практически совпадает с SaveAsPDF

   cURL = ConvertToURL( cFile )

   oDoc = StarDesktop.loadComponentFromURL( cURL, "_blank", 0, (_

            Array(MakePropertyValue( "Hidden", True ),))

 

 

   cFile = Left( cFile, Len( cFile ) - 4 ) + ".doc"

   cURL = ConvertToURL( cFile )

 

   oDoc.storeToURL( cURL, Array(_

            MakePropertyValue( "FilterName", "MS WinWord 6.0" ),)

   oDoc.close( True )

 

End Sub

 

 

' Сохранить документ в формате OpenOffice 2.

Sub SaveAsOOO( cFile )

   ' практически совпадает с SaveAsPDF

   cURL = ConvertToURL( cFile )

   oDoc = StarDesktop.loadComponentFromURL( cURL, "_blank", 0, _

            Array(MakePropertyValue( "Hidden", True ),))

 

   ' Расширение нового файла выбирается на основании расширения

   ' исходного файла, переведённого в нижний регистр.

   Select Case LCase(Right(cFile,3))

     Case "ppt"         ' PowerPoint file.

       cFileExt = "odp"

     Case "doc"         ' Word file.

       cFileExt = "odt"

     Case "xls"         ' Excel file.

       cFileExt = "ods"

     Case Else

       cFileExt = "xxx"

    End Select

 

   cFile = Left( cFile, Len( cFile ) - 3 ) + cFileExt

   cURL = ConvertToURL( cFile )

 

   oDoc.storeAsURL( cURL, Array() )

   oDoc.close( True )

 

End Sub

 

 

Function MakePropertyValue( Optional cName As String,

Optional uValue ) _

   As com.sun.star.beans.PropertyValue

   Dim oPropertyValue As New com.sun.star.beans.PropertyValue

   If Not IsMissing( cName ) Then

      oPropertyValue.Name = cName

   EndIf

   If Not IsMissing( uValue ) Then

      oPropertyValue.Value = uValue

   EndIf

   MakePropertyValue() = oPropertyValue

End Function

 

 

Язык OpenOffice Basic похож на VBA — язык макросов в Microsoft Office; VBA похож на Visual Basic, а он, в свою очередь, — на тот самый BASIC, который для тех из нас, кто постарше, был первым изученным языком программирования. Я не углублялся ни в один из этих языков, но если вам что-то будет неясно в отношении их синтаксиса, то ответы достаточно легко находятся несколькими запросами к Google. Например, я совершенно не представлял себе, как записать оператор выбора в процедуре SaveAsOOO, но нашёл всю необходимую информацию с помощью Google и справки OpenOffice.

 

Весь код состоит из трёх процедур и одной функции. Процедура SaveAsPDF и функция MakePropertyValue взяты из сообщения на форуме OpenOffice. Процедура SaveAsDoc отличается от SaveAsPDF только параметром, передаваемым в MakePropertyValue, — названием фильтра экспорта. Если вы хотите добавить процедуры для сохранения таблиц OpenOffice в файлы Excel, или презентаций OpenOffice Impress в файлы PowerPoint, то всё что вам потребуется — взять копию одной из этих процедур и изменить в ней название фильтра экспорта и расширение нового файла.

 

Что замечательно в процедуре SaveAsOOO — это её универсальность. Вам не нужно определять, чем является входной файл — документом Word, таблицей Excel или презентацией PowerPoint, и не нужно указывать формат для нового файла. OpenOffice определит всё это сам. И как вы видите, единственное существенное отличие этой процедуры от SaveAsPDF — то, что я добавил код, определяющий для нового файла правильное расширение.

Запуск преобразования

 

Макросы можно запускать из командной строки вне зависимости от того, открыт ли в этот момент OpenOffice, или вы из него уже вышли. Примерно так должна выглядеть командная строка для преобразования файла Word в формат OpenOffice на компьютере с Windows, разбитая здесь на две строки: "C:\Program Files\OpenOffice.org 2.0\program\soffice"

  -invisible

macro:///Standard.MyConversions.SaveAsOOO(c:\temp\sample.doc)

 

 

На моём компьютере файл soffice.exe не находится в пути поиска исполняемых файлов, поэтому я вынужден указывать для него полный путь — заключённый в кавычки, потому что он содержит пробелы. Ключ -invisible указывает OpenOffice, что не нужно показывать экран с приветствием, создавать документ по умолчанию, и вообще отображать какой-либо GUI. (Чтобы увидеть список всех доступных ключей, попробуйте запустить soffice.exe из командной строки, задав единственный параметр -?) Имя макроса указывается в виде, похожем на URL: сначала путь в дереве макросов до нужного макроса, затем параметр в скобках — имя файла, который требуется преобразовать. Указывать имя для нового файла не нужно — макрос выберет его сам в зависимости от исходного имени и выполняемого преобразования.

 

Поскольку макрос дописывает http:// в начало имени исходного файла, чтобы получить его URL, то это имя должно содержать полный путь к файлу, как показано в примере, — иначе вы получите сообщение об ошибке «Недопустимый URL».

 

В Linux в командной строке нужно указывать другое имя исполняемого файла. Установщик OpenOffice в моей Ubuntu поместил файл ooffice2 в путь поиска исполняемых файлов, так что мне не приходится указывать при его запуске полный путь. Я заключил вызов макроса в кавычки, потому что иначе находящиеся в нём скобки неправильно обрабатывались оболочкой. Во всех других отношениях те же самые макросы, что были созданы описанным выше способом, работали превосходно. ooffice2 -invisible

 

"macro:///Standard.MyConversions.SaveAsOOO(/home/bob/temp/sample.doc)"

 

 

Я попытался преобразовать несколько разных файлов. Тестовый файл sample.doc лежит у меня уже несколько лет для испытания программ и сервисов, которые предлагают преобразовывать файлы Word в XML. В этом файле используются встроенные и пользовательские стили для абзацев и знаков, вложенные маркированные списки, изображение, таблица с объединёнными ячейками, вложенная таблица Excel, и ещё несколько вещей, на которых может споткнуться программа для преобразования. SaveAsOOO с этим файлом прекрасно справился.

Давайте преобразуем файлы MS Office

 

Теперь, когда у вас есть открытый многоплатформенный инструмент для преобразования новых и старых (по крайней мере, вплоть до Office 97) файлов MS Office в XML-документы открытого стандарта, как же лучше всего воспользоваться этим инструментом? Всё, что может запускаться из командной строки, может использоваться в пакетном режиме — без вмешательства пользователя. Можно создать Perl-скрипт, который бы принимал список входных файлов и создавал пакетный файл либо шелл-скрипт из последовательности команд, подобных приведённым выше, которые бы преобразовывали по одному файлу. Если то, что вам на самом деле нужно — сам XML-документ, то этот скрипт может заодно извлекать его из zip-архива, которым является файл OpenOffice, и переименовывать соответствующим образом. Шелл-скрипт, выполняющий всё это, выглядит так: # Не забудьте: $1 должен содержать имя файла

# с полным путём, но без расширения

ooffice2 -invisible

"macro:///Standard.MyConversions.SaveAsOOO($1.doc)"

unzip -o $1.odt content.xml

cp content.xml $1.xml

 

 

Пакетный файл для Windows: REM Не забудьте: %1 должен содержать имя файла

REM с полным путём, но без расширения

set OooExe="C:\Program Files\OpenOffice.org 2.0\program\soffice"

%OOOExe%  -invisible

macro:///Standard.MyConversions.SaveAsOOO(%1.doc)

unzip -o %1.odt content.xml

copy content.xml %1.xml

Если вы собираетесь регулярно преобразовывать большое число документов, то запуск нового экземпляра OpenOffice для каждого преобразования будет существенно замедлять весь процесс. В Windows файл soffice.exe можно запустить в режиме «быстрого старта» (с ключом -quickstart); тогда запускаемые после этого преобразования будут выполняться быстрее. Кроме этого, можно с помощью ключа -accept указать строку Universal Network Objects, которая позволила бы, используя API, управлять запущенным экземпляром OpenOffice из программы, написанной на C++, OpenOffice Basic, Python, Java или других языках. В этом случае можно было бы передавать имена документов для преобразования в запущенный экземпляр OpenOffice, используя вызовы API.

 

Наиболее интересной возможностью, которую предоставляет этот подход, мне кажется даже не преобразование присылаемых мне новых файлов Word и Excel в XML-формат OpenOffice, — а преобразование имеющихся старых документов. Сколько у вас есть старых файлов Microsoft Office? Сколько новых применений вы нашли бы содержащейся в них информации, если бы она была представлена в открытом и документированном XML-формате, и вы могли бы использовать для работы с этой информацией любые XML-инструменты? Учитывая, что всё это теперь возможно с использованием открытого программного обеспечения, работающего и в Windows, и в Linux, перед нами должны открываться огромные новые возможности.

<{{./BAN/ARTIC6}}>