вопросы и ответызаголовкистолбец аудитория Более
SegmentFault
поиск всевнешний интерфейсзадняя часть iOSAndroid Безопасность искусственный интеллектинструментпрограммист промышленность Официальный представитель Сан-ФранцискоJavascript конвертировать html в pdf, скачать (html2canvas и jsPDF)
читать 125, опубликовано 1 день назад, источник:bbs.thankbabe.com
Недавно столкнулся с запросом, нужно сгенерировать pdf текущей страницы и скачать. Через несколько дней разобрал сам и записал, думаю кому-нибудь пригодится :)
Адрес исходного кода проекта:GitHub.com/Лин Уокер/День…
html2canvas
Введение
Мы можем использовать html2canvas непосредственно на стороне браузера, чтобы сделать «скриншот» всей страницы или ее части. Но это не настоящий снимок экрана, а просмотр структуры DOM страницы, сбор всей информации об элементах и соответствующих стилях и рендеринг изображения холста.
Поскольку html2canvas может генерировать только изображения холста, которые он может обработать, визуализированные результаты не на 100% соответствуют оригиналу. Но при этом не требуется участия сервера, а все изображение генерируется клиентским браузером, что очень удобно в использовании.
использовать
Используемый API также очень лаконичен.Следующий код может отображать элемент на холсте:
html2canvas(element, {
onrendered: function(canvas) {
// canvas is the final rendered <canvas> element
}
});
С помощью метода onrendered сгенерированный холст можно вызвать обратно, например, вставить на страницу:
html2canvas(element, {
onrendered: function(canvas) {
document.body.appendChild(canvas);
}
});
Небольшой пример кода выглядит следующим образом: онлайн-ссылка на отображениеdemo1
<html>
<head>
<title>html2canvas example</title>
<style type="text/css">...</style>
</head>
<body>
<header>
<nav>
<ul>
<li>one</li>
...
</ul>
</nav>
</header>
<section>
<aside>
<h3>it is a title</h3>
<a href="">Stone Giant</a>
...
</aside>
<article>

<h2>Stone Giant</h2>
<p>Coming ... </p>
<p>以一团石头...</p>
</article>
</section>
<footer>write by linwalker @2017</footer>
<script type="text/javascript" src="./html2canvas.js"></script>
<script type="text/javascript">
html2canvas(document.body, {
onrendered:function(canvas) {
document.body.appendChild(canvas)
}
})
</script>
</body>
</html>
В этом примере элементы в теле страницы отображаются на холсте и вставляются в тело.
jsPDF
Библиотеку jsPDF можно использовать для создания PDF-файлов на стороне браузера.
Текст в PDF
Способ применения следующий:
// 默认a4大小,竖直方向,mm单位的PDF
var doc = new jsPDF();
// 添加文本‘Download PDF’
doc.text('Download 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
Для генерации pdf нужно добавить преобразованные элементы в экземпляр jsPDF, а также есть функция добавления html, но некоторые элементы нельзя сгенерировать в pdf, поэтому для конвертации страницы в pdf можно использовать html2canvas + jsPDF. Через html2canvas элементы страницы будут пройдены, и холст будет сгенерирован путем рендеринга, а затем формат изображения холста будет добавлен к экземпляру jsPDF для создания pdf.
html2canvas + jsPDF
одна страница
Измените пример demo1 на:
<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);
//方向默认竖直,尺寸ponits,格式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 );
pdf.save('stone.pdf');
}
})
}
</script>
онлайн демоdemo5
Если содержимое страницы конвертируется в соответствии с форматом А4 и высота превышает высоту бумаги формата А4, что произойдет с сгенерированным pdf? Будет ли он разбит на страницы?
Вы можете попробовать это, чтобы проверить свои собственные идеи:
demo6
jsPDF предоставляет полезный API,addPage(), мы можем пройтиpdf.addPage(), чтобы добавить страницу в pdf, затем перейдитеpdf.addImage(...), назначьте изображение на эту страницу pdf для отображения.
Итак, как мы определяем, где разбить на страницы?
На этот вопрос легко ответить, мы можем установитьpageHeight, содержимое, превышающее эту высоту, помещается на следующую страницу pdf.
Давайте рассмотрим идею, создадим изображение холста из содержимого html-страницы и передадимaddImageДобавьте изображение первой страницы в PDF, более одной страницы содержимого, черезaddPage()Добавьте количество страниц в формате PDF, а затем передайтеaddImageДобавить изображение следующей страницы в PDF.
Мммм, очень хорошо! Барт, ты не нашел проблему?
Суть этого метода в том, что -
мы можем согласноpageHeightСначала разделите изображение холста, созданное полным содержимым страницы, на соответствующие маленькие изображения, затем одну редьку и одну косточку, одну страницу за другой.addImageвходить.
Что?Вдумайтесь, как вздулось наше полотно, не тяните его вверх, просто смотрите ниже:
html2canvas(document.body, {
onrendered:function(canvas) {
//it is here we handle the canvas
}
})
здесьbodyЭто для создания элемента объекта холста, и один элемент генерирует один холст; тогда нам нужна одна страница за одним холстом, то есть. . .
Как вы думаете, это возможно?
Я не думаю, что это реально.По этой идее нам нужно получить DOM-элементы в разных позициях на странице, а затем передатьhtnl2canvas(element,option)бороться с ней, не будем говорить, может ли она быть просто в каждомpageHeightПросто найдите DOM-элемент на позиции, даже если он будет найден, это не утомительно.
Если вы устали :) Вы можете взглянуть на следующий метод
Несколько страниц
Идея, которую я представил, заключается в том, что мы создаем только один холст, правильно, элемент преобразования — это родительский элемент, который вы хотите преобразовать в содержимое PDF, в этой демонстрации этоbody; в остальном без изменений, это также более одной страницы контентаaddPage,ПотомaddImage, но здесь добавлен тот же холст.
Конечно, это приведет только к повторению PDF-файлов на нескольких страницах, так как же добиться правильного отображения страницы? На самом деле он в основном использует две точки jsPDF:
- 超过jsPDF实例格式尺寸的内容不显示
(var pdf = new jsPDF('', 'pt', 'a4'); demo中就是a4纸的尺寸)
- addImage有两个参数可以控制图片在pdf中的位置
Хотя изображения, отображаемые на каждой странице PDF-файла, одинаковы, мы создали иллюзию разбиения на страницы, отрегулировав положение изображений. Взяв за пример вторую страницу, установите вертикальное смещение на-841.89То есть высота листа бумаги A4, и поскольку изображение, превышающее диапазон высоты бумаги A4, не отображается, на второй странице отображается содержимое в диапазоне [841,89, 1682,78] в вертикальном направлении изображения. , что дает эффект пейджинга, с И так далее.
Давайте посмотрим на код:
html2canvas(document.body, {
onrendered:function(canvas) {
var contentWidth = canvas.width;
var contentHeight = canvas.height;
//一页pdf显示html页面生成的canvas高度;
var pageHeight = contentWidth / 592.28 * 841.89;
//未生成pdf的html页面高度
var leftHeight = contentHeight;
//页面偏移
var position = 0;
//a4纸的尺寸[595.28,841.89],html页面生成的canvas在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');
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过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 и установите желаемое поле в параметре направления x при добавлении изображения, конкретный код выглядит следующим образом.
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
Старые утюги обращают внимание на публичный аккаунт WeChat «Dahua WEB Development», двумерный код ↓ для поощрения и обмена знаниями!
Больше отличных статей
Артефакт браузера --vimium
Артефакт браузера --vimiumПосмотреть полный текст>
sflyq · 31 минут назадНачните свое путешествие в Scala с IntelliJ IDEA и Maven
Начните свое путешествие в Scala с IntelliJ IDEA и MavenПосмотреть полный текст>
sflyq · 1 час назадСерия Front-end - уникальная мобильная нижняя фиксированная планка, полностью совместимая с решениями IOS и Android.
Поверьте мне, окончательное решение, которым я делюсь, и которое вы видите в других блогах... Посмотреть полный текст>
Февраль · 1 час назадАдаптация iphoneX - страница клиента H5
Так как iphoneX имеет полноэкранный режим и при этом сохраняет небольшую челку, так что...Посмотреть полный текст>
hufeiyan · 1 час назадБольше отличных статей
Артефакт браузера --vimium
Артефакт браузера --vimium Показать полный текст>
Начните свое путешествие в Scala с IntelliJ IDEA и Maven
Начните свое путешествие по Scala с IntelliJ IDEA и Maven Подробнее >
Серия Front-end - уникальная мобильная нижняя фиксированная планка, полностью совместимая с решениями IOS и Android.
Поверьте мне, окончательное решение, которым я делюсь, и которое вы видите в других блогах... Посмотреть статью полностью >
Адаптация iphoneX - страница клиента H5
Так как iphoneX имеет полноэкранный режим и по-прежнему сохраняет небольшую челку, поэтому... Просмотр полного текста >
записывать
xxxxxxxxxxСохранено[сдаться]Сохранение личных заметок Сохранение общедоступных заметок