1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/myn_wsc-html_to_pdf

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
README.md 14 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 02.06.2025 13:00 400e001

Преобразование HTML в PDF, скачивание (html2canvas и jsPDF)

html2canvas

Краткое описание

Мы можем использовать html2canvas прямо в браузере для "снятия скриншотов" с целого или части страницы. Однако это не настоящий скриншот, а рендеринг canvas изображения путем перебора структуры DOM страницы и сбора информации обо всех элементах и соответствующих стилях.

Так как html2canvas может преобразовать только то, что он способен обработать, результат рендеринга не будет 100% идентичен оригиналу. Однако он не требует участия сервера, весь процесс генерации изображения происходит на стороне клиента, что делает его удобным для использования.

Использование

API для использования также прост:

html2canvas(element, {
    onrendered: function(canvas) {
        // canvas - это окончательно отрендеренный элемент <canvas>
    }
});

С помощью метода onrendered можно выполнить обратный вызов сгенерированного canvas, например, вставить его в страницу:

html2canvas(element, {
    onrendered: function(canvas) {
       document.body.appendChild(canvas);
    }
});

Вот небольшой пример кода, ссылка на демонстрацию:```html

<title>Пример html2canvas</title> <style type="text/css">...</style>
  • один
  • ...

это заголовок

Каменный великан ...

Каменный великан

Прибытие ...

Из кучи камней...

Автор: linwalker @2017 <script type="text/javascript" src="./html2canvas.js"></script> <script type="text/javascript"> html2canvas(document.body, { onrendered:function(canvas) { document.body.appendChild(canvas) } }) </script> ```Этот пример рендерит элементы тела страницы в canvas и вставляет их в тело страницы.

jsPDF

Библиотека jsPDF может использоваться для генерации PDF на стороне клиента.

Генерация PDF с текстом

Пример использования:

// По умолчанию PDF размером A4, вертикальное расположение, единицы измерения в мм
var doc = new jsPDF();

// Добавление текста 'Скачать PDF'
doc.text('Скачать PDF!', 10, 10);
doc.save('a4.pdf');

Онлайн-демонстрация demo2

Создание PDF из изображения

Пример использования:

// Три параметра: первый - ориентация, второй - единицы измерения, третий - формат размера
var doc = new jsPDF('landscape', 'pt', [205, 115]);

// Преобразование изображения в dataUrl
var imageData = 'data:image/png;base64,iVBORw0KGgo...';

doc.addImage(imageData, 'PNG', 0, 0, 205, 115);
doc.save('a4.pdf');

Онлайн-демонстрация demo3

Создание PDF из текста и изображения

// Три параметра: первый - ориентация, второй - размер, третий - формат размера
var doc = new jsPDF('landscape', 'pt', [205, 155]);

// Преобразование изображения в dataUrl
var imageData = 'data:image/png;base64,iVBORw0KGgo...';

// Установка размера шрифта
doc.setFontSize(20);

// Параметры 10, 20 контролируют расстояние текста от левого края и верхнего края
doc.text('Stone', 10, 20);

// Параметры 0, 40 контролируют расстояние текста от левого края и верхнего края
doc.addImage(imageData, 'PNG', 0, 40, 205, 115);
doc.save('a4.pdf');
```Онлайн-демонстрация [demo4](https://linwalker.github.io/render-html-to-pdf/demo4.html)

Для создания PDF необходимо добавить преобразованные элементы в экземпляр jsPDF. Также есть возможность добавления HTML, но некоторые элементы не могут быть добавлены в PDF, поэтому можно использовать метод html2canvas + jsPDF для преобразования страницы в PDF. С помощью html2canvas можно перебрать элементы страницы и сгенерировать canvas, а затем добавить изображение из canvas в формате dataUrl в экземпляр jsPDF, создавая PDF.

## html2canvas + jsPDF

#### Одностраничный PDF

Изменение примера demo1:

```javascript
<script type="text/javascript" src="./js/jsPdf.debug.js"></script>
<script type="text/javascript">
      var downPdf = document.getElementById("renderPdf");
      downPdf.onclick = function() {
          html2canvas(document.body, {
              onrendered: function(canvas) {

                  // Получение dataURL изображения, параметры: формат изображения и качество (0-1)
                  var pageData = canvas.toDataURL('image/jpeg', 1.0);

                  // Ориентация по умолчанию - вертикальная, размер points, формат a4[595.28,841.89]
                  var pdf = new jsPDF('', 'pt', 'a4');

                  // Параметры после addImage контролируют размер добавляемого изображения, здесь высота страницы сжата в соотношении a4 бумаги
                  pdf.addImage(pageData, 'JPEG', 0, 0, 595.28, 592.28 / canvas.width * canvas.height);

Пример онлайн-демонстрации demo5

Что произойдет, если содержимое страницы превысит высоту A4 при пропорциональном преобразовании? Будет ли сгенерированный PDF содержать несколько страниц?Вы можете попробовать это и проверить свои догадки: demo6

Библиотека jsPDF предоставляет полезный API addPage(), с помощью которого можно добавлять страницы PDF с помощью pdf.addPage(), а затем использовать pdf.addImage(...) для добавления изображений на эти страницы.

Но как мы определяем, где должна быть разбита страница?

Ответ на этот вопрос прост: мы можем установить переменную pageHeight, и когда содержимое превышает эту высоту, мы начинаем новую страницу PDF.

Давайте разберем идею: сначала мы конвертируем содержимое HTML-страницы в изображение canvas, затем используем addImage для добавления первой страницы в PDF, а затем, если содержимое превышает одну страницу, используем addPage() для добавления новых страниц PDF, и снова используем addImage для добавления следующей страницы.

Но есть ли проблема с этим подходом?

Основная проблема заключается в том, что нам нужно сначала разделить изображение canvas на несколько меньших изображений, соответствующих каждой странице PDF. Это означает, что нам нужно было бы получить различные части DOM-элементов на странице, а затем использовать html2canvas(element, option) для их обработки. Это не только сложно, но и трудоемко.

Если это кажется сложным, :)

можно рассмотреть следующий подход:

Множество страницМоя идея заключается в том, чтобы создать только одно изображение canvas, именно одно, а элементом для конвертации является родительский элемент, который вы хотите преобразовать в PDF, в данном случае это body. Все остальное остается без изменений: если содержимое превышает одну страницу, мы используем addPage(), а затем addImage, но здесь мы добавляем одно и то же изображение canvas.

Конечно, такой подход приведет к тому, что каждая страница будет содержать копию всего изображения canvas. Но как мы можем правильно разделить страницы? Для этого мы используем две возможности jsPDF:

(например, `var pdf = new jsPDF('', 'pt', 'a4');` в демонстрации используется размер листа A4).
- Метод `addImage` имеет два параметра, которые контролируют положение изображения на PDF-документе.

Хотя каждая страница PDF содержит одно и то же изображение, мы можем создать иллюзию разбиения на страницы, изменяя положение изображения. Например, на второй странице горизонтальное смещение устанавливается в `-841.89`, что соответствует высоте листа A4. Поскольку изображение, выходящее за пределы высоты листа A4, не отображается, на второй странице отображается только часть изображения, соответствующая диапазону [841.89, 1682.78] по вертикали. Это позволяет создать иллюзию разбиения на страницы, и так далее.```Вот пример кода:

```javascript
html2canvas(document.body, {
  onrendered: function(canvas) {

      var contentWidth = canvas.width;
      var contentHeight = canvas.height;

      // Высота одной страницы PDF
      var pageHeight = contentWidth / 592.28 * 841.89;
      // Оставшаяся высота контента
      var leftHeight = contentHeight;
      // Смещение страницы
      var position = 0;
      // Размеры листа A4 [595.28, 841.89] и размеры изображения в PDF
      var imgWidth = 595.28;
      var imgHeight = 592.28 / contentWidth * contentHeight;

      var pageData = canvas.toDataURL('image/jpeg', 1.0);

      var pdf = new jsPDF('', 'pt', 'a4');

      // Если оставшаяся высота контента меньше высоты одной страницы PDF, не нужно разделять на страницы
      if (leftHeight < pageHeight) {
          pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
      } else {
          while (leftHeight > 0) {
              pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
              leftHeight -= pageHeight;
              position -= 841.89;
              // Предотвратить добавление пустых страниц
              if (leftHeight > 0) {
                  pdf.addPage();
              }
          }
      }

      pdf.save('content.pdf');
  }
})

Пример демонстрации demo7

Добавление отступа по краям

Измените imgWidth и установите отступ по горизонтали при вызове addImage, как показано ниже:

var imgWidth = 555.28;
var imgHeight = 555.28 / contentWidth * contentHeight;
...
pdf.addImage(pageData, 'JPEG', 20, 0, imgWidth, imgHeight);
...
pdf.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight);

Пример демонстрации demo8

В конце приведены несколько официальных ссылок на jsPDF:http://rawgit.com/MrRio/jsPDF/master/

http://rawgit.com/MrRio/jsPDF/master/docs/index.html

http://mrrio.github.io/

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/myn_wsc-html_to_pdf.git
git@api.gitlife.ru:oschina-mirror/myn_wsc-html_to_pdf.git
oschina-mirror
myn_wsc-html_to_pdf
myn_wsc-html_to_pdf
master