Php заполнение word документа

Создание word документа с помощью библиотеки phpWord

В данной статье хочу показать небольшой пример работы с библиотекой PHPWord. Логика работы примерно следующая: есть элемент инфоблока с некоторыми полями, в том числе, привязка к пользователю, где хранятся все его данные. При создании или обновлении элемента на лету создается word документ, в котором указывается фио сотрудника или возможно какие-то другие данные. Этот документ сохраняется в базу и присваивается этому же элементу как значение свойства типа «файл». После чего этот файл можно скачать.

Для подключения данной библиотеки, нам понадобиться composer. Для Bitrix composer подключается довольно просто. В папке /bitrix, есть файл «composer-bx.json». Переименовываем его в composer.json и в консоле,перейдя в эту папку, запускаем установщик composer`а

После чего в данном разделе появляется папка «vendor», куда и будут установлены необходимые библиотеки. Добавим зависимость «»phpoffice/phpword»: «v0.16.«» и установим все пакеты. Актуальную версию смотрите на официальном сайте или github разработчиков. Для подключения автозагрузки классов* в init.php пропишем следующую конструкцию:

if($_SERVER["DOCUMENT_ROOT"].'/bitrix/vendor/autoload.php') < include_once ($_SERVER["DOCUMENT_ROOT"].'/bitrix/vendor/autoload.php'); >

Также, если нужно, можем использовать автозагрузчик от Bitrix, в котором можем использовать свои собственные классы.

CModule::AddAutoloadClasses( «», // не указываем имя модуля array( // ключ - имя класса, значение - путь относительно корня сайта к файлу с классом 'MyHelper' => '/local/php_interface/MyHelper/helpers.php', ) ); AddEventHandler("iblock", "OnAfterIBlockElementAdd", 'MyHelper::DocCreator'); 

В данном примере мы подключили класс MyHelper и повешали событие, которое после добавления элемента инфоблока вызовит статический метод DocCreator этого класса.

В файле /local/php_interface/MyHelper/helpers.php

В публичном статическом методе проверяем, что обновляется элемент из нужного инфоблока и данные не пустые. Далее вызываем обычный метод для формирования самого .doc документа.

public function CreateAfterDoc($incomArray) < $phpWord = new \PhpOffice\PhpWord\PhpWord(); // создаем экземпляр класса // параметры которые будут указаны при создании документа $phpWord->setDefaultFontName("Times New Roman"); // устанавливаем шрифт $phpWord->setDefaultFontSize(12); // устанавливаем шрифт $phpWord->getSettings()->setThemeFontLang(new \PhpOffice\PhpWord\Style\Language(\PhpOffice\PhpWord\Style\Language::EN_GB)); // устанавливаем язык документа $phpWord->getSettings()->setHideSpellingErrors(true); // параметры документа $properties = $phpWord->getDocInfo(); $properties->setCreator(''); $properties->setCompany('MyCompany '); $properties->setTitle('My title'); $properties->setDescription('My description'); $properties->setCategory('My category'); $properties->setLastModifiedBy('My name'); $properties->setCreated(mktime(0, 0, 0, 3, 12, 2020)); $properties->setModified(mktime(0, 0, 0, 3, 14, 2020)); $properties->setSubject('My subject'); $properties->setKeywords('my, key, word'); $sectionStyle = []; // стили для раздела $section = $phpWord->addSection($sectionStyle); // добавление раздела с добавлением стилей > 

Мы создали документ и задали какие-то начальные параметры. Но для того, что бы начать что-то рисовать, нужно создать отдельную секцию и передать массив со стилями (цвета, шрифт, отступы, и.т.д.).

Читайте также:  Img from folder html

Добавление текста происходит примерно так:

$text = 'Отчет о выполнении плана работ'; $section->addText(htmlspecialchars($text), ['bold'=>true, 'size' => 14], ["alignment" => 'center']); 

Добавление таблиц, так:

// стили для таблиц $table_styles_1 = [ 'borderColor' => '000000', 'borderSize' => 1, 'cellMargin' => 0, 'cellSpacing ' => 0 ]; $table_styles_2 = [ 'borderColor' => '000000', 'borderTopSize' => 1, 'cellMargin' => 0, 'cellSpacing ' => 0 ]; $cellStyleTopBorder = [ 'borderTopColor' => "000000", 'borderBottomColor' => "ffffff", 'borderRightColor' => "ffffff", 'borderLeftColor' => "ffffff", 'borderSize' => 1, 'cellMargin' => 0, 'cellSpacing ' => 0 ]; // добавляем стили для таблицы. Задаем идентификатор настроек со стилями, сами стили и стили для первой строки. Параметры идут по порядку. $firstRowStyle = array('bgColor' => '66BBFF'); // стиль для первой строки $phpWord->addTableStyle('first_table', $table_styles_1, []); $phpWord->addTableStyle('second_table', $table_styles_2, []); Тут мы создали два стиля с идентификаторами ‘first_table’ и ‘'second_table’ Далее задаем параметры для строк и ячеек: $cellColSpan = array('gridSpan' => 2, 'valign' => 'center'); $cellHCentered = array('alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER); $cellVCentered = array('valign' => 'center'); И наконец, в нашей секции обрисовываем таблицу и передаем в конструктор идентификатор стилей. $table = $section->addTable("first_table"); 

Переменная $table имеет доступ к методам для создания строк и ячеек таблиц. Укажем все стили и параметры которые мы задали для них.

$table->addRow([\PhpOffice\PhpWord\Shared\Converter::pixelToTwip(1200)]); $cell2 = $table->addCell(\PhpOffice\PhpWord\Shared\Converter::pixelToTwip(600), $cellColSpan); $textrun2 = $cell2->addTextRun($cellHCentered); $textrun2->addText('ФИО работника'); $cell2 = $table->addCell(\PhpOffice\PhpWord\Shared\Converter::pixelToTwip(600), $cellColSpan); $textrun2 = $cell2->addTextRun($cellHCentered); $textrun2->addText($fullName); $table->addRow([\PhpOffice\PhpWord\Shared\Converter::pixelToTwip(1200)]); $cell2 = $table->addCell(\PhpOffice\PhpWord\Shared\Converter::pixelToTwip(600), $cellColSpan); $textrun2 = $cell2->addTextRun($cellHCentered); $textrun2->addText('Должность'); $cell2 = $table->addCell(\PhpOffice\PhpWord\Shared\Converter::pixelToTwip(600), $cellColSpan); $textrun2 = $cell2->addTextRun($cellHCentered); $textrun2->addText($userFields["FIELDS"]["UF_POSITION"]); Методы вполне говорящие. $table->addRow() - создает строку таблицы $table->addCell() - создает ячейку в таблице. Причем сколько раз указан этот метод, столько ячеек и будет создано. 

пример таблицы 1

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

Читайте также:  Python create lock file

С помощью метода $section->addTextBreak(1); можно выставлять разрывы между секциями.

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

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

$cellStyleTopBorder = [ 'borderTopColor' => "000000", 'borderBottomColor' => "ffffff", 'borderRightColor' => "ffffff", 'borderLeftColor' => "ffffff", 'borderSize' => 1, 'cellMargin' => 0, 'cellSpacing ' => 0 ]; 

пример таблицы 1

Так же можно добавить несколько строк для свободного текста с помощью $section->addLine([‘weight’ => 1, ‘width’ => 450, ‘height’ => 0]);

Что бы сохранить получившийся документ и привязать его к соответствующему свойству вашего элемента, сделаем следующие шаги:

$pathToDOC = $_SERVER["DOCUMENT_ROOT"]."/upload/hr_docs/".$incomArray["CODE"]; \Bitrix\Main\IO\Directory::createDirectory($pathToDOC); // сохраняем документ, с помощью библиотеки. Доступен $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007'); $objWriter->save($pathToDOC.'/'.$incomArray["CODE"].'.docx'); // затем сохраняем его методами Bitrix, что бы файл попал в базу и проиндексировался, присваиваем значение свойству и удаляем тот что был создан с помощью библиотеки. $arFile = CFile::MakeFileArray($pathToDOC.'/'.$incomArray["CODE"].'.docx'); $arFile["MODULE_ID"] = "iblock"; $arFile["del"] = "Y"; CIBlockElement::SetPropertyValueCode($incomArray["ID"], "DOCUMENT_SECOND", ["86" => ["VALUE" => $arFile]]); \Bitrix\Main\IO\Directory::deleteDirectory($pathToDOC); // удаление директории куда записали исходный файл 

Немного странный подход, но по-другому сделать не получилось. В моем случае, все документы делались по ajax без перезагрузки страниц.

В результате кодовая база получается довольно большая, в основном из-за больших массивов со стилями и громоздких параметров при создании элементов таблиц. Библиотека PHPWord содержит возможность создавать все элементы word, и я показал наиболее сложные, на мой взгляд, элементы — таблицы.

Источник

Генерация word документа на php (шаблон .docx)

Первое с чего нужно начать, это создать .docx документ на своем ПК, например template.docx Для примера я взял куски из договора на создание сайта

Подготавливаем шаблон word документа

Открываем word файл и начинаем его шаблонизировать путем замены текста на переменные синтаксиса типа $ У нас будут следующие переменные, которые мы будем подставлять в документ: $ — номер догвоора
$ — город
$ — текущая дата
$ — ФИО
$ — Название Организации ООО
$ — Сумма
$ — Сумма, прописью
$ — Налог, 6% от суммы
$ — Налог, 6% от суммы (прописью)
$ — Юр. адрес
$ — Почтовый адрес
$ — ОГРН
$ — ОКПО
$ — КПП
$ — ИНН организации
$ — Название банка
$ — кор. счет
$ — р. счет
$ — ФИО директора Далее скачиваем библиотеку PhpWord

Читайте также:  Vue the mask typescript

Создаем word документ

//Подключаем библиотеку require $_SERVER["DOCUMENT_ROOT"].'/lib/phpword/autoload.php'; //создаем класс $phpWord = new \PhpOffice\PhpWord\PhpWord(); $_doc = new \PhpOffice\PhpWord\TemplateProcessor('template.docx');

Синтаксис для замены переменных

Подготовим пару переменных

//запихиваем сумму в переменную, что бы далее с ней поработать $summa = 25550; // делаем красивый формат $summa_format = number_format($summa, 2, ',', ' '); // вычислим налог от суммы (6%) и так же определим в отдельную переменную красивый формат суммы $summa_nalog = $summa * 6 / 100; $summa_nalog_format = number_format($summa_nalog, 2, ',', ' '); 

Подставляем, заменяем переменные в word документ

$_doc->setValue('num_dogovor', $number_document); $_doc->setValue('city', "г. Сочи"); $_doc->setValue('name', "Масков Илон Гениальнович"); $_doc->setValue('date', date("d.m.Y")); $_doc->setValue('company', "ООО НЕ ПРОХОДИТЕ МИМО"); $_doc->setValue('summa', $summa_format); $_doc->setValue('summa_str', num2str($summa)); $_doc->setValue('summa_nalog', $summa_nalog); $_doc->setValue('summa_nalog_str', num2str($summa_nalog)); $_doc->setValue('company_ogrn', "ОГРН компании"); $_doc->setValue('company_inn', "ИНН компании"); $_doc->setValue('company_kpp', "КПП компании"); $_doc->setValue('company_bank', "Какое то название банка"); $_doc->setValue('company_bik', "бик банка"); $_doc->setValue('company_ks', "12342352456235"); $_doc->setValue('company_rs', "66666666666"); $_doc->setValue('ur_address', "Юридический адрес, какой-нибудь"); $_doc->setValue('post_address', "Фактический адрес"); $_doc->setValue('direktor', "Альберт Енштейн"); $_doc->setValue('company_okpo', "4444444");

Сохраняем сгенерированный word файл на сервер

$img_Dir_Str = "/files/"; $img_Dir = $_SERVER['DOCUMENT_ROOT']."/". $img_Dir_Str; @mkdir($img_Dir, 0777); $file = str_replace("/","-", "Договор №".date("d-m-Y")).".docx"; $_doc->saveAs($img_Dir.$file);

Обратите внимание на строку: $_doc->setValue(‘summa_str’, num2str($summa)); и $_doc->setValue(‘summa_nalog_str’, num2str($summa_nalog)); В ней мы используем функцию перевода числа в прописной вид

Функция перевода числа в прописной вид

function num2str($num) < $nul='ноль'; $ten=array( array('','один','два','три','четыре','пять','шесть','семь', 'восемь','девять'), array('','одна','две','три','четыре','пять','шесть','семь', 'восемь','девять'), ); $a20=array('десять','одиннадцать','двенадцать','тринадцать','четырнадцать' ,'пятнадцать','шестнадцать','семнадцать','восемнадцать','девятнадцать'); $tens=array(2=>'двадцать','тридцать','сорок','пятьдесят','шестьдесят','семьдесят' ,'восемьдесят','девяносто'); $hundred=array('','сто','двести','триста','четыреста','пятьсот','шестьсот', 'семьсот','восемьсот','девятьсот'); $unit=array( // Units array('коп.' ,'коп.' ,'коп.', 1), array('рубль' ,'рубля' ,'рублей' ,0), array('тысяча' ,'тысячи' ,'тысяч' ,1), array('миллион' ,'миллиона','миллионов' ,0), array('миллиард','милиарда','миллиардов',0), ); // list($rub,$kop) = explode('.',sprintf("%015.2f", floatval($num))); $out = array(); if (intval($rub)>0) < foreach(str_split($rub,3) as $uk=>$v) < // by 3 symbols if (!intval($v)) continue; $uk = sizeof($unit)-$uk-1; // unit key $gender = $unit[$uk][3]; list($i1,$i2,$i3) = array_map('intval',str_split($v,1)); // mega-logic $out[] = $hundred[$i1]; # 1xx-9xx if ($i2>1) $out[]= $tens[$i2].' '.$ten[$gender][$i3]; # 20-99 else $out[]= $i2>0 ? $a20[$i3] : $ten[$gender][$i3]; # 10-19 | 1-9 // units without rub & kop if ($uk>1) $out[]= morph($v,$unit[$uk][0],$unit[$uk][1],$unit[$uk][2]); > //foreach > else $out[] = $nul; $out[] = morph(intval($rub), $unit[1][0],$unit[1][1],$unit[1][2]); // rub $out[] = $kop.' '.morph($kop,$unit[0][0],$unit[0][1],$unit[0][2]); // kop return trim(preg_replace('/ /', ' ', join(' ',$out))); > /** * Склоняем словоформу * @ author runcore */ function morph($n, $f1, $f2, $f5) < $n = abs(intval($n)) % 100; if ($n>10 && $n<20) return $f5; $n = $n % 10; if ($n>1 && $n

Источник

Оцените статью