如何保持页面样式基本不变的前提下将HTML页面导出为PDF,下面提供一些示例代码,纯属个人原创,如对您有帮助请记得加关注、加收藏、点赞、转发、分享~
基本思路: 保持页面样式基本不变,使用 html2canvas
将页面转换为图片,然后再通过 jspdf
将图片分页导出为PDF文件(中间会遇到图片或文字等内容在分页处被切割开的问题,如何解决了?详见末尾干货)
上基础代码: 下面为项目中实际代码截取
<div>
<!-- 要打印的内容区 -->
<div ref="contentRef">
<div class="print-item print-out-flow">这是脱离文档流的内容区域</div>
<div class="print-item">这是一行内容,也是最小叶子元素内容</div>
</div>
<!-- 打印内容容器 -->
<div ref="printContainerRef" class="print-container"></div>
</div>
/**
* 1.使用一个隐藏div装载有滚动条的div.innerHTML
* 2.隐藏div使用position: absolute, z-index: -999, left: -9999px, width: 900px 控制让用户无感知
* 3.根据需要覆写隐藏div内html样式(例如textarea多行显示有问题, 可以新增一个隐藏的div
* 包裹textarea的绑定值, 然后在打印样式中覆写样式, 隐藏textarea并显示对应div)
*/
handleExport() {
// 下面是VUE组件内获取DOM元素代码,将内容放置到打印区(定义的隐藏DIV)中
const contentRef = this.$refs.contentRef as HTMLElement;
const printContainerRef = this.$refs.printContainerRef as HTMLElement;
// 打印区的需额外处理绝对定位值, 调整使得第一个元素的.top值为0, 以便于页面计算
printContainerRef.innerHTML = contentRef.innerHTML;
// 所有叶子div元素加上 print-item 样式名, 脱离文档流的额外添加 print-out-flow
handlePrintItem(printContainerRef); // 解决多页内容可能被切割问题
html2canvas(printContainerRef, {
allowTaint: false, useCORS: true}).then((canvas: any) => {
const contentHeight = canvas.height;
const contentWidth = canvas.width;
// pdf每页显示的内容高度
const pageHeight = contentWidth / 595.28 * 841.89;
// 未生成pdf的页面高度
let offsetHeight = contentHeight;
// 页面偏移值
let position = 0;
// a4纸的尺寸[595.28, 841.89], canvas图片按a4纸大小缩放后的宽高
const imgWidth = 595.28