Откуда пошла дурацкая привычка сохранять счета, бухгалтерские и финансовые документы в формате MS Excel? Зачем хранить и передавать документы, предназначенные для печати в формате электронной таблицы, если есть специальный формат PDF? Однако, во всех бухгалтерских программах документы в первую очередь обязательно экспортируются в MS Excel и уже потом предлагаются альтернативные способы сохранения документов. От сюда и возникла задача: пусть бухгалтер сохраняет свои документы как хочет, но клиент должен получить их в формате PDF и обязательно точно в том образе, который бухгалтер сваял в шаблоне MS Excel.
В качестве бухгалтерской программы мы использовали бесплатную ВС: Бухгалтерию. (По правде сказать из этой программы можно сразу сохранять документы в PDF, но раз сказали excel, значит – excel.)
Бухгалтер выгружает XLS-файл в определенный каталог на диске, откуда мы должны его забрать, перевести в PDF и сохранить в другой каталог. Все это должно быть реализовано в виде веб-сервиса, то есть клиент должен увидеть и иметь возможность скачать свои pdf-документы в «Личном кабинете» на сайте.
Пути решения:
Первое, что захотелось сделать, – это отыскать готовую библиотеку для PHP или Perl и прямо «на лету» конвертировать файлы.
Такие библиотеки для работы с форматом Excel действительно нашлись, например: PHPExcel, PHPExcelReader, Spreadsheet::ParseExcel и др.
Эти библиотеки действительно хорошо работают, но делают именно то, для чего предназначены: выискивают данные в электронной таблице Excel и оперируют с ними.
Нам же нужно совсем иное – получить экселевскую таблицу в виде как для печати, со всеми картинками с печатями и подписями, с форматами шрифтов, и ячеек.
Второй вариант решения — виртуальный принтер. Суть его в том, что мы открываем файл в подходящей программе и отправляем его на печать, но не на настоящий принтер, а – на виртуальный, который вместо бумаги сохранит в файл, сначала в постскрипт формате ps, а потом сделает из него файл PDF.
Поскольку система ко всему еще и должна функционировать как веб-сервис, я выбрал в качестве платформы Linux с Apache. А в качестве программы, которая умеет открывать все файлы MS Office – бесплатный OpenOffice.org 3.4
Итак, что делаем:
Устанавливаем OpenOffice. В руководстве по по установке конвертера PyODConverter предлагают устанавливать версию OpenOffice.org 2.4 обязательно -headless, но я просто установил OpenOffice.org 3.4 из репозитория и все получилось.
После установки я попробовал запустить программу, но система отказалась, захотев еще Java Runtime Environment. А нужен ли он? Оказалось, что нет. И запускать OpenOffice целиком, чтобы отправить файл на виртуальный принтер вовсе ни к чему. У программы есть прекрасный конвертер в pdf, который легко вызвать из командной строки.
Делается это так:
Создаем конвертер в PDF
Создаем bash-файл, например с именем converter.sh
<code> <source lang="bash"> #!/bin/bash # Проверяем где установлен OpenOffice.org и PYTHON. #Поправьте пути вручную, если они отличаются на вашей системе OOFFICE=`ls /usr/bin/openoffice.org3 /usr/bin/ooffice /usr/lib/openoffice/program/soffice | head -n 1` OOOPYTHON=`ls /opt/openoffice.org*/program/python /usr/bin/python | head -n 1` if [ ! -x "$OOFFICE" ] then echo "Could not auto-detect OpenOffice.org binary" exit fi if [ ! -x "$OOOPYTHON" ] then echo "Could not auto-detect OpenOffice.org Python" exit fi echo "Detected OpenOffice.org binary: $OOFFICE" echo "Detected OpenOffice.org python: $OOOPYTHON" # Reference: http://wiki.services.openoffice.org/wiki/Using_Python_on_Linux # If you use the OpenOffice.org that comes with Fedora or Ubuntu, uncomment the following line: # export PYTHONPATH="/usr/lib/openoffice.org/program" # If you want to simulate for testing that there is no X server, uncomment the next line. #unset DISPLAY # Kill any running OpenOffice.org processes. killall -u `whoami` -q soffice # Это важная строчка: программа пытается скачать из сети скрипт на языке Python, который как раз #нужен OpenOffice для конвертации файлов. Если все хорошо, то после запуска converter.sh в #каталоге появится файл с именем DocumentConverter.py. #Если не получилось — скачайте файл DocumentConverter.py #вручную по адресу ниже и поместите в один каталог с этим скриптом. #Проверьте чтобы порт в скрипте был указан 8100 test -f DocumentConverter.py || wget http://www.artofsolving.com/files/DocumentConverter.py # Start OpenOffice.org in listening mode on TCP port 8100. $OOFFICE "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -norestore -nofirststartwizard -nologo -headless & # Wait a few seconds to be sure it has started. sleep 5s # Здесь мы перечисляем имена файлов, которые хотим конвертировать: #Имя исходного файла — в какой файл конвертируем. # Самое приятно, что конвертировать можно не только в PDF, но и в любой формат, #поддерживаемый OpenOffice.org # # Из MS PowerPoint во Flash $OOOPYTHON DocumentConverter.py sample.ppt sample.swf #Из Excel в PDF $OOOPYTHON DocumentConverter.py sample.xls sample.pdf # Close OpenOffice.org. killall -u `whoami` soffice #---------------------------------------------------- </source> </code>
Выставьте права для запуска скрипта converter.sh (755)
Поместите в один каталог с этим скриптом (converter.sh) Excel-файл под именем sample.xls, запустите скрипт converter.sh и в каталоге появится файл sample.pdf, который будет копией печатного вида экселевского файла.
Пол-дела сделано. Теперь нам нужно организовать процесс конвертации в виде веб-сервиса.
Можно, конечно, поместить файл converter.sh в каталог /cgi-bin/ Apache и запускать сразу его, но тут уже начинаются задачи обеспечения безопасности. К вопросу безопасности такого сервиса нужно подойти очень тщательно, ведь мы собираемся передавать скрипту неизвестные файлы и разрешать ему сохранять неизвестно что на диске.
Правильный подход – это разместить файл converter.sh выше DOCUMENT_ROOT Apache, а обращаться к нему через скрипт-посредник, например, на perl, который будет лежать в каталоге /cgi-bin/ и тщательно проверять все параметры, передаваемые в converter.sh.
Какие обнаружились проблемы, после реализации сервиса конвертации.
Оказалось, что Linux не понимает файлы с именами русскими буквами в кодировке windows-1251. Что тут можно сделать:
1. Уговорить бухгалтера сохранять файлы с латинскими именами (сложно)
2. Конвертировать имя файла в utf-8 при загрузке в каталог (вполне реально)
3. Реализовать аналогичный сервис под Windows – Apache (попробую)
Под Windows конвертер реализовать тоже оказалось несложно
Я сделал так:
1. Скачал и установил LibreOffice 3.4
2. Скачал PyODConverter
3. Сохранил файл DocumentConverter.py в рабочем каталоге, например, C:test
4. Поменял в файле DocumentConverter.py константу DEFAULT_OPENOFFICE_PORT = 8100 (по умолчанию там был указан другой порт)
5. Поместил в каталог C:test пробный файл для конвертации – test.xls
Теперь запускаем процесс конвертации.
Сначала запускаем OpenOffice в скрытом режиме. В командной строке (cmd) пишем:
"C:Program FilesLibreOffice.org 3.4programsoffice.exe" -headless -nologo -norestore -accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager
Здесь важно, чтобы порт совпадал с DEFAULT_OPENOFFICE_PORT
Теперь запускаем конвертацию:
"C:Program FilesLibreOffice.org 3.4programpython" c:testDocumentConverter.py c:testtest.xls c:testtest.pdf
И в каталоге c:test обнаруживаем конвертированный файл PDF.
Вот и готов конвертер файлов xls, doc, docx, rtf, txt, odt, ott, sxw, stw, html, xml, в общем всего, что откроет OpenOffice.
Автор: EvJik