GrabDuck

Взаимная конвертация и обработка электронных документов

:

LibreOfficeВ корпоративном секторе иногда возникает задача автоматической конвертации документов из одного формата в другой, а так же задача их програмной обработки и модификации. Казалось бы, в чём проблема: для нормальных форматов давным-давно написаны полнофункциональные библиотеки для работы — так что Perl или Python в руки и вперёд.

Но, к превеликому сожалению для всех системных администраторов и программистов различных бизнес-приложений, огромная масса документооборота в данный момент всё ещё осуществляется с использованием закрытых и плохо поддающихся модификации и разбору форматов. Что уж тут лукавить — речь идёт о doc, xls и иже с ними, а так же во многом о docx, xlsx и подобных. Что делать с такими файлами, особенно если у вас нету свободной Windows с установленной последней версией Office, — совершенно непонятно. Безусловно, если у вас есть Windows, Visual Studio и навыки работы в C#, то проблем с анализом документов Microsoft будет значительно меньше. Зато возникнут проблемы с ODF. Плюс часто хочется сохранять результат в формате PDF, дабы уже никто не мог его изменить.

К счастью, есть достаточно универсальный способ работы практически с любыми распространёнными форматами документов на любой платформе. О нём и пойдёт речь дальше.

Без сомнения все знают про OpenOffice и его прогрессивное ответвление — LibreOffice. Последние версии этих пакетов отлично справляются с документами Microsoft — по крайней мере гораздо лучше многих бесплатных библиотек парсинга.

Но не многие знают, что у OpenOffice и конечно же у LibreOffice есть API, позволяющий работать с документами напрямую из Python. В частности, с помощью этого API можно преспокойно конвертировать документы из одного формата в другой.

Таким образом для разбора любого документа достаточно преобразовать его в соответствующий формат ODF, затем с помощью любимого языка программирования выполнить все необходимые изменения, а затем, при необходимости, сконвертировать результат в PDF или формат MS Office 2003 (doc, xls).

Другой сценарий: у вас есть куча документов в редактируемых форматах (doc, docx, odt), а вам надо сделать из них PDF. Всё тот же скрипт позволит вам без проблем автоматически выполнить такое преобразование. Или же вы для внутреннего документооборота используете стандартизированный ODF, но ваши партнёры до сих пор даже до docx не доросли. Ничего страшного — LibreOffice поможет автоматически сконвертировать ODF в формат MS Office.

Вообще сценариев применения API LibreOffice превеликое множество — так что круг возможных задач для решения очень широк.

Что потребуется


В статье описывается использование LibreOffice на Ubuntu, хотя с небольшой модификацией все инструкции переносятся как на другие дистрибутивы Linux и OpenOffice, так и на Windows и MacOS.

Всё, что нужно — это установленные LibreOffice и Python, а так же базовое умение писать скрипты.

Собственно сам bash скрипт конвертации выглядит так:

#!/bin/bash

# Скрипт конвертации различных форматов офисных документов
# с помощью LibreOffice.
#
# Использование: libre-converter.sh infile outfile

LIBREOFFICE=`which libreoffice`
PYTHON=`which python`
DIR=`dirname "$0"`

if [ ! -e "$1" ]
then
 echo "Could not find source file $1"
 exit
fi

if [ ! -x "$LIBREOFFICE" ]
then
 echo "Could not find LibreOffice binary"
 exit
fi

if [ ! -x "$PYTHON" ]
then
 echo "Could not find Python"
 exit
fi

# Закрываем все запущенные копии LibreOffice
killall -u `whoami` -q soffice

# Нам нужен дополнительный скрипт-обёртка для работы с LibreOffice API
test -f $DIR/DocumentConverter.py || wget http://www.artofsolving.com/files/DocumentConverter.py

# Запускаем LibreOffice в режиме прослушки 8100 порта TCP
$LIBREOFFICE "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -norestore -nofirststartwizard -nologo -headless  &

# Немного ждём, чтобы убедиться, что LibreOffice точно запустился
sleep 5s

# Конвертируем...
echo -n "   Converting $1 to $2... "
$PYTHON $DIR/DocumentConverter.py "$1" "$2"
echo "Done!"

# Закрываем LibreOffice
killall -u `whoami` soffice

Этот скрипт можно вызывать из другого скрипта-обёртки для пакетной обработки большого количества файлов.

Например, мне нужно было добавить к большому количеству doc документов титульные листы одинакового формата и сохранить результат в формате PDF. Для добавления титульных листов я использовал скрипт на Perl и библиотеку OpenOffice::OODoc (доступную в Ubuntu как пакет libopenoffice-oodoc-perl). В итоге получился такой скрипт пакетной обработки:

#!/bin/bash

DIR=`dirname "$0"`
TOOLS="$DIR/tools"

INFILE="$1"
FILENAME=`echo "$1" | sed 's/\.[^.]*$//'`
SHORTNAME=`basename "$FILENAME"`
OUTPATH=`dirname "$FILENAME"`

if [ ! -e "$INFILE" ]
then
 echo "Could not find source file $INFILE"
 exit
fi

echo ""
echo "### Converting $INFILE ###"

# Преобразуем DOC в ODT:
echo "1. Converting DOC to ODT:"
$TOOLS/libre-converter.sh "$INFILE" "$FILENAME.odt"
if [ $? -ne 0 ];
then
	echo "ERROR!"
	echo "Ошибка преобразования $INFILE с помощью LibreOffice!"
	rm "$FILENAME.odt"
	exit
fi

# Добавляем титульный лист
echo -n "2. Add first page to ODT... "
$TOOLS/add-1st-page.pl "$FILENAME.odt"
if [ $? -ne 0 ];
then
	echo "ERROR!"
	echo "Ошибка добавления титульного листа в файл $INFILE!"
	rm "$FILENAME.odt"
	exit
fi
echo "Done!";

# Преобразуем ODT в PDF
echo "3. Converting ODT to PDF:"
$TOOLS/libre-converter.sh "$FILENAME.odt" "$OUTPATH/$SHORTNAME.pdf"
if [ $? -ne 0 ];
then
	echo "ERROR!"
	echo "Ошибка преобразования $FILENAME.odst с помощью LibreOffice!"
	rm "$FILENAME.odt"
	exit
fi

# Удаляем временные файлы
echo -n "4. Do some cleaning... "
rm "$FILENAME.odt"

echo "All done! :)"

Теперь достаточно выполнить
find /my/doc/path -type f -iname "*.doc" -exec ./convert.sh {} \;

и на выходе получим набор PDF файлов с красивыми титульными листами.

Другие возможности


С помощью описанной техники можно не только конвертировать различные форматы документов между собой, но и выполнять экспорт в файлы изображений, как то JPEG или PNG. Для этого потребуется поставить ImageMagic, затем с помощью описанного скрипта сконвертировать документ в PDF, а с помощью ImageMagic сконвертировать PDF в нужный формат изображений:
convert sample.pdf sample.png
convert sample.pdf sample.jpg
convert sample.pdf sample.tif

Чуть больше информации об автоматической конвертации документов с использованием LibreOffice или OpenOffice можно найти тут:

http://www.oooninja.com/2008/02/batch-command-line-file-conversion-with.html

Упоминаемый выше Python API для LibreOffice (который, к слову, называется PyUNO), можно использовать для прямого редактирования документов из Python, хотя зачастую это не очень удобно. Подробнее можно почитать в этом хабратопике.

UPD: Как подсказали в комментариях: добрые люди упростили конвертацию документов с помощью OpenOffice (LibreOffice), написав скрипт-обёртку unoconv. Эта утилитка делает ровно то же и ровно таким же способом, что и описаные выше скрипты. Но она безусловно будет удобней в большинстве случаев, если нормально запустится на вашей системе.