Generated Document Examples
This article contains full process of document generation. All examples are written in PHP via webhook.
Creating a numerator
First, let's create a new REST numerator via 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);
Response
[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] => ) ) ) )
Response gets the numerator id
available for use.
Template upload
First, upload a template. The complete code is the same as in previous example, but with different input data and method name:
documentgenerator.template.add
$data = [ 'fields' => [ 'name' => 'Rest Template', 'file' => base64_encode(file_get_contents($_SERVER['DOCUMENT_ROOT'].'/upload/rest_template.docx')), 'numeratorId' => 1, 'region' => 'en', 'users' => ['EN'], 'providers' => ['Bitrix\\DocumentGenerator\\DataProvider\\Rest'], ], ]; $url = $webHookUrl.$prefix.'.template.add/';
Response
[result] => Array ( [template] => Array ( [id] => 203 [name] => Rest Template [region] => en [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 // URL string here ) )
List of fields
Check if template fields were recognized correctly. Execute the method documentgenerator.template.getfields
:
$data = [ 'id' => 203, 'providerClassName' => '\\Bitrix\\DocumentGenerator\\DataProvider\\Rest', 'value' => 1, ]; $url = $webHookUrl.$prefix.'.template.getfields/';
Response
[result] => Array ( [templateFields] => Array ( [DocumentNumber] => Array ( [title] => Number [value] => 1 [group] => Array ( [0] => Document ) [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] => ) ) )
As we see, all document fields are retrieved correctly.
Generating simple document
In case when only simple text data must ne inserted into a document, only the array values
with the text values must be passed into the method documentgenerator.document.add
as follows:
$data = [ 'templateId' => 203, 'providerClassName' => 'Bitrix\\DocumentGenerator\\DataProvider\\Rest', 'value' => 1, 'values' => [ 'SomeDate' => '14.12.2018', 'SomeName' => 'John Smith', ], ]; $url = $webHookUrl.$prefix.'.document.add/';
The example above is the simplest one. Now let's review the variant, when we need to insert images, stamp, use modifier for date and time and fill in several values
Generating document with images and stamps
To pass complex data in the document not only in the string format, the parameter fields
must be generated correctly. First, specify an image and stamp.
$data = [ 'templateId' => 203, 'providerClassName' => 'Bitrix\\DocumentGenerator\\DataProvider\\Rest', 'value' => 1, 'values' => [ 'SomeDate' => '14.12.2018', 'SomeName' => 'John Smith', 'Stamp' => 'http://myrestapp.com/upload/stamp.png', // external path to stamp file 'Image' => 'http://myrestapp.com/upload/image.jpg', // external path to image file ], 'fields' => [ 'Stamp' => ['TYPE' => 'STAMP'], // field type - stamp 'Image' => ['TYPE' => 'IMAGE'], // field type - image ] ]; $url = $webHookUrl.$prefix.'.document.add/';
The array fields
can specify type of field, by the key TYPE
.
- For "Image" type fields -
STAMP
- For "Stamp or signature" type fields -
IMAGE
The array values
must specify absolute path to file as value. The file will be downloaded via this address and inserted into document.
Document generation with date and name modifier
There is no requirement to use modifiers for dates and names via REST - input data can be pre-formatted by the app itself. However, it can be convenient. That's why REST has the modifier feature. To use it, pass corresponding field type in fields
. Also, default format can be passed in the fields
by the key FORMAT
. If the template field has a specified modifier - template modifier will be applied.
For modifiers to work for date type fields, pass them in the following format:
- Date must be passed in atom format in
values
(applies to all REST methods) - in
fields
TYPE
=DATE
- also, default modifier can be passed in
fields
by the keyFORMAT['format']
(the same as for the template)
For modifiers to work for name type fields, pass them i the following format :
- name must be passed un
values
as an array
[ 'NAME' => 'John', // name 'LAST_NAME' => 'Smith', // last name 'SECOND_NAME' => 'William', // middle name 'GENDER' => 'M', // gender ]
Gender can be specified explicitly by the key GENDER
(M
- male, F
- female). If gender is not specified, the module attempts to determine it by the second name. If second name is not specified - gender will not be defined and case inflection will not be applicable.
- in
fields
TYPE
=NAME
- default format can be passed in
fields
by the keyFORMAT['format']
- default case can be passed in
fields
by the keyFORMAT['case']
$data = [ 'templateId' => 203, 'providerClassName' => 'Bitrix\\DocumentGenerator\\DataProvider\\Rest', 'value' => 1, 'values' => [ 'SomeDate' => '2018-10-10T14:30:18+02:00', // value passed in atom format 'SomeName' => [ // name passed as an array 'NAME' => 'John', 'LAST_NAME' => 'Smith', 'GENDER' => 'M', ], ], 'fields' => [ 'SomeDate' => [ 'TYPE' => 'DATE', 'FORMAT' => [ 'format' => 'd f Y H:i', // display format ], ], // field type - date 'SomeName' => [ 'TYPE' => 'NAME', 'FORMAT' => [ // default field format can be passed here 'case' => 0, // case code 'format' => '#NAME# #LAST_NAME#' // display format ] ], // field type - name ] ]; $url = $webHookUrl.$prefix.'.document.add/';
Document generation with data as an array
The test template contains table to insert an image, name and product price. Modifiers for prices cannot be used in document generator REST, that's why the price will have to be passed as generated string.
Below is the working example of code with following details.
$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/';
Keep in mind that the template contains a table that has three fields {TableItemName}, {TableItemImage}, {TableItemPrice}. First, let's review how array of fields fields
is filled.
- Pass the
Table
field configuration. Template does not have such field, but its needed to pass array of values via this key for the table. - The provider
fields['Table']['PROVIDER'] = 'Bitrix\\DocumentGenerator\\DataProvider\\ArrayDataProvider'
must be specified for this field. This is done to indicate that this key will pass an array of values. - Provider settings must be configured:
fields['Table']['OPTIONS']['ITEM_NAME'] = 'Item'
. Internal key was passed here to be used by provider to request elements of array. fields['Table']['OPTIONS']['ITEM_PROVIDER'] = 'Bitrix\\DocumentGenerator\\DataProvider\\HashDataProvider'
- specifies that each element of field arrayTable
by the keyItem
- its a simple cache.- Specify that field
TableItemImage
is an image.
The details on the array values
.
- Pass an empty array in the key
Table
(with index sequential keys). Each array element - is an associative array, where the key - is the right portion of the field, except forTable
(name of field-array) andItem
(name of internal key). - The chain to get value must be passed from provider as the value for the table fields themselves. This chain is built of sequential provider codes, split by a period. In this instance, the chain will be
Table
- name of field-array used to get values. Then, a period. After that -Item
- name of internal provider keyTable
, used by provider to pass elements of array. Then, a period. Next, a key of internal associative array ofTable
elements. - The provider
ArrayDataProvider
has an internal variableINDEX
that indicates the current No. of element (starting from 1). For the index number to be indicated inside the field {TableIndex}, thevalues['TableIndex'] = 'Table.INDEX'
was specified.
To specify a usual string as a field value, it will be inserted in the table as is in all strings.
Copying tables
Starting from version 18.7.200, the Documentgenerator module offers an option of creating documents with inserted lists, i. e. when one of the first level list values - is another list itself (Attention: can work only via REST and PHP API, this feature cannot be used via UI).
It can be useful when you must insert several tables with the same structure, but with different numbers of strings.
Main reason for this feature is that a first level list must pass field names as values for internal lists. All descriptions and field values must be passed at once. Fields array must contain external list as the first (due to the fields processing in the same sequence as they are passed in the description)
This method can be used in such structural layouts as Table inside repeating blocks or Repeated blocks inside repeated blocks; however a table cannot be inserted inside another table.
Example:Upload a template via the method documentgenerator.template.add.
Then, you can create a
document
Example of document contents:
, containing two tables. Input data example:
// Description of values 'values' => [ 'Title' => 'Welcome to my template', 'Description' => '<b>Description is here</b>', 'Picture' => null, // you can put here link to an image 'Events' => [ [ 'Title' => 'Automation', 'Description' => 'Some description of the automation event', 'SpeakerName' => '{Event1SpeakersSpeakerName}', 'SpeakerCompany' => '{Event1SpeakersSpeakerCompany}', 'SpeakerPosition' => '{Event1SpeakersSpeakerPosition}', ], [ 'Title' => 'Documents', 'Description' => 'This event is about document procession', 'SpeakerName' => '{Event2SpeakersSpeakerName}', 'SpeakerCompany' => '{Event2SpeakersSpeakerCompany}', 'SpeakerPosition' => '{Event2SpeakersSpeakerPosition}', ], ], 'EventsEventTitle' => 'Events.Event.Title', 'EventsEventDescription' => 'Events.Event.Description', 'EventsEventSpeakerName' => 'Events.Event.SpeakerName', 'EventsEventSpeakerCompany' => 'Events.Event.SpeakerCompany', 'EventsEventSpeakerPosition' => 'Events.Event.SpeakerPosition', 'Event1SpeakersSpeakerName' => 'Event1Speakers.Speaker.Name', 'Event1SpeakersSpeakerCompany' => 'Event1Speakers.Speaker.Company', 'Event1SpeakersSpeakerPosition' => 'Event1Speakers.Speaker.Position', 'Event1Speakers' => [ [ 'Name' => 'Roger Davis', 'Company' => 'Cool Ltd.', 'Position' => 'Core developer', ], [ 'Name' => 'Miles Harrington', 'Company' => 'Cool Ltd.', 'Position' => 'Product Manager', ], ], 'Event2Speakers' => [ [ 'Name' => 'John Smith', 'Company' => 'Vanguard corp.', 'Position' => 'Chief', ], ], 'Event2SpeakersSpeakerName' => 'Event2Speakers.Speaker.Name', 'Event2SpeakersSpeakerCompany' => 'Event2Speakers.Speaker.Company', 'Event2SpeakersSpeakerPosition' => 'Event2Speakers.Speaker.Position', ]
// Description of fields 'fields' => [ 'Events' => [ 'PROVIDER' => 'Bitrix\\DocumentGenerator\\DataProvider\\ArrayDataProvider', 'OPTIONS' => [ 'ITEM_NAME' => 'Event', 'ITEM_PROVIDER' => 'Bitrix\\DocumentGenerator\\DataProvider\\HashDataProvider', ], ], 'Event1Speakers' => [ 'PROVIDER' => 'Bitrix\\DocumentGenerator\\DataProvider\\ArrayDataProvider', 'OPTIONS' => [ 'ITEM_NAME' => 'Speaker', 'ITEM_PROVIDER' => 'Bitrix\\DocumentGenerator\\DataProvider\\HashDataProvider', ], ], 'Event2Speakers' => [ 'PROVIDER' => 'Bitrix\\DocumentGenerator\\DataProvider\\ArrayDataProvider', 'OPTIONS' => [ 'ITEM_NAME' => 'Speaker', 'ITEM_PROVIDER' => 'Bitrix\\DocumentGenerator\\DataProvider\\HashDataProvider', ], ], 'Event1SpeakersSpeakerName' => ['TITLE' => 'Event1SpeakersSpeakerName'], 'Event1SpeakersSpeakerCompany' => ['TITLE' => 'Event1SpeakersSpeakerCompany'], 'Event1SpeakersSpeakerPosition' => ['TITLE' => 'Event1SpeakersSpeakerPosition'], 'Event2SpeakersSpeakerName' => ['TITLE' => 'Event2SpeakersSpeakerName'], 'Event2SpeakersSpeakerCompany' => ['TITLE' => 'Event2SpeakersSpeakerCompany'], 'Event2SpeakersSpeakerPosition' => ['TITLE' => 'Event2SpeakersSpeakerPosition'],