Движок JP — быстрое создание PDF в браузерах

01.07.2021

Создание различных макетов на основе данных — самая частая операция при работе с шаблонами. Так почему бы не создавать эти макеты автоматически и прямо в браузере?

Если есть описание макета и многочисленные данные, то зачем заниматься рутиной? Зачем получать постоянные правки об ошибках?

Вам не будет нужна лицензия на продукты Адоба, чтобы создавать многочисленные макеты нажатием кнопки, загружая данные из Гугл-таблиц.

JP — это написанные на JavaScript классы и методы, которые выполняют всю рутину при создании PDF-файлов.

Внутри движка реализовано:

  • единый формат записи цветов: RGB и CMYK;
  • единый формат позиций объектов (абсолютные и относительные);
  • единый формат размеров (абсолютные и относительные);
  • простое добавление текстовых элементов с выравниванием и несколькими стилями в одной строке;
  • добавление текстов как в виде текстовых блоков, так и в «кривых»;
  • простое рисование элементарных форм или по массиву кривых Безье;
  • раскрашивание текстов и форм согласно шаблонам;
  • настройка макета: радиусы скругления каждого из углов, цвет фона;
  • простое подключение Google-таблиц для генерации сразу нескольких макетов;
  • постоянное развитие возможностей движка за счет новых ситуаций при создании макетов;
  • наличие скриптов и экстеншенов для Adobe Illustrator, чтобы экспортировать макет в веб-интерфейс;
  • подробная документация.

Шаблон — это стандартизованный набор параметров, который хранит настройки всего макета и всех его элементов.

Все элементы макета имеют свои уникальные ключи — slug, по которым происходит применение свойств.

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

Например, все тексты по умолчанию чёрные, выровненные по левому краю и позиционируются по нижней линии букв.

Шаблоны бывают 2 типов: глобальный шаблон и шаблон конкретного макета.

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

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

Документация обновляется. Тут пока ничего не понятно 😜

Условия шаблонов:

  • ключи текстовых блоков и форм (векторов) должны быть уникальными (латиница без пробелов с цифрами не в начале имени).

Пример шаблона

Здесь 2 текстовых блока и 1 форма (вектор). Сначала рисуется текст «names» (у него внутри тексты 2-х стилей: «nameFirst» и «nameSecond»), потом относительно него рисуется форма (вектор) «logo», и потом относительно него — текст «number».

Описание стилей хранятся в шаблоне в 2 параметрах объекта data:

  • textFrames — текстовые блоки,
  • paths — формы (векторы).

В примере ниже рисование формы (вектора) хранится во внешнем методе extraNumber(), который не описан в документации.

Порядок элементов в data.textFrames и в data.paths не важен, так как движок рисует сначала объекты с абсолютными позициями, а потом относительные них. Относительность может быть вложенной (как в примере).

const TEMPLATE = {
    background: {                                             // параметры фона
        cornerRadius: {                                       // Object, радиусы скругления углов макета
            leftTop: 15,                                      // Number, левый верхний угол
            rightTop: 15,                                     // Number, правый верхний угол
            rightBottom: 15,                                  // Number, правый нижний угол
            leftBottom: 15,                                   // Number, левый нижний угол
        },
        fillColor: new JPColor(50, 45, 20, 0),                // цвет заливки фона
    },
    size: {                                                   // размер макета
        width: 480,                                           // Number, фиксированная ширина (мм)
        height: 320,                                          // Number, фиксированная высота (мм)
    },
    previewScale: 0.25,                                       // Number, масштаб превью шаблона

    data: {                                                   // элементы шаблона
        textFrames: {                                         // текстовые блоки
            'names': {                                        // ключ текстового блока
                position: new JPPosition(54, 54),             // JPPosition, позиция (x, y)
                textStyles: {                                 // стили внутри текстового блока
                    'nameFirst': {                            // String, ключ стиля
                        size: 176,                            // Number, размер текста
                        fontStyle: JP_FONT_STYLE.BOLD,        // String, начертание шрифта — ссылка на константы
                        fillColor: JP_COLOR.BLUE,             // JPColor, цвет — ссылка на константы
                        baselineShift: 58,                    // Number, вертикальное смещение букв
                        tracking: 25,                         // Number, трекинг
                    },
                    'nameSecond': {
                        size: 140,                            // Number, размер текста
                        fontStyle: JP_FONT_STYLE.MEDIUM,      // String, начертание шрифта — ссылка на константы
                    },
                },
                'number': {                                   // ключ текстового блока
                    position: new JPPosition(72, 31),         // JPPosition, позиция
                    paragraphAlign: JPParagraphAlign.center,  // String, выравнивание текстового блока (ссылка на объект с ключами)
                    style: {                                  // один стиль для всех текстов внутри текстового блока
                        size: 170,                            // Number, размер шрифта
                        fontStyle: JP_FONT_STYLE.REGULAR,     // String, начертание шрифта — ссылка на константы
                    },
                    anchor: {                                 // относительно кого рисуется (по умолчанию - документ)
                        slug: 'arrow',                        // String, ключ объекта, относительно которого рисуется
                    },
                },
            }
        },
        paths: {                                              // формы (векторы)
            'logo': {                                         // ключ формы (вектора)
                extraMethodName: 'extraNumber',               // String, имя метода, который рисует форму
                fillColor: JP_COLOR.BLUE,                     // JPColor, цвет — ссылка на константы
                position: new JPPosition(-20, -44),           // JPPosition, позиция (x, y) относительна снизу и справа
                size: {                                       // размер формы (вектора)
                    width: 84.232,                            // Number, ширина (высота будет подобрана пропорциональна)
                },
                anchor: {                                     // относительно чего рисуется (по умолчанию — документ)
                    slug: 'names',                            // String, ключ объекта, относительно которого рисуется
                },
            },
        },
    }
}

Этапы создания PDF:

const jpTemplate = new JPTemplate(TEMPLATE)                         // создаём jp-шаблон из объекта
const jpDocument = new JPDocument(jpTemplate)                       // создаём jp-документ на основе шаблона
jpDocument.createTextFrameFromString('123-45-67', 'number')         // создаём текстовый блок с ключом «number» из строки
jpDocument.addPath('logo')                                          // добавляем форму (вектор) с ключом «logo»
jpDocument.buildDocument()                                          // создаём pdf-документ
jpDocument.download('Example1.pdf')                                 // скачиваем файл под именем «Example1.pdf»

Если у вас есть желание сделать генератор табличек для своих нужд: адресные таблички, макеты по шаблонам — пишите на электронную почту.