Документация для разработчиков
Темная тема

Примеры генерации документа

Здесь изложен полностью процесс генерации документа. Все примеры написаны на php через веб-хук.

Создание нумератора

Для начала создадим новый нумератор для реста с помощью documentgenerator.numerator.add.

\Bitrix\Main\Loader::includeModule('rest');
$client = new \Bitrix\Main\Web\HttpClient();
$webHookUrl = 'http://mycrm.bitrix24.com/rest/1/webhookkey/';
$prefix = 'documentgenerator';

$data = [
	'fields' => [
		'name' => 'Rest Numerator',
		'template' => '{NUMBER}',
		'settings' => [
			'Bitrix_Main_Numerator_Generator_SequentNumberGenerator' => [
				'start' => '0',
				'step' => '1',
			],
		], 
	],
];

$url = $webHookUrl.$prefix.'.numerator.add/';
$answer = $client->post($url, $data);
try
{
	$result = \Bitrix\Main\Web\Json::decode($answer);
}
catch(Exception $e)
{
	var_dump($answer);
}

print_r($result);

Ответ

[result] => Array
	(
		[numerator] => Array
			(
				[name] => new rest numerator
				[template] => {NUMBER}
				[id] => 68
				[settings] => Array
					(
						[Bitrix_Main_Numerator_Generator_SequentNumberGenerator] => Array
							(
								[start] => 0
								[step] => 1
								[periodicBy] => 
								[timezone] => 
								[isDirectNumeration] => 
							)

					)

			)
	)

Из ответа получаем id нумератора и можем дальше его использовать.

Загрузка шаблона

Сначала необходимо загрузить шаблон. Весь код как в предыдущем примере, но другие входные данные и название метода:

documentgenerator.template.add

$data = [
	'fields' => [
		'name' => 'Rest Template',
		'file' => base64_encode(file_get_contents($_SERVER['DOCUMENT_ROOT'].'/upload/rest_template.docx')),
		'numeratorId' => 1,
		'region' => 'ru',
		'users' => ['UA'],
		'providers' => ['Bitrix\\DocumentGenerator\\DataProvider\\Rest'],
	],
];

$url = $webHookUrl.$prefix.'.template.add/';

Ответ

[result] => Array
	(
		[template] => Array
			(
				[id] => 203
				[name] => Rest Template
				[region] => ru
				[code] => 
				[download] => http://mycrm.bitrix24.com/bitrix/services/main/ajax.php?action=documentgenerator.template.download&id=203&ts=1539173306
				[active] => Y
				[moduleId] => rest
				[numeratorId] => 1
				[withStamps] => N
				[providers] => Array
					(
						[bitrix\documentgenerator\dataprovider\rest] => bitrix\documentgenerator\dataprovider\rest
					)

				[users] => Array
					(
						[UA] => UA
					)

				[isDeleted] => N
				[sort] => 500
				[createTime] => 2018-10-10T14:08:26+02:00
				[updateTime] => 2018-10-10T14:08:26+02:00
				[downloadMachine] => http://mycrm.bitrix24.com/rest/1/webhookkey/documentgenerator.template.download/?token=documentgenerator%7CYWN0a // тут длинная ссылка
			)

	)

Список полей

Проверим, что поля шаблона распознались правильно. Выполним метод documentgenerator.template.getfields:

$data = [
	'id' => 203,
	'providerClassName' => '\\Bitrix\\DocumentGenerator\\DataProvider\\Rest',
	'value' => 1,
];
$url = $webHookUrl.$prefix.'.template.getfields/';

Ответ

[result] => Array
	(
		[templateFields] => Array
			(
				[DocumentNumber] => Array
					(
						[title] => Номер
						[value] => 1
						[group] => Array
							(
								[0] => Документ
							)

						[default] => 1
					)
				[SomeDate] => Array
					(
						[value] => 
						[default] => 
					)
				[SomeName] => Array
					(
						[value] => 
						[default] => 
					)
				[Stamp] => Array
					(
						[value] => 
						[default] => 
					)
				[Image] => Array
					(
						[value] => 
						[default] => 
					)
				[TableItemImage] => Array
					(
						[value] => 
						[default] => 
					)
				[TableItemName] => Array
					(
						[value] => 
						[default] => 
					)
				[TableItemPrice] => Array
					(
						[value] => 
						[default] => 
					)
				[TableIndex] => Array
					(
						[value] => 
						[default] => 
					)
			)
	)

Как видим, все поля документа на месте.

Генерация простого документа

Если в документ необходимо вставить только простые текстовые данные, то надо в метод documentgenerator.document.add передать только массив values с текстовыми значениями:

$data = [
	'templateId' => 203,
	'providerClassName' => 'Bitrix\\DocumentGenerator\\DataProvider\\Rest',
	'value' => 1,
	'values' => [
		'SomeDate' => '14.02.2018',
		'SomeName' => 'Горелкин Владислав',
	],
];
$url = $webHookUrl.$prefix.'.document.add/';

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

Генерация документа с изображениями и печатями

Чтобы в документ передать сложные данные, не только в строковом формате, необходимо правильно сформировать параметр fields. Для начала, заполним изображение и печать.

$data = [
	'templateId' => 203,
	'providerClassName' => 'Bitrix\\DocumentGenerator\\DataProvider\\Rest',
	'value' => 1,
	'values' => [
		'SomeDate' => '14.02.2018',
		'SomeName' => 'Горелкин Владислав',
		'Stamp' => 'http://myrestapp.com/upload/stamp.png', // внешний путь к файлу печати
		'Image' => 'http://myrestapp.com/upload/image.jpg', // внешний путь к файлу изображения
	],
	'fields' => [
		'Stamp' => ['TYPE' => 'STAMP'], // тип поля - печать
		'Image' => ['TYPE' => 'IMAGE'], // тип поля - изображение
	]
];
$url = $webHookUrl.$prefix.'.document.add/';

В массиве fields можно указать тип поля, по ключу TYPE.

  • Для полей "Изображение" тип - STAMP
  • Для полей "Печать или подпись" тип - IMAGE

В массиве values в качестве значений необходимо указать абсолютный путь к файлу. Файл будет скачан по этому адресу и вставлен в документ.

Генерация документа с модификаторами даты и имени

Про сами модификаторы можно почитать здесь.

Использование модификаторов для дат и имён через REST не обязательно - входные данные могут быть заранее отформатированы самим приложением. Тем не менее, это может быть удобно. Поэтому в REST есть возможность использовать модификаторы. Для этого необходимо передать соответствующий тип поля в fields. Также в fields по ключу FORMAT можно передать формат по умолчанию. Если в самом шаблоне у этого поля будет указан модификатор - будет применен модификатор шаблона.

Дата

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

  • в values дата должна быть передана в формате atom (как во всех rest-методах)
  • в fields TYPE = DATE
  • также в fields по ключу FORMAT['format'] можно передать модификатор по умолчанию (также, как в шаблоне)

Имя

Чтобы модификаторы работали для полей типа имя необходимо передать их в следующем виде:

  • в values имя должно быть передано в виде массива

[
	'NAME' => 'Игорь', // имя
	'LAST_NAME' => 'Иванов', // фамилия
	'SECOND_NAME' => 'Петрович', // отчество
	'GENDER' => 'M', // пол
]

По ключу GENDER можно указать пол в явном виде (M - мужской, F - женский). Если пол не указан, то модуль попытается определить его по отчеству. Если отчество не указано - пол не будет определен и склонение не будет работать.

  • в fields TYPE = NAME
  • в fields по ключу FORMAT['format'] можно передать формат по умолчанию
  • в fields по ключу FORMAT['case'] можно передать падеж по умолчанию

$data = [
	'templateId' => 203,
	'providerClassName' => 'Bitrix\\DocumentGenerator\\DataProvider\\Rest',
	'value' => 1,
	'values' => [
		'SomeDate' => '2018-10-10T14:30:18+02:00', // значение передано в формате atom
		'SomeName' => [ // имя передано в виде массива
			'NAME' => 'Владислав',
			'LAST_NAME' => 'Горелкин',
			'GENDER' => 'M',
		],
	],
	'fields' => [
		'SomeDate' => [
			'TYPE' => 'DATE',
			'FORMAT' => [
				'format' => 'd f Y H:i', // формат вывода
			],
		], // тип поля - дата
		'SomeName' => [
			'TYPE' => 'NAME',
			'FORMAT' => [ // здесь можно передать формат поля по умолчанию
				'case' => 0, // код падежа
				'format' => '#NAME# #LAST_NAME#' // формат вывода
			]
		], // тип поля - имя
	]
];
$url = $webHookUrl.$prefix.'.document.add/';

Генерация документа с данными в виде массива

В нашем тестовом шаблоне есть таблица, куда надо вставить картинку, название и цену товара. Модификаторы для цен нельзя использовать в ресте генератора документов, поэтому цену придётся передавать в виде сформированной строки.

Ниже рабочий пример кода, после него подробности.

$data = [
	'templateId' => 203,
	'providerClassName' => '\\Bitrix\\DocumentGenerator\\DataProvider\\Rest',
	'value' => 1,
	'values' => [
		'Table' => [
			[
				'Name' => 'Item name 1',
				'Price' => '$111.23',
				'Image' => 'http://myrestapp.com/upload/stamp.png'
			],
			[
				'Name' => 'Item name 2',
				'Price' => '$222.34',
				'Image' => 'http://myrestapp.com/upload/stamp.png'
			],
		],
		'TableItemName' => 'Table.Item.Name',
		'TableItemImage' => 'Table.Item.Image',
		'TableItemPrice' => 'Table.Item.Price',
		'TableIndex' => 'Table.INDEX',
	],
	'fields' => [
		'Table' => [
			'PROVIDER' => 'Bitrix\\DocumentGenerator\\DataProvider\\ArrayDataProvider',
			'OPTIONS' => [
				'ITEM_NAME' => 'Item',
				'ITEM_PROVIDER' => 'Bitrix\\DocumentGenerator\\DataProvider\\HashDataProvider',
			],
		],
		'TableItemImage' => ['TYPE' => 'IMAGE'],
	],
];
$url = $webHookUrl.$prefix.'.document.add/';

Напоминаем, что в шаблон вставлена таблица, в таблице три поля {TableItemName}, {TableItemImage}, {TableItemPrice}. Для начала посмотрим, как заполняется массив полей fields.

  1. Передаем настройки поля Table. Такого поля в явном виде нет в шаблоне, но оно нам нужно, чтобы передать по этому ключу массив значений для таблицы.
  2. Для этого поля нужно обязательно указать провайдера fields['Table']['PROVIDER'] = 'Bitrix\\DocumentGenerator\\DataProvider\\ArrayDataProvider'. Таким образом мы указываем, что по этому ключу придёт массив значений.
  3. Надо заполнить массив настроек провайдера. fields['Table']['OPTIONS']['ITEM_NAME'] = 'Item'. Здесь мы передали внутренний ключ, по которому провайдер будет обращаться к элементам массива.
  4. fields['Table']['OPTIONS']['ITEM_PROVIDER'] = 'Bitrix\\DocumentGenerator\\DataProvider\\HashDataProvider' - здесь указывается, что каждый элемент массива поля Table по ключу Item - это простой хеш.
  5. Указываем, что поле TableItemImage является изображением - здесь всё как обычно.

Теперь про массив values.

  1. По ключу Table передаем простой массив (с индексными последовательными ключами). Каждый элемент массива - это ассоциативный массив, где ключ - это правая часть поля, за исключением Table (название поля-массива) и Item (название внутреннего ключа).
  2. В качестве значения для самих полей таблицы передаем цепочку получения значения из провайдера. Строится она как последовательные коды провайдеров, разделенные точкой. В нашем случае это будет Table - название поля-массива, откуда получаются значения. Потом точка. Дальше Item - название внутреннего ключа провайдера Table, по которому провайдер отдает элементы массива. Потом точка. Дальше идёт ключ внутреннего ассоциативного массива из элементов Table.
  3. У провайдера ArrayDataProvider есть внутренняя переменная INDEX, которая указывает на текущий номер элемента (начиная с 1). Чтобы в поле {TableIndex} внутри таблицы подставился порядковый номер, было указано values['TableIndex'] = 'Table.INDEX'.

Если указать в качестве значения поля обычную строку, то она вставится в таблицу как есть во все строки.

Копирование таблиц

Начиная с версии 18.7.200 модуля documentgenerator появилась возможность создавать документы с вложенными списками, т.е. когда одно из значений списка первого уровня - это ещё один список (Внимание: работает только через REST и PHP API, через интерфейс такое не сделать).

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

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

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

Пример для схемы Таблица внутри повторяющихся блоков
Пример для схемы Повторяющиеся блоки внутри повторяющихся блоков


Пользовательские комментарии

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

Для этого нужно всего лишь авторизоваться на сайте

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

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.
5
Андрей Гомзин
Сообщение не промодерировано, возможны ошибки и неточности.
Предупреждение для тех, кто решит делать сложный проект через REST API, используя конструкции, подобные "Таблица внутри повторяющихся блоков", которая описана выше.
Здесь есть не описанные ограничения! Я о них не знал и пожалел.
Обработка запроса генерации документов, идущего на облачный сервер Битрикс, очень тяжелая. Чем больше в шаблоне динамических данных, тем она тяжелее. В нашем проекте был полностью динамически формируемый документ с высокой вариативностью, из-за чего пришлось все делать такими конструкциями. И примерно при 3 конструкциях "Таблица внутри повторяющихся блоков", каждая из которых содержала примерно 3 таблицы (это было всего 5 страниц в текстовом документе), сервер Битрикса стал не справляться и выдавать ошибку INTERNAL_SERVER_ERROR, документ при этом не создается вообще.
То есть именно с обработкой этих запросов могут быть большие задержки, и можно неожиданно упереться в неописанное ограничение при относительно небольшом объеме документа. Решения у данной проблемы нет, кроме как использовать для генерации документов какую-то свою коробку вместо облака (там нет этих ограничений). В ТП заявка по проблеме есть, под номером 161135. Сервер Битрикса начинает отклонять запросы, когда не может выполнить их за 60 секунд. Через curl_getinfo можно отслеживать этот параметр для текущего запроса, чтобы понимать, где находится допустимая граница. Пример логов отклоненного запроса:
Код
Array
(
    [url] => ***
    [content_type] => application/json
    [http_code] => 500
    [header_size] => 207
    [request_size] => 187
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 61.514408 - если этот параметр приблизится к 60 секундам, запрос будет отклонен
    [namelookup_time] => 2.2E-5
    [connect_time] => 0.001021
    [pretransfer_time] => 0.00815
    [size_upload] => 111173
    [size_download] => 78
    [speed_download] => 1
    [speed_upload] => 1807
    [download_content_length] => 78
    [upload_content_length] => 111173
    [starttransfer_time] => 0.010474
)
© «Битрикс», 2001-2024, «1С-Битрикс», 2024