安装
dom-to-image:
npm install dom-to-image
import domtoimage from 'dom-to-image';
//当前项目是自己写的js文件,还需研究:
import domtoimage from '@/utils/dom_to_image'
jspdf:
npm install jspdf
import JsPDF from 'jspdf'
使用
// 添加的另外图片转换为base64
let base64 = await this.getBase64Image()
// 先获取需要打印预览的DOM节点,如果使用了vuescroll,需要定位到getElementsByClassName('__view')[0]
let modalDom = document.getElementsByClassName('print-me')[0].getElementsByClassName('__view')[0]
// 如果DOM节点里有不能展示的内容,使用opacity来隐藏
Array.from(document.getElementsByClassName('print-hidden')).forEach(dom => { dom.style.opacity = 0 })
domtoimage.toJpeg(modalDom, {
bgcolor: '#fff' //设置背景色为白色,不设置则为黑色
}).then(pageData => { //pageData为base64
let that = this
// 先创建一个Image对象,后续创建canvas需要用到这个对象
let img = new Image()
img.src = pageData
img.onload = function() {
// 获取图片的实际宽高
let contentWidth = img.width
let contentHeight = img.height
// 创建canvas,并将这张图片绘制上去
const canvas = document.createElement('canvas')
canvas.width = img.naturalWidth
canvas.height = img.naturalHeight
// 依照图片宽度获取到A4纸一张纸的高度
let pageHeight = contentWidth / 592.28 * 841.89 //A4纸的px宽高为:592.28 * 841.89
let leftHeight = contentHeight //图片总高度
let position = 0 //高度偏移量
const a4Height = 297 //A4纸张mm高度
const a4Width = 210 //A4纸张mm宽度
// 将图片宽高换算成A4纸张mm的宽高
let imgWidth = a4Width
let imgHeight = a4Width / contentWidth * contentHeight
const ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0)
// 创建pdf文档
const PDF = new JsPDF({
orientation: 'p', //l:横向 p:纵向
unit: 'mm', //测量单位("pt","mm", "cm", "m", "in" or "px")
format: 'a4',
putOnlyUsedFonts: true,
})
let curPage = 1
// 将图像添加到PDF: PDF.addImage('图片的base64', '图片类型', 'x轴偏移量', 'y轴偏移量', '纸张里显示的宽度', '纸张里显示的高度')
// 需要添加一张另外的图片
PDF.addImage(base64, "JPEG", 5, -5, imgWidth - 10, 20)
// 页面只有一页
if(leftHeight <= pageHeight) {
// 需要给左右留间距,所以x轴偏移5,同时显示的宽度减少5*2
PDF.addImage(pageData, 'JPEG', 5, 15, imgWidth - 10, imgHeight)
} else {
while(leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 5, position + 15, imgWidth - 10, imgHeight)
// 图片总高度减少一页的高度
leftHeight -= pageHeight
// 下一张的y轴偏移量减少A4纸张mm高度
position -= a4Height
if(leftHeight > 0) {
PDF.addPage() //在PDF文档中添加新页面
}
curPage++
}
}
// 下载PDF
PDF.save('设置名称.pdf')
}
}).catch(e => {
this.$Message.error('下载失败')
}).finally(() => {
// 下载完成,将之前隐藏的内容显示
Array.from(document.getElementsByClassName('print-hidden')).forEach(dom => { dom.style.opacity = 1 })
})
// 将图片转换为base64
getBase64Image() {
return new Promise((r, j) => {
const imgUpload = new Image()
imgUpload.src = require('./cloudas_title.png') //必须要写require
imgUpload.onload = () => {
let canvas = document.createElement("canvas");
canvas.width = imgUpload.width;
canvas.height = imgUpload.height;
let ctx = canvas.getContext("2d");
// imgUpload必须为Image对象
ctx.drawImage(imgUpload, 0, 0, imgUpload.width, imgUpload.height);
let dataURL = canvas.toDataURL("image/png") // 可选其他值 image/jpeg
r(dataURL)
}
})
},
未使用方法
// dom-to-image
domtoimage.toPng(…);将节点转化为png格式的图片
domtoimage.toSvg(…);将节点转化为svg格式的图片,生成的图片的格式都是base64格式
domtoimage.toBlob(…);将节点转化为二进制格式,这个可以直接将图片下载
domtoimage.toPixelData(…);获取原始像素值,以Uint8Array 数组的形式返回,每4个数组元素表示一个像素点,即rgba值。这个方法也是挺实用的,可以用于WebGL中编写着色器颜色。
// jspdf
let targetPage = pdf.internal.getNumberOfPages(); //获取总页
pdf.deletePage(targetPage); // 删除目标页
问题
无法打印,报错:因为HTML中有异常标签,这里是<o:p>,word文档粘贴转html生成的标签
处理办法:
// 在获取打印DOM节点前过滤掉<o:p>标签
const opElements = Array.from(document.getElementsByTagName('o:p'))
opElements.forEach(function (opElements) {
opElements.parentNode.removeChild(opElements)
})
// 为保证打印时,<o:p>标签都过滤完,将打印代码放入$nextTick()
this.$nextTick(() => {
let modalDom = document.getElementsByClassName('print-me')[0].getElementsByClassName('__view')[0]
...
domtoimage.toJpeg(modalDom, {
bgcolor: '#fff'
}).then(pageData => {
...
})
})