Если вы собираетесь преобразовывать ваши файлы в новый формат по одному, то вам придётся открыть и заполнить несколько диалоговых окон для каждого файла. Если вам требуется преобразовать несколько сотен файлов, то такой подход окажется затруднительным. Что же делать, если у вас есть большая куча документов 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, перед нами должны открываться огромные новые возможности.