在做项目时有这么一个需求,需要将当前页面指定区域的内容导出pdf到本地。借助了两个插件分别是html2canvas.js和pdf.js来实现。使用过程中遇到的问题及解决方法
解决一些问题:
npm install html2canvas --save
npm install jspdf --save
JSPDF是一个用于生成PDF文件的客户端JavaScript库。它提供了简单易用的API,使得我们可以在浏览器端创建PDF文件。相比于服务端生成PDF文件,使用JSPDF可以避免服务端的压力,并且能够实现更多的交互与设计效果。基于JSPDF,我们可以生成包括图表、表格、文字、图片、图形等各种元素的PDF文档,同时也可以设置字体、颜色、边框等多种属性来调整文档的样式。
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
export const downloadPDF = page => {
html2canvas(page, {
useCORS: true, //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
allowTaint: true, //允许跨域
scale: 2, 设置放大倍数
backgroundColor: '#ffffff'//背景色
}).then((canvas)=> {
canvas2PDF(canvas);
})
};
const canvas2PDF = canvas => {
// 新建JsPDF对象
const PDF = new jsPDF({
orientation: 'p', //参数: l:横向 p:纵向
unit: 'mm', //参数:测量单位("pt","mm", "cm", "m", "in" or "px")
format: 'a4', //A4纸
})
const ctx = canvas.getContext('2d')
const a4w = 190
const a4h = 277 //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
const imgHeight = Math.floor(a4h * canvas.width / a4w) //按A4显示比例换算一页图像的像素高度
let renderedHeight = 0
while (renderedHeight < canvas.height) {
let page = document.createElement("canvas");
page.width = canvas.width;
page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页
//用getImageData剪裁指定区域,并画到前面创建的canvas对象中
page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);
// canvas转图片数据保留10mm边距
PDF.addImage(page.toDataURL('image/jpeg', 0.2), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width));
renderedHeight += imgHeight;
//判断是否分页,如果后面还有内容,添加一个空页
if (renderedHeight < canvas.height) {
PDF.addPage()
}
}
PDF.save("导出.pdf");
};
如果是直接使用jsPDF生成pdf文件,中文是乱码。
PDF.text('JSPDF是一个用于生成PDF文件的客户端JavaScript库。它提供了简单易用的API,使得我们可以在浏览器端创建PDF文件。', 10, 100);
需要一个支持中文的字体ttf文件,可以在网上下载,也可以使用本地window/font/路径下的文件。
选择你本地的ttf文件,点击“Create”按钮,会生成一个js文件。
在页面中引入js文件
import '@/utils/simhei-normal.js'
PDF.setFont('simhei')
PDF.text('JSPDF是一个用于生成PDF文件的客户端JavaScript库。它提供了简单易用的API,使得我们可以在浏览器端创建PDF文件。', 10, 100);
上面乱码解决了,但是发现中文字不会自动换行。这个还需要进一步解决。
1、使用splitTextToSize解决
//文本内容
const reportTitle = 'JSPDF是一个用于生成PDF文件的客户端JavaScript库。它提供了简单易用的API,使得我们可以在浏览器端创建PDF文件。相比于服务端生成PDF文件,使用JSPDF可以避免服务端的压力,并且能够实现更多的交互与设计效果。基于JSPDF,我们可以生成包括图表、表格、文字、图片、图形等各种元素的PDF文档,同时也可以设置字体、颜色、边框等多种属性来调整文档的样式。'
//设置自动换行
const splitTitle = PDF.splitTextToSize(reportTitle, 190);
//添加文本内容
PDF.text(splitTitle, 10, 110);