Основное назначение — решение проблемы создания PDF из HTML и контроль пагинации. С его помощью можно легко создавать высококачественные PDF-файлы.
Зависимые библиотеки JavaScript: polyfill, jquery, lodash, bookjs-eazy.
Преимущества:
Недостатки:
Ещё один новый случай:
Случай счёта-фактуры:
Таблица: объединение ячеек. Пример ссылки: eazy-6.html.
Скачайте или клонируйте проект, перейдите в командную строку в каталог проекта. Запустите ./docker-start.sh или docker-start.bat. Вы можете получить доступ к демо через браузер http:// 127.0.0.1:3000/eazy-1.html, распечатать и создать PDF. Попробуйте написать собственную страницу PDF в каталоге dist.
Механизм рендеринга:
Поместите элементы содержимого PDF-страницы под узел body>#content-box (см. раздел «Дизайн содержимого PDF»).
Программа не начнёт рендеринг содержимого узла #content-box в стиле PDF до тех пор, пока значение глобальной переменной window.bookConfig.start не станет истинным (см. параметры конфигурации страницы). Важно: если ваша страница динамическая, сначала установите значение по умолчанию в false, а затем установите в true, когда содержимое будет готово.
Принцип обнаружения переполнения высоты страницы: узел содержимого страницы. nop-page-content является узлом контейнера с эластичной высотой. Добавление содержимого на страницу приводит к изменению высоты узла контейнера. Чтобы вычислить, произошло ли переполнение страницы, её получают путём вычисления высоты. Примечание: а. display: float, position: absolute; Вставка элементов с переполнением стиля не изменяет высоту контейнера страницы. Может привести к тому, что переполнение страницы останется незамеченным.
B потому что элементы стиля поля не могут быть растянуты. Размер nop-page-content, приводящий к смещению позиции nop-page-content, может легко вызвать явление переполнения страницы, поэтому по возможности контролируйте относительное положение и используйте заполнение.
Настройка параметров страницы:
<script>
bookConfig = {
// ! ! Важно! ! Важно!
// Когда это значение истинно, начинается рендеринг страницы. Если ваша страница динамическая,
// сначала установите для этого значения значение false, а затем установите его в true после того, как содержимое узла #content-box в следующем разделе будет готово
// **Готово** означает, что все html-рендеринг завершен. Например: есть несколько асинхронных запросов, есть диаграммы и т.д. Ссылка: eazy-1.html
// bookConfig.start = true; // Запустить рендеринг bookjs, дифференциальная страница.
// Все остальные параметры, кроме этого элемента конфигурации, являются необязательными! ! !
start : true
/**Все типы бумаги, полностью не протестированы, обычно используются ISO_A4
ISO_A0, ISO_A1, ISO_A2, ISO_A3, ISO_A4, ISO_A5
ISO_B0, ISO_B1, ISO_B2, ISO_B3, ISO_B4, ISO_B5, ISO_B6, ISO_B7, ISO_B8, ISO_B9, ISO_B10
ISO_C0, ISO_C1, ISO_C2, ISO_C3, ISO_C4, ISO_C5, ISO_C6, ISO_C7, ISO_DL, ISO_C7_6
JIS_B0, JIS_B1, JIS_B2, JIS_B3, JIS_B4, JIS_B5, JIS_B6, JIS_B7, JIS_B8, JIS_B9
NA_LEGAL, NA_LETTER, NA_LEDGER, NA_EXECUTIVE, NA_INVOICE,
BIG_K32
* */
// Определяем размер бумаги, два способа, необязательно, по умолчанию: ISO_A4
pageSize : 'ISO_A4 ',
orientation : 'landscape', // определение бумаги по вертикали/горизонтали экрана
/**pageSizeConfig и pageSize/orientation комбинации, просто выберите один * */
pageSizeOption : {
width : '15cm', // пользовательская ширина и высота
height : '20cm ',
}
// необязательно, поля, перечисленные варианты являются значениями по умолчанию
padding : "31.8mm 25.4mm 31.8mm 25.4mm ",
//
// -- !!!! Смотрите здесь, можете перейти к главе «Дизайн содержимого PDF», когда необходимо узнать больше о следующих параметрах!!!! --//
// Необязательно, опция исправления высоты.
// Разные браузеры могут иметь пустые страницы на каждой странице при печати PDF
// Обычно используется для настройки нестандартной бумаги.
// Отрегулируйте исправление этим значением
pageFixedHeightOffset : -1.0, //единица измерения мм, обычно отрицательная
// Необязательно, принудительно печатать фон страницы, перечисленные опции являются значениями по умолчанию
forcePrintBackground : true
// Необязательно. Когда текстовое содержимое распространяется на несколько страниц, символ, который не появляется в начале абзаца. Перечисленные варианты являются значениями по умолчанию.
textNoBreakChars : [',','. ',':',' "','! ','? ',',',';',',','] ','... ',',',',','! ',']','}','}'],
// Необязательно, миллисекунды, время задержки генерации PDF, (этот элемент конфигурации не влияет на предварительный просмотр). Некоторые страницы содержат асинхронные неконтролируемые факторы. Отрегулируйте это значение, чтобы обеспечить правильную печать страницы. Это значение можно соответствующим образом отрегулировать, чтобы оптимизировать скорость генерации PDF сервером
printDelay : 1000
// Простой плагин номера страницы, необязательно (по умолчанию не включен), перечисленные варианты — значения по умолчанию при включении
simplePageNum : {
//Номер страницы, по умолчанию 0 — первая страница, номера страниц нет или это может быть селектор css, такой как ".first_page", номер страницы, содержащей контакт селектора
pageBegin : 0
//С конца номер страницы, по умолчанию -1 — конец последней 1 страницы. Без номера страницы также может быть селектором css, таким как ".end_page" до конечного номера страницы, содержащей контактный селектор
pageEnd : -1
// Часть страницы, необязательно
pendant : '<div class="page-num-simple"><span style="">${PAGE} / ${TOTAL_PAGE}</span></div> ',
},
// каталог/закладка плагин, необязательно (по умолчанию не включён),
*Примечание: в тексте запроса присутствуют фрагменты кода на языке программирования JavaScript.* **Переведённый текст:**
listed options are the default values when enabled
simpleCatalog: {
// current version, if you need to generate PDF bookmarks, toolBar.serverPrint.wkHtmlToPdf must be true
// titlesSelector do not modify, use h1-h6 to mark bookmarks
titlesSelector: 'h1,h2,h3,h4,h5,h6', // optional, as a selector for directory titles, in turn by directory level
/**Directory-related options * */
showCatalog: true, // optional, whether to insert a directory into the page, default, insert a directory into the page
Header: '<div class="catalog-title"> directory </div>', //optional, Header section of directory page, put everything you want to add
itemFillChar: '...', // optional, directory entry padding character, "" empty string, no padding, ignored when using custom makeItem configuration
positionSelector: '.nop-page-item-pagenum-1', //optional, the directory location will be inserted before the matching page, and the default is before the first numbered page.
// Optional, custom directory entry.
makeItem: function(itemEl, itemInfo) {
/* *
* @var itemEl jQuery Element
* @var object itemInfo PS: {title, pageNum, level,linkId}
* */
return '<div> custom directory item html content, constructed according to the itemInfo </div>';
},
/**Sidebar (PDF Bookmarks) Related Options * */
showSlide: true, // optional, whether to display sidebar, directory navigation, toolbar button order index: 200, invalid when bookConfig.toolBar option is false
slideOn: false, // optional, directory navigation, default open state
slideHeader: '<div class="title"> Purpose & nbsp;& nbsp; Record </div>', // Optional, sidebar title
slideClassName: '', // optional, sidebar custom class
slidePosition: 'left', // optional, position left, right
slideMakeContent: null, // custom sidebar content processing function, when null, the default behavior: fill with directory content, function(){return'sidebar content';}
},
// Toolbar plug-in, optional (enabled by default),object | false, false will not display the toolbar, the listed options are the default values when enabled
toolBar: {
// Web print button function is optional, default true, button order index: 100
webPrint: true
/* *
* HTML save button, optional, bool | object, default false: disable saving HTML feature, true: enable and use default option
* Button order index: 300
* saveHtml : {
* // Optional. The saved file name. Default value: document.title + '.html'
* fileName : 'output.html ',
* // Optional, custom download and save. Can be used for downloading in mixed APP
* save : function(getStaticHtmlPromiseFunc,fileName) {
* getStaticHtmlPromiseFunc().then(function(htmlBlob) {
* ...
* })
*}
*}
*/
saveHtml: false
/* *
* The server prints the download button, and the button sequence index: 400
* optional, bool | object, default false: not enabled, true: enable and use the default option, object: use custom server printing
* true Equivalent object configuration: serverPrint : { serverUrl : '/' },
* Official website available serverUrl : '// bookjs.zhouwuxue.com/'
* To use serverPrint, you must have server access to your web page. Web pages do not use login status authorization, it is recommended to pass temporary authorization through URL parameters.
* If you use the official server for printing, you need to correctly access the web page you constructed with bookjs-eazy on the public network.
*
* serverPrint : {
* // Optional, print server address, button order index: 400
* serverUrl : '/',
*
* // Optional. If true, use wkHtmlPdf creation. If false, use chrome headless by default.
* // **Note**: The wkhtmltopdf does not support es6 and lacks some new web features. The advantage is that it can generate PDF directory bookmarks. **PDF-контент (метод разбивки содержимого страницы)**
1. Определите содержимое, которое нужно вставить в документ, в узле с идентификатором content-box;
2. Каждому дочернему узлу первого уровня под content-box необходимо определить атрибуты data-op-type, чтобы указать, как он будет вставлен в документ.
Пример:
```html
<body>
<div id="content-box">
<p data-op-type="text">Hello World! </p>
</div>
</body>
block: блок, неделимый (по умолчанию)
<div data-op-type="block">...</div>
Используйте в одном из мест, которые соответствуют следующим правилам селектора:
#content-box> узел следующего уровня
[data-op-type = mix-box] .nop-fill-box> Узел 1-го уровня под смешанным контейнерным узлом box
[data-op-type = table] tbody td> Ячеек таблицы
text: текст, который можно разделить на разные страницы
<p data-op-type="text"> длинный текст...</p>
<p data-op-type="text"> long text2...</p>
Используйте в одном из мест, которые соответствуют следующим правилам селектора:
#content-box> следующий уровень узла
[data-op-type = mix-box] .nop-fill-box> Уровень 1 узла под смешанным контейнером box
[data-op-type = table] tbody td> Первый уровень узла ячейки таблицы
new-page: новая страница, ручное управление для добавления новой страницы
<div **data-op-type="new-page"> — это просто узел тега, содержимое здесь не отображается **</div>**
#content-box> следующий уровень узла
[data-op-type = mix-box] .nop-fill-box> Узел уровня 1 под контейнером смешанного поля (unlike marked to other positions, marked tr nodes will remain and will not be deleted from the page)
[data-op-type = table] tbody>tr узлы под tbody таблицы tr, (в отличие от отмеченных других позиций, отмеченные tr узлы останутся и не будут удалены со страницы)
**Подвески: части страницы, элементы, которые зафиксированы относительно позиции страницы (заголовок, нижний колонтитул, ярлык страницы и т. д.)**
- Дочерний узел внутри подвесок будет автоматически помечен классом: nop-page-pendants, и каждая страница после его определения будет отображаться до появления следующих подвесок.
- Виджет nop-page-pendants содержит атрибут css: {position: absolute}, который зафиксирован относительно положения бумаги на странице.
- При разработке страницы необходимо установить css: left/right/top/bottom/width/height и другие свойства для узла детали, чтобы контролировать положение и размер детали.
- Используйте в одной из позиций, соответствующих следующим правилам селектора:
#content-box> следующий уровень узла
Пример: [Пример детали](https://bookjs.zhouwuxue.com/static/book-tpl/editor.html?code=V86PPDPA)
```html
<div data-op-type="pendants">
<div style="top: 50px;left: 100px;width: 100px;height: 100px"><img src="...." alt="logo"></div>
<div style="bottom: 50px;left: 400px;width: 100px; height: 30px"><span> Нижний колонтитул: Глава: xxx</span></div>
</div>
Стиль макета коробки, дифференциала и переноса
<div data-op-type="mix-box"><!-- при переходе на страницы: этот узел будет скопирован на следующую страницу, за исключением того, что все содержимое в nop-fill-box страницы будет повторно использовано. В странице data-op-type может быть только один узел контейнера (класс:nop-fill-box), и узел контейнера может находиться где угодно в data-op-type="mix-box" -->
<div class="title"> Макет 1</div>
<div class="nop-fill-box">
<!-- при переходе на страницы содержимое класса: nop-fill-box будет продолжать заполнять предыдущую страницу -->
<span data-op-type="text">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</span>
<span data-op-type="new-page"></span><!-- Вставить новую страницу -->
<span data-op-type="text" sytle="color:red">BBBBBBBBBBBBBBBBBBBBBBB</span>
<a data-op-type="text" target="_blank" href="https://baijiahao.baidu.com/s?id=1726750581584920901&wfr=spider&for=pc"> Ссылка на статью...</a><!-- текст ссылки здесь: если на последних двух страницах разворота есть гиперссылки -->
</div>
<div class="title"> Макет 2</div>
<div class="title"> Макет 3</div>
</div>
Используйте в одной из позиций, соответствующих следующим правилам селектора:
#content-box> следующий уровень узла
#content-box> следующий уровень узла
Пример: См. Пример: [Таблица]. Генерация информации
<meta name="author" content="nop">
<meta name="description" content="bookjs-eazy so eazy !! ">
<meta name="keywords" content="PDF, bookjs">
# Собственная команда для службы докеров печати
# ./docker-start.sh [WEB порт, по умолчанию 3000]
./docker-start.sh
# Запустите службу печати
# будет создан веб-сайт с dist в качестве корневого каталога. Пример можно получить по адресу http:// 127.0.0.1:3000/eazy-1.html и распечатать на сервере.
#
# Вы можете создать book.html с bookjs-eazy в корневом каталоге dist (см. пример: eazy-1.html).
# Доступ к http:// 127.0.0.1:3000/book.html для предварительного просмотра/загрузки печати
# Сгенерированный pdf будет находиться в каталоге dist/pdf/.
Для получения дополнительной информации см. проект wuxue107/screenshot-api-сервер.
# Вам необходимо предварительно установить среду nodejs и установить yarn
git clone https://gitee.com/wuxue107/screenshot-api-server.git
cd screenshot-api-server
# Установить зависимости
yarn
# Запуск службы. Номер порта службы по умолчанию — 3000
# Укажите номер порта для запуска
# Переменные среды, которые можно указать при запуске
# MAX_BROWSER = 1 Максимальное количество экземпляров puppeteer. Если параметр игнорируется, значение по умолчанию составляет [Доступная память]/200M
# PDF_KEEP_DAY = 0 Автоматически удалять каталог файлов, созданный num дней назад, по умолчанию: 0: не удалять файлы
# PORT = 3001 порт прослушивания, по умолчанию: 3000
yarn start
Укажите значение конфигурации bookConfig.toolBar.serverPrint.serverUrl как: '// ваш-screenshot-api-сервер[:ПОРТ]/'
# При первом использовании установите пакет зависимостей bin/html2pdf
yarn install
# После установки выполните команду
# Пример:
bin/html2pdf print --output eazy-2-1.pdf "https://bookjs.zhouwuxue.com/eazy-2.html"
#
# Описание команды:
# Использование: html2pdf print [options] <url>
#
# Параметры:
# -o -- output [outputfile] Путь для сохранения файла PDF (по умолчанию: "output.pdf")
# -t -- timeout [type] тайм-аут (по умолчанию: 60000)
# -a -- agent [agent] указывает на конверсионный движок chrome-headless | puppeteer, по умолчанию: puppeteer (по умолчанию: "puppeteer")
# -d -- printDelay [delay] задержка ожидания (мс) перед печатью (по умолчанию: 1000)
# -c -- checkJs [jsExpression] выражение js для проверки завершения рендеринга (по умолчанию: "window.status === 'PDFComplete'")
# "window.document.readyState === 'complete'" Это выражение можно использовать в качестве встроенной веб-страницы, отличной от bookjs-eazy
# -h, --help отобразить справку по команде
#
#
Обычно встречается в td>[data-op-type="block"]
.
Следующий элемент в td будет рассматриваться как блок по умолчанию, если data-op-type не указан. Пожалуйста, разумно разделите элемент блока, чтобы его можно было разместить на 1 странице.
Части не могут отображаться:
Настройка bookConfig.padding = "1px 0 0 0".
Или вы можете попробовать заполнить пустой текстовый узел для <span> <span>
на странице.
:: Запустить локальный безголовый хром
"chrome.exe" --headless --disable-gpu --remote-debugging-port=9222 --disable-extensions --mute-audio
:: Затем использовать --agent = chrome-headless для успеха.
:: По умолчанию --agent = puppeteer не требуется. Вышеупомянутая операция запустит собственный браузер.
Изображение отсутствует.
Репозиторий: GITEE (https://gitee.com/wuxue107/bookjs-eazy), GITHUB (https://github.com/wuxue107/bookjs-eazy).
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )