html2canvas 出现图片无法展示
我有一个大胆的想法,我要一直写到死,那一天我不写了,可能就死了。哈哈。
哈喽,大家好,我是你们的攻城狮,人贱人爱的 Ken,一个永远充满激情的人。
最近接收到一个优化需求:就是对之前的行程文档的图文介绍添加打印生成 pdf 的功能
当然,我们需要依赖 html2canvas 和 jspdf.min.js 这两个库,html2canvas 是用于生成 canvas,jspdf.min.js 是用于生成 pdf 的。
首先我们需要引入 html2canvas, jspdf
代码语言:javascript复制// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import './jspdf.min.js'
我们将在 Vue 的原型上面添加一个全局方法,传入两个参数
1 selector 选择的元素
2 title 标题
判断选择的元素是否存在,不存在抛出错误,让用户知道
代码语言:javascript复制export default {
install(Vue, options) {
Vue.prototype.$_getpdf = function(selector, title='') {
if(!selector) {
throw new Error("缺少 selector")
}
let el = document.querySelector(selector)
if(!el) {
throw new Error('未找到' selector '对应的DOM节点')
}
}
}
}
然后我们需要将这个元素生成 canvas:
代码语言:javascript复制export default {
install(Vue, options) {
Vue.prototype.$_getpdf = function(selector, title='') {
if(!selector) {
throw new Error("缺少 selector")
}
let el = document.querySelector(selector)
if(!el) {
throw new Error('未找到' selector '对应的DOM节点')
}
html2canvas(el, {
dpi: 120, // 图片清晰度问题
}).then(canvas => {
})
}
}
}
因为我们这里需要进行分页打印,所以需要根据 a4 纸的大小进行计算:
代码语言:javascript复制export default {
install(Vue, options) {
Vue.prototype.$_getpdf = function(selector, title='') {
if(!selector) {
throw new Error("缺少 selector")
}
let el = document.querySelector(selector)
if(!el) {
throw new Error('未找到' selector '对应的DOM节点')
}
html2canvas(el, {
dpi: 120, // 图片清晰度问题
}).then(canvas => {
let contentWidth = canvas.width // 画布的宽度
let contentHeight = canvas.height // 画布的高度
let pageHeight = contentWidth / 592.28 * 841.89 // 每一页的高度
let leftHeight = contentHeight // 偏移的位置
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new jsPDF('', 'pt', 'a4')
PDF.text(100, 100, '设置的表头的参数')
let pageArr = []
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
pageArr.push(position)
console.log('打印的页码数是多少', position)
if (leftHeight > 0) {
PDF.addPage()
}
}
}
console.log('打印页码数', pageArr)
pageArr.forEach((val,index) => {
console.log('循环的数组', index)
})
PDF.save(title '.pdf')
})
}
}
}
这样我们就生成了代码。
注意点
就是一般我们打印的话,可能需要再写一份代码,或者一个组件,将所需要打印的数据传递进去,将这个组件定位到很远很远的地方,设置好宽度,样式代码如下:
代码语言:javascript复制.xschedule-print-wrap {
position: fixed;
background-color: #ffffff;
top: -9999999px;
width: 1487px;
}
然后我们点击右下角的下载 PDF 按钮,我们可以看到我们已经把 pdf 下载好了,一开始如果我们没有开启上面的 useCORS,图片会是一段空白
开启之后:
代码语言:javascript复制html2canvas(el, {
dpi: 120, // 图片清晰度问题
useCORS:true, // 支持跨域打印图片
}).then(canvas => {
})
在下载就不会空白了