Генератор документов

Этот онлайн генератор позволяет загрузить шаблон документа в виде OpenOffice Document File (odt) файла, со включенными в него Handlebars шаблонами, и сгенерировать итоговый документ по введенным в формате JSON данным.

Под генератором находится инструкция по созданию документов-шаблонов.

PLANETCALC, Генератор документов OpenOffice/LibreOffice с использованием Handlebars шаблонов

Генератор документов OpenOffice/LibreOffice с использованием Handlebars шаблонов

Шаблон документа (файл .odt)
  • Перетащите сюда файлы
Документ (файл .odt)
 

Введение

Данный генератор предназначен для упрощения создания текстовых документов ("вордовских" документов) на основе каких-либо данных. Когда это может пригодиться? По сути есть два варианта:

  1. Вам нужно часто генерировать однотипные документы по похожим данным. Если документ, например, многостраничный, открывать незаполненный шаблон и пролистывать страницу за страницей, меняя содержание в отдельных местах, не очень удобно. Кроме того, Вы можете случайно пропустить места, которые нужно было заполнить. Используя генератор, вы готовите шаблон, где прописываете все поля, которые должны быть заполнены. Данные для заполнения готовятся отдельно (в данном случае в формате JSON, хотя возможны варианты, об этом отдельно). Генератор берет данные и заполняет ими шаблон, генерируя заполненный документ.
  2. Вам нужно сгенерировать много повторяющихся страниц для какого-либо массива данных. Предположим, вам нужно сделать 25 страниц с приглашением на вечеринку или день рождения для 25 гостей, причем приглашения должны быть именными. Вы готовите шаблон, в который включаете операцию повторения содержимого. Данные также готовятся отдельно, и содержат в себе массив с информацией. Генератор берет данные и заполняет ими шаблон, повторяя размеченное содержимое.

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

В качестве документа шаблона используется документ OpenOffice Document, файл с расширением odt. Это формат текстового документа, аналогичного документам docx. Формат открывается как OpenOffice/LibreOffice Writer, так и Microsoft Word, причем обе программы поддерживают конвертацию между odt и docx. Формат является открытым, с известной структурой, что и позволило приспособить его для автоматической обработки. Создание шаблона заключается в добавление в odt документ разметки двух типов:

  1. Разметка для места, где нужно вставить значение из данных
  2. Разметка начала и конца участка, который нужно повторить для каждого элемента из массива данных.

Использовать для добавления такой разметки нужно 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
Добавление поля call

Заменив "Дорогой" на {{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 Строка таблицы

Ссылка скопирована в буфер обмена
PLANETCALC, Генератор документов

Комментарии