image

Год назад ко мне в очередной раз обратился постоянный заказчик. «Менеджеры — идиоты, — негодовал он. — Текучка кадров огромная, на обучение каждого уходят месяцы. А потом они делают ошибки».

Лишь после такой эмоциональной прелюдии последовало задание: «Необходимо, чтоб при заказе с сайта на почту приходил уже сформированный пакет документов в форматах MS Office: бланк заказа, счет к оплате, товарный чек, и спецификация».

Задача сама по себе близка к статье «PHP + Word». Но сервис LiveDocx нам не подошел. Во-первых, предполагалось, что большая часть документов должна быть в Excel. Во-вторых, оплата «на Запад» из России была и есть проблематичной. В-третьих, у заказчика была масса идей и хотелок, которые этот, или подобный сервис вряд ли реализовал бы. Например, сложную таблицу, с разбивкой товаров на категории.

Так как сайтов у заказчика несколько, решено было строить отдельную систему — свой собственный сервис генерации документов, к которому сайты обращались бы в момент заказа.

В основу будущего кода легли идеи из той же, приведенной выше, хабростатьи, а так же публикация «Разбираем xlsx в PHP без готовых библиотек».

В итоге за месяц работы «генератор документов» был создан и запущен.

Что он умеет:

  • генерировать по шаблону документ docx путем прямой замены шаблонного тега на данные;
  • то же самое делать с шаблонами в формате xlsx;
  • расширять таблицы в xlsx и заполнять их входящими данными из массива;
  • вставлять подзаголовки, разбивая таблицу на группы;
  • вставлять ссылки — единичные, или как содержимое таблицы;


Что генератор на данный момент не умеет:

  • работать с разными типами данных — все ячейки заполняются как строки. По этой причине невозможно использование формул excel в шаблоне, которые оперировали бы введенными данными;
  • вставлять изображения;
  • менять форматирование — оно полностью определяется в шаблоне.

В таком виде он проработал вот уже скоро год. Проблемы за этот период возникали в основном только с клиентской частью — со стороны магазина. Хотя, это не значит, что скрипт «генератора» идеален. На сегодняшний день он обкатан только в одной реальной задаче.

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

Сегодня я получила разрешение от заказчика выложить проект на Гитхабе и опубликовать эту статью, чем спешу воспользоваться.

Проверить работу скрипта можно на демо-примере.

Исходный код доступен в репозитории.

Комментарии (20)


  1. PQR
    01.04.2015 13:47
    +4

    Полезная наработка!

    Сможете отделить библиотеку генерации документа от сайта (index.php) и завернуть её в composer пакет?


    1. floppox Автор
      03.04.2015 13:14

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


  1. BoxaShu
    01.04.2015 15:51
    +1

    Так же писал в свое время подобный генератор отчетов в xlsx и так же оформление и прочее были зашиты в шаблон, но потом узнал про xslt и все встало на свои места. Теперь, код отдельно, оформление отдельно и в любой момент можно поправить шаблон. Чего и Вам желаю.


    1. gaelpa
      01.04.2015 19:39
      +1

      Зависит от задачи. В моем случае, например, трудно заставить клиентов осваивать xslt или платить за постоянную корректировку шаблонов по их хотелкам.


  1. great_boba
    01.04.2015 18:02
    +2

    Давно, когда надо было написать подобную вещь…
    Я формировал документ в формате xml с тегами и заголовками (как их сохранял Excel), а потом при скачивании кидал в header соответствующий content-type (application/vnd.ms-excel) и все.
    Это позволяло не мучиться с внутренней структурой xlsx файла


  1. yurash
    02.04.2015 09:17

    нисколько не критикую, просто интересуюсь — а Google Spreadsheet/Document не рассматривались в качестве альтернативы? Хоть многие excel фичи там отсутствуют, но благодаря google apps script есть очень широкие возможности автоматизации. Генерацию по шаблону там можно сделать за считанные часы (с нуля, достаточно знать javascript). Если конечно, речь не идёт о сотнях документов в день (т.к. есть квоты и ограничения)


    1. floppox Автор
      03.04.2015 13:18

      Был реальный заказчик. Ему нужна была реализация именно в том виде, как есть. Гуглдокс как раз в первую очередь был предложен, но у фирмы уже был налаженный документооборот, и требовалось вписаться в существующую систему.


  1. t1gor
    11.04.2015 19:24

    А почему вы не использовали phoExcel какой-нибудь?


  1. floppox Автор
    12.04.2015 11:30

    Среди разных вариантов ответа, рискну остановиться на следующем: чтоб получить инвайт на хабр. Можно так?
    На самом деле, конечно, мысли об этом 13 месяцев назад не было, были другие, которые уже сложно вспомнить так, чтоб не соврать.


  1. AlexGx
    14.04.2015 17:31

    А в генераторе docx можно вставлять новые строки в таблицы?


    1. floppox Автор
      14.04.2015 18:52

      На данный момент нет.


    1. Alexufo
      14.04.2015 20:08

      это делается очень просто. Там практически html


  1. Alexufo
    14.04.2015 20:30

    как реализована подстановка переменных в документе? как обрамлять переменные?


    1. floppox Автор
      15.04.2015 11:48

      Как обрамлять переменные.

      На счет реализации, я не уверенна, что поняла ваш вопрос на 100% правильно. Каждый вид переменных обрабатывается разным способом. Одиночные — прямой заменой всех вхождений на значение, табличные — создаются новые ячейки, по количеству входящих элементов, и уже в них производится замена на значения из массива.


      1. Alexufo
        19.04.2015 00:07

        переменные имею ввиду типа %firm_name% вставленные в шаблон docx, которые потом заменяются на значения. Причем вставленны именно в ворде не в xml. Как у вас это работает?


        1. floppox Автор
          19.04.2015 20:28

          Простой заменой


          1. Alexufo
            20.04.2015 22:41

            но в xml переменные могут не храниться в строчку. Если вы ошибетесь в написани переменной и исправите ошибку, она будет разбита тегом history и обычной заменой в xml уже не прокатит.


            1. floppox Автор
              21.04.2015 07:00

              Эта проблема решается с помощью регулярных выражений.
              github.com/floppox/f-document/blob/master/generator/docx_processor.class.php
              Функция search_filds()


              1. Alexufo
                21.04.2015 08:45

                В моём случае я решал это покороче, сначала грохал все теги между требуемыми ключевыми символами регуляркой, а после — обычной заменой.


                1. floppox Автор
                  21.04.2015 10:57

                  Перестановка мест слагаемых. Хотя, возможно, имеет смысл для оптимизации, но это не очевидно — нужны экперименты. Ну а мой выбор обоснован тем, что такой подход показался более контролируемым, чем «грохать все регуляркой».