Формирование word документа php

PHPWord - создание MS Word документов средствами PHP

От автора: не так давно на нашем сайте были опубликованы уроки по работе с таблицами Microsoft Excel средствами языка PHP, которые вызвали значительный интерес у нашей аудитории и поэтому, сегодня я решил показать Вам, как создавать документы Microsoft Word ,формата .docx, используя мощнейшую библиотеку PHPWord.

скачать исходникискачать урок

Актуальную версию библиотеки PHPWord, вы найдете на сервисе GitHub.

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

Установка PHPWord

Установка PHPWord, может быть выполнена двумя способами. Первый способ – ручной, при котором Вы скачиваете архив с последней актуальной версией PHPWord, далее, выполняете распаковку, копируете файлы в собственный проект и подключаете на соответствующих страницах. То есть достаточно стандартный способ. И второй – так сказать, автоматический способ установки, используя инструмент Composer, который мы будем использовать в данном уроке.

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

Итак, открываем командную строку и переходим в каталог нашего проекта, используя команду “CD имя папки”.

Далее, используя конструкцию “composer require”, указываем от какой библиотеки “зависит” наш проект и выполняем инструкцию.

composer require phpoffice/phpword

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

require ‘vendor/autoload.php’;

Далее, создаем объект главного класса библиотеки.

$phpWord = new  PhpOfficePhpWordPhpWord();

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

Создание документа MS Word

Теперь, мы можем сформировать свой первый документ MS Word средствами языка PHP. Для этого, первым делом определим шрифт, используя метод setDefaultFontName(имя шрифта), который будет использоваться, по умолчанию, для отображения текстовых данных.

$phpWord>setDefaultFontName(‘Times New Roman’);

Затем зададим, размер шрифта, при помощи метода setDefaultFontSize(размер шрифта).

$phpWord>setDefaultFontSize(14)

Перед добавлением текстовых данных, необходимо определить параметры всего документа в целом. Для получения объекта параметров документа, используем метод getDocInfo().

$properties = $phpWord>getDocInfo();  

Используя полученный объект, зададим основные параметры документа.

$properties>setCreator(‘Name’);

$properties>setCompany(‘Company’);

$properties>setTitle(‘Title’);

$properties>setDescription(‘Description’);

$properties>setCategory(‘My category’);

$properties>setLastModifiedBy(‘My name’);

$properties>setCreated(mktime(0, 0, 0, 3, 12, 2015));

$properties>setModified(mktime(0, 0, 0, 3, 14, 2015));

$properties>setSubject(‘My subject’);

$properties>setKeywords(‘my, key, word’);  

При этом использовались следующие методы (каждый метод устанавливает определенный глобальный параметр документа):

setCreator() – автор документа;

setCompany() – организация автора документа;

setTitle() – заголовок документа;

setDescription() – краткое описание документа;

setCategory() – категория документа;

setLastModifiedBy() – автор последнего редактирования документа;

setCreated() – дата создания документа;

setModified() – дата редактирования документа;

setSubject() – тема документа;

setKeywords() – ключевые слова документа.

Собственно, теперь мы можем добавить необходимые текстовые данные в будущий документ MS Word, но перед этим мы должны определиться с понятием раздела, которое используется библиотекой PHPWord, для работы с документом.

Итак, раздел или секция – это специальная область прямоугольной формы, внутри которой размещаются элементы документа, такие как текст, изображения, списки, таблицы и т.д. А значит, перед добавлением информации в будущий документ, необходимо создать раздел, что мы собственно и выполним, используя метод addSection(массив стилей).

$sectionStyle = array(

‘orientation’ => ‘landscape’,

‘marginTop’ => PhpOfficePhpWordSharedConverter::pixelToTwip(10),

‘marginLeft’ => 600,

    ‘marginRight’ => 600,

    ‘colsNum’ => 1,

    ‘pageNumberingStart’ => 1,

    ‘borderBottomSize’=>100,

    ‘borderBottomColor’=>‘C0C0C0’

);

$section = $phpWord>addSection($sectionStyle);

Данный метод, в качестве результата работы возвращает объект созданного раздела, который мы сохраним в переменную. При вызове метода, в качестве первого параметра, можно передать массив настроек, которые будут использоваться для создания раздела (каждая настройка представляет собой отдельную ячейку массива). В примере Выше, я использовал следующие настройки:

orientation — расположение раздела, в виде альбомного листа (значение по умолчанию portrait);

marginTop – верхний отступ;

marginLeft – отступ от левого края;

marginRight – отступ от правого края;

colsNum – количество колонок, в которых будут отображаться данные;

pageNumberingStart – страница, с которой будет начата нумерация страниц;

borderBottomSize – размер нижней рамки;

borderBottomColor – цвет нижней рамки.

Полный список настроек приведен в разделе “Styles”, официальной документации PHPWord.

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

Твип (англ. twip) — типографская единица измерения, равная одной двадцатой пункта, или 1/1440 дюйма, или 1/567 сантиметра (приближённо).

Конечно, разработчикам не совсем удобно использовать данную единицу измерения, для определения размеров, поэтому библиотека PHPWord, содержит в своем составе, специальный класс конвертер, основных известных единиц в твипы. К примеру, для конвертации “пискселей в твипы”, необходимо использовать следующий метод pixelToTwip() , который переведет значение в пикселях, передаваемое в качестве первого параметра в твипы.

PhpOfficePhpWordSharedConverter::pixelToTwip(10)

Для добавления текста, в будущий документ, необходимо использовать метод addText($text, [$fontStyle], [$paragraphStyle]). В качестве параметров, при вызове данного метода, необходимо передать следующее:

$text – текст, который необходимо отобразить на странице документа. При этом текст не должен содержать тегов HTML, поэтому, как правило, его обрабатывают функцией htmlspecialchars().

$fontStyle – массив с настройками шрифта, который будет использоваться для отображения текста. Полный список доступных настроек, Вы найдете на странице “Styles” в разделе “Font”, официальной документации.

$paragraphStyle – массив с настройками параграфа, или абзаца, в котором будет отображен текст. Полный список доступных настроек, Вы найдете на странице “Styles” в разделе “ Paragraph”, официальной документации.

Теперь, используем рассмотренный Выше метод и добавим текст, в будущий документ.

$text = «PHPWord is a library written in pure PHP that provides a set of classes to write to and read from different document file formats.»;

$fontStyle = array(‘name’=>‘Arial’, ‘size’=>36, ‘color’=>‘075776’, ‘bold’=>TRUE, ‘italic’=>TRUE);

$parStyle = array(‘align’=>‘right’,‘spaceBefore’=>10);

$section>addText(htmlspecialchars($text), $fontStyle,$parStyle);

Настройки шрифта, использованные в примере:

name – имя шрифта;

size – размер шрифта;

color – цвет шрифта;

bold – если, true, будет использован жирный шрифт;

italic — если, true, будет использован курсив.

Настройки параграфа из примера:

align – выравнивание текста в параграфе, в нашем случае по правому краю;

spaceBefore – расстояние до параграфа.

Теперь давайте, непосредственно, создадим документ MS Word.

$objWriter = PhpOfficePhpWordIOFactory::createWriter($phpWord,‘Word2007’);

$objWriter>save(‘doc.docx’);

Для создания документа, необходимо создать объект специального класса Word2007, используя статический метод createWriter(), класса IOFactory. Класс IOFactory – реализует шаблон проектирования Factory, и необходим для создания объектов других классов, имена которых мы передаем в качестве, второго параметра при вызове метода createWriter(). Далее вызывая метод save() и передавая в качестве первого параметра, имя будущего файла, мы формируем документ MS Word.

Как Вы видите, документ успешно создан. Если, не нужно создавать файл, а сформированный документ, необходимо отдать пользователю на скачивание, то при вызове метода save(), в качестве первого параметра, необходимо передать строку «php://output». При этом, так же, необходимо указать определенный набор заголовков.

header(«Content-Description: File Transfer»);

header(‘Content-Disposition: attachment; filename=»first.docx»‘);

header(‘Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document’);

header(‘Content-Transfer-Encoding: binary’);

header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0’);

header(‘Expires: 0’);

$objWriter = PhpOfficePhpWordIOFactory::createWriter($phpWord, ‘Word2007’);

$objWriter>save(«php://output»);

Добавление списков

Для формирования списков, в будущем документе, необходимо использовать метод addListItem($text, [$depth], [$fontStyle], [$listStyle], [$paragraphStyle]), который за каждый свой вызов, формирует элемент списка. Параметры, которые необходимо передать при вызове метода:

$text – текст, элемента списка;

$depth – глубина вложенности. Если создается одноуровневый список, то данный параметр равен 0.

$fontStyle – массив настроек шрифта, по аналогии с добавлением простого текста.

$listStyle – массив настроек списка.

$paragraphStyle – массив настроек параграфа, по аналогии с добавлением текста.

Массив настроек списка $listStyle, поддерживает настройку – listType, то есть, тип списка, к примеру, нумерованный или же нет. В качестве значений, доступны специальные константы класса PhpOfficePhpWordStyleListItem:

TYPE_SQUARE_FILLED FILLED – не нумерованный список. В виде маркеров используются квадраты.

TYPE_BULLET_FILLED – не нумерованный список (значение по умолчанию). В виде маркеров используются точки.

TYPE_BULLET_EMPTY FILLED – не нумерованный список. В виде маркеров используются не закрашенные окружности.

TYPE_NUMBER – нумерованный список.

TYPE_NUMBER_NESTED – многоуровневый нумерованный список.

TYPE_ALPHANUM – нумерованный список, с использованием букв, в качестве маркеров.

Таким образом, следующий код, добавит одноуровневый нумерованный список в документ.

$fontStyle = array(‘name’ => ‘Times New Roman’, ‘size’ => 16,‘color’ => ‘075776’,‘italic’=>true);

$listStyle = array(‘listType’=>PhpOfficePhpWordStyleListItem::TYPE_BULLET_EMPTY);

$section>addListItem(‘Элемент 1’,0,$fontStyle,$listStyle);        

$section>addListItem(‘Элемент 2’,0,$fontStyle,$listStyle);        

$section>addListItem(‘Элемент 3’,0,$fontStyle,$listStyle);        

$section>addListItem(‘Элемент 4’,0,$fontStyle,$listStyle);        

$section>addListItem(‘Элемент 5’,0,$fontStyle,$listStyle);  

Добавление изображений

Для добавления изображений, необходимо использовать метод addImage($path,[$imgStyle]). При вызове данного метода, в качестве первого параметра, передается путь к изображению, которое необходимо добавить в документ. В качестве второго, необязательного параметра, можно передать массив с настройками отображения изображения. Полный список настроек изображения, Вы найдете на странице “Styles”, в разделе “ Image”.

Соответственно, давайте добавим изображение в создаваемый документ.

$section>addImage(‘picture.jpg’, array(

        ‘width’ => 100,

        ‘height’ => 100,

));

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

На этом данный урок я буду завершать. Как Вы видите, библиотека PHPWord, обладает огромнейшим функционалом и позволяет формировать документы MS Word различной сложности. Если она Вас заинтересовала, то изучайте более подробно официальную документацию, потому как мы с Вами рассмотрели только некоторые ее возможности. Всего Вам доброго и удачного кодирования!!!

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

Для примера я взял куски из договора на создание сайта

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

Открываем word файл и начинаем его шаблонизировать путем замены текста на переменные синтаксиса типа ${data}

У нас будут следующие переменные, которые мы будем подставлять в документ:

${num_dogovor} — номер догвоора
${city} — город
${date} — текущая дата
${name} — ФИО
${company} — Название Организации ООО
${summa} — Сумма
${summa_str} — Сумма, прописью
${summa_nalog} — Налог, 6% от суммы 
${summa_nalog_str} — Налог, 6% от суммы (прописью)
${ur_address} — Юр. адрес
${post_address} — Почтовый адрес
${company_ogrn} — ОГРН
${company_okpo​​​​​​​} — ОКПО
${company_kpp​​​​​​​} — КПП
${company_inn​​​​​​​} — ИНН организации
${company_bank​​​​​​​} — Название банка
${company_ks​​​​​​​} — кор. счет
${company_rs​​​​​​​} — р. счет
${direktor​​​​​​​} — ФИО директора

Далее скачиваем библиотеку PhpWord

//Подключаем библиотеку
require $_SERVER["DOCUMENT_ROOT"].'/lib/phpword/autoload.php';

//создаем класс
$phpWord = new  PhpOfficePhpWordPhpWord(); 
$_doc = new PhpOfficePhpWordTemplateProcessor('template.docx');

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

$_doc->setValue('num_dogovor', $number_document); 

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

//запихиваем сумму в переменную, что бы далее с ней поработать
$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('/ {2,}/', ' ', 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<5) return $f2;
	if ($n==1) return $f1;
	return $f5;
}

Статья подготовлена для Вас сайтом kisameev.ru

Перевел: Кисамеев Дмитрий

Урок создан: 3 октября 2021 г.

Статью просмотрели: 8670

Понравилось: 17

На момент написания данной статьи релиз PHPWord датируется 8 июля 2011 года. Да еще бета версия. Конечно старовата, но с другой стороны, если класс хорошо выполняет поставленную задачу, то почему бы и нет?!

К делу: скачиваем, подключаем обычным инклюдом и вперед.

Создаем экземпляр класса:

$PHPWord = new PHPWord();

Необязательно, но можем добавить, что по-умолчанию используем шрифт Arial размером 14 пунктов.

$PHPWord->setDefaultFontName(‘Arial’);
$PHPWord->setDefaultFontSize(14);

Добавляем новый раздел в документ:

$section = $PHPWord->createSection([array $sectionStyle]);

По-умолчанию этот метод создает страницу A4 книжной ориентации. Поля: по 2,5 см верхнее, левое и правое и 2 см нижнее.

Массив $sectionStyle может содержать:

$sectionStyle = array(
    ‘orientation’ => ‘landscape’, // альбомная ориентация страницы
    ‘marginTop’ => ‘0’, // по-умолчанию равен 1418* и соответствует 2,5 см отступа сверху
    ‘marginLeft’ => ‘0’, // по-умолчанию равен 1418* и соответствует 2,5 см отступа слева
    ‘marginRight’ => ‘0’, // по-умолчанию равен 1418* и соответствует 2,5 см отступа справа
    ‘marginBottom’ => ‘0’, // по-умолчанию равен 1134* и соответствует 2 см отступа снизу
    ‘pageSizeW’ => ‘8419’, // по-умолчанию равен 11906* и соответствует 210 мм по ширине
    ‘pageSizeH’ => ‘11906’, // по-умолчанию равен 16838* и соответствует 297 мм по высоте
    ‘borderColor’=>’999999’, // Цвет ненужного бордюра
    ‘borderSize’=>’100’, // Ширина ненужного бордюра*
);

* В качестве единиц измерения тут используются типографские твипы. Для справки: 1 твип равен 1/567 см.

Текст

У нас есть пустая страница. Для начала добавим обычную текстовую строку. Для этого существует метод addText() и два синтаксиса:

$section->addText(string $text[, array $textStyle]);
// или
$section->addText(string $text[, string $fontStyleName[, string $paragraphStyleName]]);

На практике выглядит это так:

$section->addText(‘Создание сайтов — Лаборатории WEB’);

Тут стоит сделать замечание: автор PHPWord решил, что все, кто будет пользоваться его классом будут работать в кодировке отличной от UTF-8. Если просматривать код PHPWord, то там везде, как через мясорубку, все текстовые переменные проходят через utf8_encode(). Вот в моем случае это сыграло не на руку, потому что я как раз-то работаю с UTF-8.

Что делать, если вы тоже работаете с UTF-8? Варианта как минимум два:

  1. перед тем как отдать строки в PHPWord измените их кодировку на не UTF-8 с помощью iconv();
  2. прошерстите PHPWord и удалите все utf8_encode() оттуда.

Мной был выбран второй вариант.

Двигаемся дальше… Наведем «красоту» в тексте.

Первый вариант — это объявление всякой «красоты» непосредственно в методе addText().

$section->addText(‘Разработка сайтов — Лаборатория WEB’, array(
    ‘name’ => ‘Tahoma’,
    ‘color’ => ‘990000’,
    ‘bold’ => true,
    ‘italic’ => true,
    ‘size’ => 16,
));

Второй вариант — объединение набора «красот» в стиль.

$PHPWord->addFontStyle(‘fStyle’, array(
    ‘name’ => ‘Tahoma’,
    ‘color’ => ‘990000’,
    ‘bold’ => true,
    ‘italic’ => true,
    ‘size’ => 16,
));
$section->addText(‘Изготовление сайтов — Лаборатория WEB’, ‘fStyle’);

Сейчас был задан стиль для шрифта, но можно задать стиль и для параграфа:

$PHPWord->addParagraphStyle(‘pStyle’, array(
    ‘align’ => ‘center’,
    ‘spaceBefore’ => 100, // отступ сверху
    ‘spaceAfter’ => 100, // отступ снизу
    ‘spacing’ => 100, // межстрочный интервал
));

И использовать эти стили как совместно, так и по-отдельности:

$section->addText(‘Поддержка сайтов — Лаборатория WEB’, ‘fStyle’, ‘pStyle’);
// или
$section->addText(‘Продвижение сайтов — Лаборатория WEB’, null, ‘pStyle’);

Если вам нужно объединить в одном параграфе несколько текстовых блоков с разным форматированием, то для этого существует метод createTextRun():

$textrun = $section->createTextRun(‘pStyle’);
$textrun->addText(‘Жирный’, array(
    ‘bold’ => true
));
$textrun->addText(‘Курсив’, array(
    ‘italic’ => true
));
$textrun->addText(‘Красный’, array(
    ‘color’=>’990000’
));

С текстом, вроде, все ясно. Перенос курсора на следующую строку:

$section->addTextBreak([int $number]); // В скобках указывается количество строк на которое нужно перейти. По-умолчанию $number = 1

Изображения

Изображения вставляются также просто, как и текст. Для этого используется метод addImage():

$section->addImage(string $srcLocalImage[, array $imageStyle]);

Массив $imageStyle может содержать:

$imageStyle = array(
    ‘width’ => ‘200’, // в пикселях
    ‘height’ => ‘200’, // в пикселях
    ‘align’ => ‘center’, // left || right || center
)

На практике это выглядит так:

$section->addImage(‘path-to-image.png’, $imageStyle);

Ссылки

Метод для добавления ссылки addLink():

$section->addLink(string $url, [string $text[, string $linkFontStyle[, string $paragraphStyle]]]);

Наведение «красоты» для ссылки:

$PHPWord->addLinkStyle(‘lStyle’, array(
    ‘name’ => ‘Tahoma’,
    ‘color’ => ‘990000’,
    ‘bold’ => true,
    ‘italic’ => true,
    ‘size’ => 16,
));

На практике это выглядит:

$section->addLink(‘http://www.w-lab.ru’, ‘Лаборатория WEB’, ‘lStyle’, ‘pStyle’);

Таблицы

С таблицами немного сложнее. Для добавления таблицы на страницу используем метод addTable(). Как и в случае с текстом, для таблиц существует два синтаксиса. Первый выглядит так:

$table = $section->addTable([array $tableStyle]);

Массив $tableStyle может содержать:

$tableStyle = array(
    ‘cellMarginTop’ => 0, // отступ от ячейки сверху *
    ‘cellMarginRight’ => 0, // отступ от ячейки справа *
    ‘cellMarginBottom’ => 0, // отступ от ячейки снизу *
    ‘cellMarginLeft’ => 0, // отступ от ячейки слева *
);

* в твипах.

cellMarginTop, cellMarginRight, cellMarginBottom, cellMarginLeft можно заменить одним cellMargin.

Второй синтаксис:

$table = $section->addTable([string $tableStyleName]);

Для того, чтобы назначить $tableStyleName, вызовем метод addTableStyle():

$PHPWord->addTableStyle(string $styleName, array $tableStyle[, array $firstRowTableStyle]);

Как можно понять из названия, массив $firstRowTableStyle отвечает за стили первой строки таблицы.

На практике:

$word->addTableStyle(‘tStyle’,  array(
    ‘borderSize’ => 6,
    ‘borderColor’ => ‘999999’,
    ‘cellMarginTop’ => 40,
    ‘cellMarginRight’ => 20,
    ‘cellMarginBottom’ => 40,
    ‘cellMarginLeft’ => 20,
), array(
    ‘borderSize’ => 12,
    ‘borderColor’ => ‘000000’,
    ‘cellMargin’ => 80,
));
$table = $section->addTable(‘tStyle’);

Тут мы назначили для ячеек всей таблицы ширину границы 6, цвет серый, с отступами 40 20 40 20. А для ячеек первой строки ширину границы 12, черного цвета с отступами 80 со всех сторон.

Теперь в таблицу нужно добавить строку. Для этого существует метод addRow():

$table->addRow([int $rowHeight]); // $rowHeight — высота строки в твипах

И методом addCell() добавляем ячейку:

$cell = $table->addCell(int $cellWidth[, array $cellStyle]);

Здесь $cellWidth — ширина ячейки в твипах, а массив $cellStyle может содержать:

$cellStyle = array(
    ‘valign’ => ‘center’, // top || bottom || center || both
    ‘textDirection’ => PHPWord_Style_Cell:TEXT_DIR_BTLR, // PHPWord_Style_Cell:TEXT_DIR_BTLR || PHPWord_Style_Cell:TEXT_DIR_TBRL
    ‘bgColor’ => ‘fafafa’,
    ‘borderTopSize’ => 6,
    ‘borderRightSize’ => 6,
    ‘borderBottomSize’ => 6,
    ‘borderLeftSize’ => 6,
    ‘borderSize’ => 6, // вместо borderTopSize, borderRightSize, borderBottomSize, borderLeftSize
    ‘borderTopColor’ => ‘999999’,
    ‘borderRightColor’ => ‘999999’,
    ‘borderBottomColor’ => ‘999999’,
    ‘borderLeftColor’ => ‘999999’,
    ‘borderColor’ => ‘999999’, // вместо borderTopColor, borderRightColor, borderBottomColor, borderLeftColor
);

Последнее, что нужно сделать — это добавить содержимое в новую ячейку (добавим текст). Сделать это можно двумя способами:

$cell = $table->addCell();
$cell->addText(‘Создание Langing Page — Лаборатория WEB’);
// или
$table->addCell()->addText(‘Разработка Langing Page — Лаборатория WEB’);

Списки

Добавление на страницу нумерованных и ненумерованных списков осуществляется методом addListItem():

$section->addListItem(string $text[, int $depth[, string $textStyle[, array $listStyle[, string $paragraphStyle]]]]);

Здесь $depth — глубина (вложенность) списка от 1 до 9, а массив $listType может состоять из:

$listType = array(
    ‘listType’ => PHPWord_Style_ListItem:TYPE_NUMBER, // одноуровневый нумерованный список
);

Также параметр ‘listType’ может принимать следующие значения:

  • PHPWord_Style_ListItem:TYPE_NUMBER_NESTED — многоуровневый нумерованный список;
  • PHPWord_Style_ListItem:TYPE_BULLET_FILLED — ненумерованный список с маркерами в виде закрашенных кругов;
  • PHPWord_Style_ListItem:TYPE_BULLET_EMPTY — ненумерованный список с маркерами в виде незакрашенных кругов;
  • PHPWord_Style_ListItem:TYPE_SQUARE_FILLED — ненумерованный список с маркерами в виде закрашенных квадратов.

Колонтитулы

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

Создадим верхний и нижний колонтитулы и добавим в них содержимое:

$header = $section->createHeader();
$header->addText(‘Лаборатория WEB’);

$footer = $section->createFooter();
$footer->addPreserveText(‘Страница {PAGE} из {NUMPAGES}’, array(
    ‘italic’ => true,
),
array(
    ‘align’ => ‘right’,
));

Метод addPreserveText() существует специально для добавления номеров страниц.

Разное

$section->addPageBreak(); // Разрыв страницы

Метаданные:

$meta = $PHPWord->getProperties();
$meta->setTitle(‘Название’);
$meta->setSubject(‘Тема’);
$meta->setCreator(‘Автор’);
$meta->setCompany(‘Учреждение’);
$meta->setDescription(‘Заметки’);
$meta->setCategory(‘Группа’);
$meta->setLastModifiedBy(‘Автор изменений’);
$meta->setKeywords(‘Ключевые слова’);
$meta->setCreated(time()); // Дата и время создания документа
$meta->setModified(time()); //Дата и время последнего изменения документа

Сохранение файлов

В файл на жесткий:

$writer = PHPWord_IOFactory::createWriter($PHPWord, ‘Word2007’);
$writer->save(‘document.docx’);

Вывод вопроса на скачивание:

header(«Content-Type: application/msword»);
header(«Content-Transfer-Encoding: binary»);
header(‘Content-Disposition: attachment;filename=»document.docx»‘);
header(‘Cache-Control: max-age=0’);
$writer = PHPWord_IOFactory::createWriter($PHPWord, ‘Word2007’);
$writer->save(‘php://output’);

PHPWord

Latest Stable Version
CI
Code Quality
Code Coverage
Total Downloads
License
Join the chat at https://gitter.im/PHPOffice/PHPWord

PHPWord is a library written in pure PHP that provides a set of classes to write to and read from different document file formats. The current version of PHPWord supports Microsoft Office Open XML (OOXML or OpenXML), OASIS Open Document Format for Office Applications (OpenDocument or ODF), Rich Text Format (RTF), HTML, and PDF.

PHPWord is an open source project licensed under the terms of LGPL version 3. PHPWord is aimed to be a high quality software product by incorporating continuous integration and unit testing. You can learn more about PHPWord by reading the Developers’ Documentation.

If you have any questions, please ask on StackOverFlow

Read more about PHPWord:

  • Features
  • Requirements
  • Installation
  • Getting started
  • Contributing
  • Developers’ Documentation

Features

With PHPWord, you can create OOXML, ODF, or RTF documents dynamically using your PHP scripts. Below are some of the things that you can do with PHPWord library:

  • Set document properties, e.g. title, subject, and creator.
  • Create document sections with different settings, e.g. portrait/landscape, page size, and page numbering
  • Create header and footer for each sections
  • Set default font type, font size, and paragraph style
  • Use UTF-8 and East Asia fonts/characters
  • Define custom font styles (e.g. bold, italic, color) and paragraph styles (e.g. centered, multicolumns, spacing) either as named style or inline in text
  • Insert paragraphs, either as a simple text or complex one (a text run) that contains other elements
  • Insert titles (headers) and table of contents
  • Insert text breaks and page breaks
  • Insert and format images, either local, remote, or as page watermarks
  • Insert binary OLE Objects such as Excel or Visio
  • Insert and format table with customized properties for each rows (e.g. repeat as header row) and cells (e.g. background color, rowspan, colspan)
  • Insert list items as bulleted, numbered, or multilevel
  • Insert hyperlinks
  • Insert footnotes and endnotes
  • Insert drawing shapes (arc, curve, line, polyline, rect, oval)
  • Insert charts (pie, doughnut, bar, line, area, scatter, radar)
  • Insert form fields (textinput, checkbox, and dropdown)
  • Create document from templates
  • Use XSL 1.0 style sheets to transform headers, main document part, and footers of an OOXML template
  • … and many more features on progress

Requirements

PHPWord requires the following:

  • PHP 7.1+
  • XML Parser extension
  • Laminas Escaper component
  • Zip extension (optional, used to write OOXML and ODF)
  • GD extension (optional, used to add images)
  • XMLWriter extension (optional, used to write OOXML and ODF)
  • XSL extension (optional, used to apply XSL style sheet to template )
  • dompdf library (optional, used to write PDF)

Installation

PHPWord is installed via Composer.
To add a dependency to PHPWord in your project, either

Run the following to use the latest stable version

composer require phpoffice/phpword

or if you want the latest unreleased version

composer require phpoffice/phpword:dev-master

Getting started

The following is a basic usage example of the PHPWord library.

<?php
require_once 'bootstrap.php';

// Creating the new document...
$phpWord = new PhpOfficePhpWordPhpWord();

/* Note: any element you append to a document must reside inside of a Section. */

// Adding an empty Section to the document...
$section = $phpWord->addSection();
// Adding Text element to the Section having font styled by default...
$section->addText(
    '"Learn from yesterday, live for today, hope for tomorrow. '
        . 'The important thing is not to stop questioning." '
        . '(Albert Einstein)'
);

/*
 * Note: it's possible to customize font style of the Text element you add in three ways:
 * - inline;
 * - using named font style (new font style object will be implicitly created);
 * - using explicitly created font style object.
 */

// Adding Text element with font customized inline...
$section->addText(
    '"Great achievement is usually born of great sacrifice, '
        . 'and is never the result of selfishness." '
        . '(Napoleon Hill)',
    array('name' => 'Tahoma', 'size' => 10)
);

// Adding Text element with font customized using named font style...
$fontStyleName = 'oneUserDefinedStyle';
$phpWord->addFontStyle(
    $fontStyleName,
    array('name' => 'Tahoma', 'size' => 10, 'color' => '1B2232', 'bold' => true)
);
$section->addText(
    '"The greatest accomplishment is not in never falling, '
        . 'but in rising again after you fall." '
        . '(Vince Lombardi)',
    $fontStyleName
);

// Adding Text element with font customized using explicitly created font style object...
$fontStyle = new PhpOfficePhpWordStyleFont();
$fontStyle->setBold(true);
$fontStyle->setName('Tahoma');
$fontStyle->setSize(13);
$myTextElement = $section->addText('"Believe you can and you're halfway there." (Theodor Roosevelt)');
$myTextElement->setFontStyle($fontStyle);

// Saving the document as OOXML file...
$objWriter = PhpOfficePhpWordIOFactory::createWriter($phpWord, 'Word2007');
$objWriter->save('helloWorld.docx');

// Saving the document as ODF file...
$objWriter = PhpOfficePhpWordIOFactory::createWriter($phpWord, 'ODText');
$objWriter->save('helloWorld.odt');

// Saving the document as HTML file...
$objWriter = PhpOfficePhpWordIOFactory::createWriter($phpWord, 'HTML');
$objWriter->save('helloWorld.html');

/* Note: we skip RTF, because it's not XML-based and requires a different example. */
/* Note: we skip PDF, because "HTML-to-PDF" approach is used to create PDF documents. */

More examples are provided in the samples folder. For an easy access to those samples launch php -S localhost:8000 in the samples directory then browse to http://localhost:8000 to view the samples.
You can also read the Developers’ Documentation for more detail.

Contributing

We welcome everyone to contribute to PHPWord. Below are some of the things that you can do to contribute.

  • Read our contributing guide.
  • Fork us and request a pull to the master branch.
  • Submit bug reports or feature requests to GitHub.
  • Follow @PHPWord and @PHPOffice on Twitter.

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

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

composer install

После чего в данном разделе появляется папка «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

class DocChange{
 public static function DocCreator(&$arFields) {
      if($arFields["PROPERTY_VALUES"]) { // условие на инфоблок или что угодно  
       self::CreateAfterDoc($arFields);  
       }
     }
}

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

public function CreateAfterDoc($incomArray) { 
 $phpWord = new PhpOfficePhpWordPhpWord(); // создаем экземпляр класса
 // параметры которые будут указаны при создании документа
 $phpWord->setDefaultFontName("Times New Roman"); // устанавливаем шрифт
 $phpWord->setDefaultFontSize(12); // устанавливаем шрифт
 $phpWord->getSettings()->setThemeFontLang(new PhpOfficePhpWordStyleLanguage(PhpOfficePhpWordStyleLanguage::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); // добавление раздела с добавлением стилей
}

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

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

$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' => PhpOfficePhpWordSimpleTypeJc::CENTER);
$cellVCentered = array('valign' => 'center');
И наконец, в нашей секции обрисовываем таблицу и передаем в конструктор идентификатор стилей.
$table = $section->addTable("first_table");

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

$table->addRow([PhpOfficePhpWordSharedConverter::pixelToTwip(1200)]); 
 $cell2 = $table->addCell(PhpOfficePhpWordSharedConverter::pixelToTwip(600), $cellColSpan);
 $textrun2 = $cell2->addTextRun($cellHCentered);
 $textrun2->addText('ФИО работника');     

 $cell2 = $table->addCell(PhpOfficePhpWordSharedConverter::pixelToTwip(600), $cellColSpan);
 $textrun2 = $cell2->addTextRun($cellHCentered);
 $textrun2->addText($fullName);

$table->addRow([PhpOfficePhpWordSharedConverter::pixelToTwip(1200)]); 
 $cell2 = $table->addCell(PhpOfficePhpWordSharedConverter::pixelToTwip(600), $cellColSpan);
 $textrun2 = $cell2->addTextRun($cellHCentered);
 $textrun2->addText('Должность');     

$cell2 = $table->addCell(PhpOfficePhpWordSharedConverter::pixelToTwip(600), $cellColSpan);
 $textrun2 = $cell2->addTextRun($cellHCentered);   
 $textrun2->addText($userFields["FIELDS"]["UF_POSITION"]);
Методы вполне говорящие. 
 $table->addRow() - создает строку таблицы
 $table->addCell() - создает ячейку в таблице. Причем сколько раз указан этот метод, столько ячеек и будет создано.

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

С помощью метода $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"];
BitrixMainIODirectory::createDirectory($pathToDOC);

// сохраняем документ, с помощью библиотеки. Доступен
$objWriter = PhpOfficePhpWordIOFactory::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]]);
BitrixMainIODirectory::deleteDirectory($pathToDOC); // удаление директории куда записали исходный файл

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

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

Like this post? Please share to your friends:
  • Формирование данных в excel это
  • Формирование excel файлов на php
  • Форматы ячеек в excel дробный
  • Формирование графиков в excel
  • Формирование excel файла python