当前位置: 首页 > 工具软件 > HTML2PDF > 使用案例 >

html页面导出pdf截断问题,html2canvas 与 jspdf 相结合生成 pdf 内容被截断的终极解决方案...

梁丘招
2023-12-01

欢迎关注我的公众号

《人生代码》

我有一个大胆的想法,我要一直写到死,那一天我不写了,可能就死了。哈哈。

哈喽,大家好,我是你们的攻城狮,人贱人爱的 Ken,一个永远充满激情的人。

最近接收到一个优化需求:就是对之前的行程文档的图文介绍添加打印生成 pdf 的功能

当然,我们需要依赖 html2canvas 和 jspdf.min.js 这两个库,html2canvas 是用于生成 canvas,jspdf.min.js 是用于生成 pdf 的。

首先我们需要引入 html2canvas, jspdf

import html2canvas from 'html2canvas'

import './jspdf.min.js'

如果有滚动条,先把滚动条置顶

document.body.scrollTop = document.documentElement.scrollTop = 0

if (!selector) {

throw new Error('缺少selector')

}

let el = document.querySelector(selector)

if (!el) {

throw new Error('未找到' + selector + '对应的dom节点')

}

设置背景色为白色,然后转成图片后,获取截断处图片像素点,从截断处往上一行行扫描像素点颜色,碰到这一行颜色都是全白的,代表是从这里开始截断,将这个高度开始将往下的内容都放到下一页

html2canvas(el, {

allowTaint: true,

useCORS: true,

dpi: 120, // 图片清晰度问题

background: '#FFFFFF', //如果指定的div没有设置背景色会默认成黑色,这里是个坑

}).then(canvas => {

//未生成pdf的html页面高度

var leftHeight = canvas.height

var a4Width = 595.28

var a4Height = 841.89 //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277

//一页pdf显示html页面生成的canvas高度;

var a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height)

//pdf页面偏移

var position = 0

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

var pdf = new jsPDF('p', 'pt', 'a4') //A4纸,纵向

var index = 1,

canvas1 = document.createElement('canvas'),

height

pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen')

var pdfName = title

function createImpl(canvas){

console.log(leftHeight, a4HeightRef)

if (leftHeight > 0) {

index++

var checkCount = 0

if (leftHeight > a4HeightRef) {

var i = position + a4HeightRef

for (i = position + a4HeightRef; i >= position; i--) {

var isWrite = true

for (var j = 0; j 

var c = canvas.getContext('2d').getImageData(j, i, 1, 1).data

if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {

isWrite = false

break

}

}

if (isWrite) {

checkCount++

if (checkCount >= 10) {

break

}

} else {

checkCount = 0

}

}

height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef)

if (height <= 0) {

height = a4HeightRef

}

} else {

height = leftHeight

}

canvas1.width = canvas.width

canvas1.height = height

console.log(index, 'height:', height, 'pos', position)

var ctx = canvas1.getContext('2d')

ctx.drawImage(

canvas,

0,

position,

canvas.width,

height,

0,

0,

canvas.width,

height,

)

var pageHeight = Math.round((a4Width / canvas.width) * height)

// pdf.setPageSize(null, pageHeight)

if (position != 0) {

pdf.addPage()

}

pdf.addImage(

canvas1.toDataURL('image/jpeg', 1.0),

'JPEG',

10,

10,

a4Width,

(a4Width / canvas1.width) * height,

)

leftHeight -= height

position += height

if (leftHeight > 0) {

setTimeout(createImpl, 500, canvas)

} else {

pdf.save(pdfName + '.pdf')

}

}

}

//当内容未超过pdf一页显示的范围,无需分页

if (leftHeight 

pdf.addImage(

pageData,

'JPEG',

0,

0,

a4Width,

(a4Width / canvas.width) * leftHeight,

)

pdf.save(pdfName + '.pdf')

} else {

try {

pdf.deletePage(0)

setTimeout(createImpl, 500, canvas)

} catch (err) {

// console.log(err);

}

}

})

如果是连续的表格的,我们的方案是不使用一个表格来填充所有数据,这就有点像那个分页加载数据一样了,如果我们使用多个表格来循环这些数据,然后每个表格的高度设置为 a4 纸的高度,这样也许能够做到不被截断了

 类似资料: