Мы можем использовать 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 может использоваться для генерации PDF на стороне клиента.
Пример использования:
// По умолчанию PDF размером A4, вертикальное расположение, единицы измерения в мм
var doc = new jsPDF();
// Добавление текста 'Скачать PDF'
doc.text('Скачать PDF!', 10, 10);
doc.save('a4.pdf');
Онлайн-демонстрация demo2
Пример использования:
// Три параметра: первый - ориентация, второй - единицы измерения, третий - формат размера
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
// Три параметра: первый - ориентация, второй - размер, третий - формат размера
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)
для их обработки. Это не только сложно, но и трудоемко.
Если это кажется сложным, :)
можно рассмотреть следующий подход:
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/
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )