前端生成和导出pdf zip;
使用的插件:jspdf、html2canva、jszip、file-saver
插件安装 :npm install jspdf html2canvas jszip file-saver
可用于单个导出pdf ,或者多个 直接生成压缩包
ps:这里演示代码使用场景是:zip文件里多个pdf (自行修改)
pdf.js
//PDF.js
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
/**
* 网页转pdf
* @param {*} dom 指定区域
* @param {*} name 文件名
*/
export const downloadPDF = (dom, name) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
var _downDOM = dom
// 导出之前先将滚动条置顶,不然会出现数据不全的现象
window.pageYOffset = 0
document.documentElement.scrollTop = 0
document.body.scrollTop = 0
html2canvas(_downDOM, {
scale: 4, //按比例增加分辨率 (2=双倍).
dpi: window.devicePixelRatio * 4, //设备像素比
}).then((canvas) => {
var contentWidth = canvas.width
var contentHeight = canvas.height
// console.log(contentWidth + '||' + contentHeight)
//一页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 = 555.28
var imgHeight = (555.28 / contentWidth) * contentHeight
var pageData = new Image()
//设置图片跨域访问
pageData.setAttribute('crossOrigin', 'Anonymous')
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', 20, 80, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
//避免添加空白页
if (leftHeight > 0) {
pdf.addPage()
}
}
}
//这里返回文件 用来处理多个下载 打包zip
resolve({ PDF: pdf, name: name })
//直接单个pdf可直接调用下面方法
// pdf.save(name)
})
}, 10)
})
}
template中使用
import JSZip from 'jszip'
import FileSaver from 'file-saver'
import { downloadPDF } from '@/utils/pdf' //引入封装的pdf.js文件
/**
* 触发下载
*/
async download() {
let promises = []
//downloadTaskList 为下载的长度,我这里是为发票数组
for (let i = 0; i < this.downloadTaskList.length; i++) {
//dom 具体传入参数 自行修改
let PDFres = await downloadPDF(this.$refs[`pdf${this.downloadTaskList[i].code}`][0], `${this.downloadTaskList[i].realName}-${this.downloadTaskList[i].code}`)
promises.push(PDFres)
const loading = this.$loading({
lock: true,
text: 'loading...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
})
//动态提示需要等待生成文件
loading.setText(`正在生成第${i + 1}/${this.downloadTaskList.length}份回执单`)
if (i === this.downloadTaskList.length - 1) {
this.zipChange(promises)
loading.close()
}
}
},
/**
*生成zip
*/
zipChange(promises) {
Promise.all(promises).then(async(pdfs) = >{
const zip = new JSZip()
promises.forEach(async(item, index) = >{
const {PDF,name} = item
if (promises.length === 1) {
PDF.save(`$ {name}.pdf`)
} else {
await zip.file(`$ {name}.pdf`, PDF.output('blob'))
}
})
if (promises.length > 1) {
zip.generateAsync({type: 'blob'}).then((content) = >{
FileSaver.saveAs(content, '回执' + '.zip')
})
}
})
},