导出PDF
刀刀
12/30/2024
0 字
0 分钟
导出页面为一个 pdf
文件,我们需要用到两个第三方包: html2Canvas
和 jsPdf
。
html2Canvas
安装
shell
npm i html2canvas
shell
yarn add html2canvas
shell
pnpm i html2canvas
引用
javascript
import html2Canvas from 'html2canvas'
是什么
允许让我们直接在用户浏览器上拍摄网页或其部分的“截图”。 它的屏幕截图是基于 DOM 的,因此可能不会 100% 精确到真实的表示,因为它不会生成实际的屏幕截图,而是基于页面上可用的信息构建屏幕截图。
怎么用
- 获取到需要“截图”的 DOM 节点
- 传递“截图”的参数:
allowTaint
:允许跨域图片useCORS
:开启跨域配置scale
:比例缩放整体图片
- 在回调中通过 toDataURL 方法把获取到的图片转为 base64 的形式
javascript
html2Canvas(document.querySelector('.id'), {
allowTaint: true,
useCORS: true,
}).then((canvas) => {
/* 导出不分页处理 */
const pageData = canvas.toDataURL('image/jpeg', 1.0)
const img = new Image()
img.src = pageData
})
常见问题
Error loading img
图片跨域时会造成污染,导致绘制失败。看后台是否开启跨域,开启后设置
useCORS
和allowTaint
。不支持 css3
插件不支持
css3
新特性,因此使用background
等背景图会有一些潜在的bug
,如果确定该页面需要导出,就使用img
配合定位的形式实现效果。
jsPdf
安装
shell
npm i jspdf
shell
yarn add jspdf
shell
pnpm i jspdf
引用
javascript
import jsPDF from "jspdf"
使用
javascript
let pdf = new jsPDF('p', 'pt', [pdfX, pdfY]);
- 参数一:方向(l:横向 p:纵向)
- 参数二:测量单位("pt","mm", "cm", "m", "in" or "px")
- 参数三:可以是下面格式,默认为“a4”。如果想使用自己的格式,只需将大小作为数字数组传递,例如[595.28, 841.89];
添加图片
通过 pdf.addImage()
将图像添加到 PDF ,addImage
参数设置如下:
保存文档
通过 pdf.save(name + '.pdf');
的方法导出文档并命名。
整体代码
javascript
const pageData = canvas.toDataURL('image/jpeg', 1.0)
const img = new Image()
img.src = pageData
const imgWidth = (canvas.width) * 0.195
const imgHeight = (canvas.height) * 0.195 // 内容图片这里不需要留白的距离
let PDF
img.onload = function() {
if (contentWidth > contentHeight) {
PDF = new JsPDF('l', 'mm', [contentWidth, contentHeight])
} else {
PDF = new JsPDF('p', 'mm', [contentWidth, contentHeight])
}
PDF.addImage(pageData, 'jpeg', 10, 10, imgWidth, imgHeight)
PDF.save(title + '.pdf')
}
return true
导出函数封装
javascript
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
install(Vue, options) {
Vue.prototype.getPdf = function(title,id) {
html2Canvas(document.querySelector(id), { // 使用页面的总DIV 的ID,比如 el-col
allowTaint: true,
useCORS: true,
// scale: 2 // 提升画面质量,但是会增加文件大小
}).then((canvas) => {
// 以下大小经过测试比较合适,可以根据自己的需要,一点点调整
const contentWidth = (canvas.width + 100) * 0.2
const contentHeight = (canvas.height + 100) * 0.2
/* 导出不分页处理 */
const pageData = canvas.toDataURL('image/jpeg', 1.0)
const img = new Image()
img.src = pageData
const imgWidth = (canvas.width) * 0.195
const imgHeight = (canvas.height) * 0.195 // 内容图片这里不需要留白的距离
// 导出pdf
let PDF
img.onload = function() {
if (contentWidth > contentHeight) {
PDF = new JsPDF('l', 'mm', [contentWidth, contentHeight])
} else {
PDF = new JsPDF('p', 'mm', [contentWidth, contentHeight])
}
PDF.addImage(pageData, 'jpeg', 10, 10, imgWidth, imgHeight)
PDF.save(title + '.pdf')
}
return true
})
}
}
}