Генератор документов
Этот онлайн генератор позволяет загрузить шаблон документа в виде OpenOffice Document File (odt) файла, со включенными в него Handlebars шаблонами, и сгенерировать итоговый документ по введенным в формате JSON данным.
Под генератором находится инструкция по созданию документов-шаблонов.
Введение
Данный генератор предназначен для упрощения создания текстовых документов ("вордовских" документов) на основе каких-либо данных. Когда это может пригодиться? По сути есть два варианта:
- Вам нужно часто генерировать однотипные документы по похожим данным. Если документ, например, многостраничный, открывать незаполненный шаблон и пролистывать страницу за страницей, меняя содержание в отдельных местах, не очень удобно. Кроме того, Вы можете случайно пропустить места, которые нужно было заполнить. Используя генератор, вы готовите шаблон, где прописываете все поля, которые должны быть заполнены. Данные для заполнения готовятся отдельно (в данном случае в формате JSON, хотя возможны варианты, об этом отдельно). Генератор берет данные и заполняет ими шаблон, генерируя заполненный документ.
- Вам нужно сгенерировать много повторяющихся страниц для какого-либо массива данных. Предположим, вам нужно сделать 25 страниц с приглашением на вечеринку или день рождения для 25 гостей, причем приглашения должны быть именными. Вы готовите шаблон, в который включаете операцию повторения содержимого. Данные также готовятся отдельно, и содержат в себе массив с информацией. Генератор берет данные и заполняет ими шаблон, повторяя размеченное содержимое.
Подготовка документа шаблона
В качестве документа шаблона используется документ OpenOffice Document, файл с расширением odt. Это формат текстового документа, аналогичного документам docx. Формат открывается как OpenOffice/LibreOffice Writer, так и Microsoft Word, причем обе программы поддерживают конвертацию между odt и docx. Формат является открытым, с известной структурой, что и позволило приспособить его для автоматической обработки. Создание шаблона заключается в добавление в odt документ разметки двух типов:
- Разметка для места, где нужно вставить значение из данных
- Разметка начала и конца участка, который нужно повторить для каждого элемента из массива данных.
Использовать для добавления такой разметки нужно LibreOffice Writer. В качестве языка разметки используется язык Handlebars.
Разметка для места, где нужно вставить значение из данных
Для добавления такой разметки откройте документ в LibreOffice Writer. Поставьте курсор в место, куда должны попасть данные. Выберите в меню "Вставка" - "Поле" - "Ещё поля". В открывшемся окне "Поля" на вкладке "Функции" в списке "Тип" выберите "Поле ввода", в поле "Подсказка" (справа) введите handlebars.
Нажмите "Вставить". В окне "Проверка полей" введите выражение в handlebars формате, например, {{text}}.
Нажмите "ОК", нажмите "Закрыть". Документ должен выглядеть следующим образом:
Вы создали минимальный шаблон. Этот шаблон предполагает следующую структуру данных:
{
"text": "Что-то для вставки в шаблон"
}
Теперь можно использовать генератор, загрузив в него шаблон и данные:
Генератор создаст итоговый документ processed.template1.odt, где поле ввода {{text}} будет заменено на текст Что-то для вставки в шаблон.
Разметка начала и конца участка, который нужно повторить для каждого элемента из массива данных
Данная разметка нужна для повторяющихся данных. Предположим, у нас есть следующая структура данных:
{
"guests": [
{ "name": "Сергей", "call": "Дорогой"},
{ "name": "Мария", "call": "Дорогая"}
]
}
Нам нужно сгенерировать какое-то содержимое для каждого элемента из списка guests. Для этого мы будет использовать Handlebars блок #each (это единственный блок, который поддерживается генератором). В шаблон документа надо добавить разметку начала и конца блока.
Рассмотрим три примера:
Повторение абзаца текста
Предположим, что мы хотим "размножить" на всех гостей следующий абзац текста:
Для добавления разметки начала блока поставьте курсор внутрь абзаца, который вы хотите повторить. Выберите в меню "Вставка" - "Сценарий". В открывшемся окне в поле "Тип сценария" введите handlebars. В поле текст введите
@text:p
{{#each guests}}
Для добавления разметки конца поставьте курсор внутрь абзаца, который вы хотите повторить, после сценария начала блока. Выберите в меню "Вставка" - "Сценарий". В открывшемся окне в поле "Тип сценария" введите handlebars. В поле текст введите
@/text:p
{{/each}}
Обратите внимание, что сценарии, добавляемые выше должны содержать две строки. Первая строка начинается с символа @ - это так называемый селектор начала и конца повторяемого участка, вторая - описывает начало и конец блока #each соответственно.
Абзац, содержащий сценарии начала и конца блока повторяется в контексте массива guests. Внутри абзаца вы можете ссылаться на поля повторяемого объекта через механизм полей, рассмотренный выше. Поэтому после вставки поля, в окне "Проверка полей", можно использовать выражения {{call}} и {{name}}.
Заменив "Дорогой" на {{call}} и "Имярек" на {{name}} мы получим финальный шаблон для повтора абзаца:
Используем шаблон в генераторе
Генератор создаст итоговый документ processed.template2.odt, с повторяющимися абзацами.
Повторение элемента списка
Предположим, что мы хотим "размножить" на всех гостей следующий элемент списка:
Для добавления разметки начала блока поставьте курсор внутрь элемента списка, который вы хотите повторить. Выберите в меню "Вставка" - "Сценарий". В открывшемся окне в поле "Тип сценария" введите handlebars. В поле текст введите
@text:list-item
{{#each guests}}
Для добавления разметки конца поставьте курсор внутрь элемента списка, который вы хотите повторить, после сценария начала блока. Выберите в меню "Вставка" - "Сценарий". В открывшемся окне в поле "Тип сценария" введите handlebars. В поле текст введите
@/text:list-item
{{/each}}
Отличие от примера с абзацем в другой первой строке. Для абзаца это была @text:p, для элемента списка - @text:list-item. Это уже упомянутые выше селекторы начала и конца повторяемого участка документа. Интересующиеся техническими подробностями могут прочитать про селекторы, а также о том, как работает генератор, в конце статьи.
Далее аналогично предыдущему примеру редактируем элемент списка со сценариями, заменяя "Дорогой" и "Имярек" на поля {{call}} и {{name}}.
Получается финальный шаблон для повтора списка:
Используем шаблон в генераторе
Генератор создаст итоговый документ processed.template2.odt, с повторяющимся списком.
Повторение строк таблицы
Предположим, что мы хотим заполнить следующую таблицу:
Для добавления разметки начала блока поставьте курсор в любое место строки таблицы, которую вы хотите повторить (внутрь любой ячейки). Выберите в меню "Вставка" - "Сценарий". В открывшемся окне в поле "Тип сценария" введите handlebars. В поле текст введите
@table:table-row
{{#each guests}}
Для добавления разметки конца поставьте курсор в любое место строки таблицы, которую вы хотите повторить, после сценария начала блока. Выберите в меню "Вставка" - "Сценарий". В открывшемся окне в поле "Тип сценария" введите handlebars. В поле текст введите
@/table:table-row
{{/each}}
И опять, отличие от примера с абзацем или списком в другой первой строке. Для строки таблицы это @table:table-row.
Далее аналогично предыдущим примерам редактируем строку со сценариями, заменяя в ячейках таблицы "Дорогой" и "Имярек" на поля {{call}} и {{name}}.
Получается финальный шаблон для повтора строки таблицы:
Используем шаблон в генераторе и получаем итоговый документ:
Примечание: разметка начала и конца блока не обязательно должна ограничиваться одним абзацем или элементом списка, или строкой таблицы. Будет повторены все соответствующие элементы, попавшие между сценарием начала и сценарием конца блока. Например, если сценарий конца абзаца стоит в конце второго абзаца после абзаца со сценарием начала, то будут повторены два абзаца. Тоже самое относится и к элементам списка - можно повторить сразу несколько, и к строкам таблицы - можно повторить две или более строк сразу - от строки со сценарием начала, до строки со сценарием конца блока включительно.
Расширение функциональности
Калькулятор на этой странице представляет собой скорее образец, демонстрирующий технологию, чем что-то, пригодное к употреблению. Вряд ли можно ожидать от обычного пользователя, что он будет формировать JSON для объединения с разметкой документа. JSON, скорее всего, должен формировать программист (также как и шаблон документа, который надо будет сделать один раз вручную), при помощи кода, обрабатывающего данные, вносимые пользователем в какую-либо форму. Форму для ввода данных можно создать в виде калькулятора на этом же сайте.
То есть полезное применение технологии видится следующим образом:
- Программист создает форму ввода данных в виде калькулятора и разрабатывает odt-документ шаблон под эту форму.
- Пользователь заполняет форму и подгружает шаблон.
- Код калькулятора по данным формы формирует JSON и объединяет его с загруженным шаблоном, генерируя итоговый документ.
Обратите внимание, что JSON может быть представлять собой что-то более сложное, чем простой набор полей, соответствующих полям формы. Например, он может высчитывать какие-то агрегатные значения по введенным данным (например, сумму по строкам таблицы) и использовать их в шаблоне. Пользователю на форме надо будет вводить меньше данных, что удобнее.
В качестве примера калькулятора, по данным формы формирующего JSON для шаблона документа, можно привести Генератор рабочей программы дисциплины (РПД) для высших учебных заведений.
Технические подробности
Селектор
Что такое селектор? Дело в том, что документ odt является zip-архивом, внутри которого, в том числе, лежит xml-файл с содержимым документа content.xml. Документ, таким образом, имеет определенную структуру, описанную деревом xml-тегов. Например, текст отдельного абзаца в odt файле размечается примерно таким образом
<text:p>Это текст абзаца</text:p>
Что определить границы повторяемого участка, первая строка сценария должна указать тег. Калькулятор во время обработки документа будет искать ближайший тег данного типа выше по xml-дереву. Та же логика применяется для определения границы конца повторяемого участка.
Рассмотрим пример. Предположим, мы создали шаблон, в котором часть текста размечена следующим образом:
<text:p text:style-name="P9">First paragraph
<text:script script:language="handlebars">@text:p
{{#each guests}}</text:script>
<text:span text:style-name="T5">
<text:text-input text:description="handlebars">{{name}}</text:text-input>
</text:span>
</text:p>
<text:p text:style-name="P10">
<text:span text:style-name="T3">Yet another paragraph </text:span>
<text:span text:style-name="T4">
<text:script script:language="handlebars">@/text:p
{{/each}}</text:script>
</text:span>
</text:p>
Сценарий начала участка занимает строки 2 и 3. Он сообщает калькулятору, что для определения начала участка надо искать тег text:p, и в данном случае это тег на строке 1. Сценарий конца участка занимает строки 11 и 12. Он также сообщает калькулятору, что конец участка - это ближайший тег text:p, в данном случае тег на строке 8. То есть повторяемый участок это все строки с 1 по 14 включительно.
Если загрузить этот шаблон в калькулятор, и объединить со следующими данными:
{
"guests": [
{ "name": "John" },
{ "name": "Jane" }
]
}
то результат будет выглядеть так:
<text:p text:style-name="P9">First paragraph
<text:span text:style-name="T5">
John
</text:span>
</text:p>
<text:p text:style-name="P10">
<text:span text:style-name="T3">Yet another paragraph </text:span>
<text:span text:style-name="T4"/>
</text:p>
<text:p text:style-name="P9">First paragraph
<text:span text:style-name="T5">
Jane
</text:span>
</text:p>
<text:p text:style-name="P10">
<text:span text:style-name="T3">Yet another paragraph </text:span>
<text:span text:style-name="T4"/>
</text:p>
Поле из шаблона (строка 5 в предыдущей разметке), было заменено на значения John и Jane в строках 3 и 12, то есть шаблон был повторен два раза.
Типовые селекторы
В большинстве случаев в документе вы захотите повторить либо абзацы текста, либо элементы списка, либо строки таблицы. Селекторы для этих элементов документа приведены в таблице ниже:
Селектор | Элемент документа |
---|---|
@text:p | Абзац |
@text:list-item | Элемент списка |
@table:table-row | Строка таблицы |
Комментарии