Как стать автором
Обновить

PHP + Word

Время на прочтение 4 мин
Количество просмотров 87K
image

Что делать, если нужно создавать много Word файлов одинакового вида, но разного содержания? Например заполнять бланки, квитанции.

Есть 3 варианта:
1) использовать одну из библиотек для работы с Word документами
2) сохранить документ в формате docx, открыть архиватором и внутри мы увидим "\word\document.xml" — чистый xml, с которым можно работать через str_replace (спасибо Enuriru за подсказку)
3) использовать сторонний сервис, который сделает за меня большую часть работы

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

Второй варинт хорош и прост, когда мы работаем с word документами в формате .docx, но к сожалению он не поддерживает формат .doc

В процессе проработки третьего варианта, наткнулся на интересное решение LiveDocx

Преимущества:
— файл шаблона можно создать привычным способом через Word
— представление документа в форматах doc, docx, rtf, pdf
— не нужно заморачиваться с представлением Word документа через html или XML
— простота подключения
— надежность — сервис существует давно и под него даже есть готовая библиотека от Zend
Недостатки:
— в бесплатной версии ограничение на 250 генерируемых документов в сутки
— шаблон нельзя менять (например нельзя сгенерировать таблицу с кол-вом строк, равным количеству элементов в базе)



Вот так выглядел присланный заказчиком файл.



Приступим.

1) Для начала нужно разметить шаблон. Открываем файл и размечаем нужные поля специальными вордовскими переменными mergeField, вот как это делается в Word 2007:
— Вставка => Экспресс блоки => Поле
Появляется окно.

Выбираем тип поля: MergeField => В имени поле пишем имя переменной => Жмем ОК

Таким образом размечаем весь документ, получится нечто похожее на:



Сохраняем документ, кладём в директорию нашего приложения.

2) Поработаем с кодом

Регистрируемся на сайте LiveDocx, получаем логин и пароль.

Если вы счастливый/несчастливый обладатель Zend Framework, то всё довольно просто, поддержка LiveDocx идёт прямо из коробки:

    // Создаём объект для работы с сервисом и передаём свой логин и пароль   
    $livDoc = new Zend_Service_LiveDocx_MailMerge(array(
        'username' => 'yourusername',
        'password' => 'yourpassword'
   ));

    // Передаём значения для наших mergeFields в Word шаблоне
    $livDoc->assign('orderNum','Номер заказа');
    $livDoc->assign('orderDay',date('d', 'Дата заказа'));

    // Задаём путь к файлу шаблона и передаём его объекту
    $documentPath = 'contract_bid_for_customer.doc';
    $livDoc->setLocalTemplate($documentPath);

    // заполняем документ с помощью сервиса 
    $livDoc->createDocument();
    $doc = $livDoc->retrieveDocument('doc');

    // отдаём готовый документ для скачки 
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    $fileName = "Документ.doc";
    header("Content-Disposition: attachment; filename=$fileName");
    header("Content-Type: application/msword");
    header("Content-Transfer-Encoding: binary");
    echo $doc;
    die;


Если же вы предпочитаете plain php, то голодными тоже не останетесь.

Для работы понадобится включенный модуль soap, в большинстве случаев он включен по умолчанию, но проверьте как обстоит дело у вас:
phpinfo();
Раздел SOAP
Вы должны увидеть Soap client enabled и Soap server enabled.

    // Выключаем WSDL кэширование
    ini_set ('soap.wsdl_cache_enabled', 0);

    // Выставляем временную зону
    date_default_timezone_set('Europe/Moscow');

    // Создаём экземпляр объекта Soap и передаём ему свои учетные данные
    $soap = new SoapClient('https://api.livedocx.com/1.2/mailmerge.asmx?WSDL');
    $soap->LogIn(
        array(
            'username' => 'yourusername',
            'password' => 'yourpassword'
        )
    );

    // Путь к файлу шаблона
    $data = file_get_contents('contract_bid_for_customer.doc');

    // Установка расширения файла .doc и параметров кодирования
    $soap->SetLocalTemplate(
        array(
            'template' => base64_encode($data),
            'format'   => 'doc'
        )
    );

    // Задаём значения переменным
    $fieldValues = array (
        'orderNum'  => 'Номер заказа',
        'orderDay'  => 'Дата заказа'
    );

    // Эта хитрая функция преобразует массив c переменными в то что понимает SOAP
    function assocArrayToArrayOfArrayOfString ($assoc)
    {
        $arrayKeys   = array_keys($assoc);
        $arrayValues = array_values($assoc);
        return array ($arrayKeys, $arrayValues);
    }

    // Передаём переменные в наш LiveDocx объект
     $soap->SetFieldValues(
        array (
            'fieldValues' => assocArrayToArrayOfArrayOfString($fieldValues)
        )
    );

    // Формируем документ
    $soap->CreateDocument();
    $result = $soap->RetrieveDocument(
        array(
            'format' => 'doc'
        )
    );
    $doc = base64_decode($result->RetrieveDocumentResult);
    
    // Разрываем сессию с SOAP 
    $soap->LogOut();

    // Отдаём вордовский файл  
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    $fileName = "Документ.doc";
    header("Content-Disposition: attachment; filename=$fileName");
    header("Content-Type: application/msword");
    header("Content-Transfer-Encoding: binary");
    echo $doc;
    die;


3) На выходе мы имеем вот такой файл



LiveDocx поддерживает и другие форматы: DOCX, RTF and PDF.

Подробнее вы можете почитать здесь:
livedocx.com
phplivedocx.org/articles/getting-started-with-phplivedocx
blog.zendguru.com/2010/02/13/creating-word-processing-document-using-zend_service_livedocx
Теги:
Хабы:
+69
Комментарии 59
Комментарии Комментарии 59

Публикации

Истории

Работа

PHP программист
175 вакансий

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн