Сохранение документов Excel в PDF на сервере

Не так давно появилась задача создать простой сервис по созданию PDF отчетов на основе офисных документов для интранета. И вроде бы все просто, но вот с сохранением Excel в PDF возникли проблемы. Интересно? Прошу под кат.


Как я и сказал, поначалу все казалось легко, у меня были собственные наработки, на хабре была статья. Но обо всем по порядку.

Мои наработки использовали сom объекты excel.application и метод saveAs, это прекрасно работало, пока требовалось взять обычный, красивый документ и сделать из него pdf, но в данном случае файлы были нет так просты.

Во-первых, документы предполагаются трех форматов — xls, xlsx и xml. Во вторых все документы содержат макросы, а некоторые ссылки на другие документы. В третьих они содержат кучу листов, и перекрестные ссылки между листами. Не нужные для отчета листы делаются скрытыми, а на самих листах в каше вспомогательных цифр отчетная информация выделялась областью печати. Нужно ли говорить, что saveAs игнорирует все это богатство и на выходе после танца с бубнами получаем абсолютно не читаемую картину.

Здесь я думаю необходимо сделать лирическое отступление и пояснить, почему с файлами творится такая неразбериха. Я работаю в очень крупной организации, бок обок с кучей бабушке пенсионного возраста. Они не могут даже сделать текст в ячейке жирным, но прекрасно могут говорить начальству о том, что они не «программисты» и не должны это уметь. Начальства у нас тоже много, и в силу жалости к бабушкам или своей компьютерной безграмотности, а быть может, по велению звезд жалобы бабушек поощряются, и все попытки разгрести бардак в документах пресекается.

Вернемся к нашим баранам. В выше упомянутой статье был предложен вариант конвертации «Как вижу» с использованием open office, этот вариант меня не устроил в силу ветреного отношения OO к MS. Некоторые документы действительно открывались в нем корректно, но чаще всего содержимое ехало еще до конвертации.

Был еще третий вариант. Печатать документы на виртуальный принтер, но я решил, что этот вариант я приберегу на самый крайний случай, так это костыль.

И тогда я обратился к гуглу и он дал мне эту замечательную ссылку. Описанный в ней метод ExportAsFixedFormat был тем, что нужно! Но меня опять постигла не удача.

Он начисто игнорировал области печати, а без них получалась каша. Я гуглил, оставлял вопросы на множестве форумах, в том числе и на англоязычных. Ответа не было. Я даже перенес код статьи в C#, но результат не изменился.

После недели изысканий, я решил плюнуть на все и использовать тот самый крайний вариант с виртуальным принтером, но каково же было мое изумление, когда и он проигнорировал область печати, притом, что если отправить документ из самого Excel все было нормально.

Путем проб и ошибок, танцев с бубнами и увлекательным чтением гугла я выяснил, области печати игнорируется при вызове этого метода и печати в php, C#, но почему то при использовании VBScript все работает как надо. Чем это вызвано я, к сожалению, так и не выяснил.

И так, было решено из PHP открывать VBS скрип и уже из него преобразовывать excel в pdf. Да, это тоже костыль, но не такой неуклюжий как виртуальный принтер.

Вот получившийся скрипт:

Dim XL
Dim XLWkbk
Dim ObjArgs
Dim paramSourceBookPath
Dim paramExportFilePath

set objargs = wscript.arguments
if objArgs.count <= 1 then
wscript.echo «invalid passed arguments»
wscript.quit
end if

Set XL = CreateObject(«excel.application»)
XL.Visible = false

paramSourceBookPath=objargs(0)
paramExportFilePath=objargs(1)

Set XLWkbk = XL.Workbooks.Open(paramSourceBookPath,False)

XLWkbk.ExportAsFixedFormat 0,paramExportFilePath,1,false,false

XLWkbk.Close False
XL.Quit

Set XLWkbk = Nothing
Set XL = Nothing
set ObjArgs = nothing


Он довольно прост, принимает на входе два аргумента, первый путь к файлу, Excel второй путь и имя создаваемой PDF.

Вызывается из любого ЯП, например PHP:
exec(APPLICATION_SCRIPT_FOLDER.'\\excel.vbs C:\\tmp\\test.xlsx C:\\tmp\\test.pdf");


В сухом остатке мы имеем не совсем красивый, но 100% рабочий метод по преобразованию Excel в PDF, который гарантирует результат «Как на печати» без подводных камней.

P.S.: Хабр, то место где из комментариев к статье ты узнаешь больше чем из статьи, так что буду рад если мне укажут более простой путь.

P.P.S.: Ошибки при письме мой крест, я проверил данный текст спелчекером огнелиса и ворда, но сомневаюсь, что помогло. Не ругайте сильно, лучше пишите в личку, все поправлю.

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 6

    0
    тоже костыль, но не такой неуклюжий как виртуальный принтер

    На сервере ставим виртуальный pdf-принтер, расшариваем, подключаем на клиентах. Профит! Кроссплатформенно, масштабируемо, не зависит от коммерческого софта, при печати можно изменить множество параметров. В чем неуклюжесть? Пользователю нужно левое поле 2.5см для определенного документа, что он будет делать?

    * VBS и VBScript — разные вещи
      0
      Про скрипты спасибо, учту.

      А про принтер. Вы думаете я шутил когда написал, что они реально не знают как сделать текст жирным? Скорее меня уволят, чем пользователи начнут выбирать виртуальный принтер для печати документов. Так можно было бы и в pdf их самих сохранять заставить, excel это умеет.

      Плюс на сервере есть определенная иерархия папок по которым сортируются документы, в том числе и по дате отчетных суток, который может не совпадать с текущей датой, такой параметр можно передать на принтер?

        0
        Оооо, microsoft interop как всегда прекрасен! Чем больше в нем копаешься, тем больше становится страшно.
        Автоматизация офисных документов всегда приводит к очень сильной ненависти к MS.
          0
          На самом деле все вроде логично, но вот не работающий параметр без каких либо указании на то, почем он не работает, действительно напрягает.
            0
            Ну Вы видимо пока не работали с внутренними объектами :) В них то и кроется настоящий ужас.
              0
              Тогда надеюсь мне не придется.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое