目录

jspdf前端html生成pdf的两种办法-以及-引入中文字体

【jspdf】前端html生成pdf的两种办法 以及 引入中文字体

导出pdf有下面两种方法

1、使用canvas把html生成图片,然后使用jspdf生成pdf。优点:生成的pdf 样式还原度极高,缺点:图片形式的pdf无法编辑

2、直接使用jspdf的html方法直接把html生成pdf。优点:可编辑,缺点:只是把文本内容搂出来生成pdf,也就是说样式基本无,而且jspdf不支持中文字体的,如果有中文字体需要一 一引入字体

一、从图片导出pdf

1、安装插件html2canvas、jspdf

 yarn add jspdf
yarn add html2canvas

2、使用

//html使用的是Ant Design Vue框架,pdf_content为生成canvas区域
<div ref="pdf_content">
     <a-table :loading="loading" :dataSource="dataSource" :columns="columns" :pagination="ipagination" @change="handleTableChange" /> 
</div>
// js
import html2canvas from 'html2canvas'
import JsPDF from 'jspdf'
getpdf() { // 未分页
const pdf_content = this.$refs.pdf_content
html2canvas(pdf_content, {backgroundColor: '#fff', useCORS: true}).then((canvas) => { // 获取图片
const dataURL = canvas.toDataURL('image/png')
console.log(dataURL) // 生成的图片
var contentWidth = canvas.width
var contentHeight = canvas.height
// 一页 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 = 595.28
var imgHeight = (595.28 / contentWidth) _ contentHeight
var 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', 左,上,宽度,高度)设置在 pdf 中显示;
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
// pdf.addImage(pageData, 'JPEG', 20, 40, imgWidth, imgHeight);
} else {
// 分页
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
// 避免添加空白页
if (leftHeight > 0) {
pdf.addPage()
}
}
}
pdf.save('订单列表')
})
}

三、可能出现的问题

Ant Design Vue 框架的分页组件中的一个样式影响了 html2canvas,生成图片会缺失数字部分,如下图

https://i-blog.csdnimg.cn/blog_migrate/24a2ef1b2344caebdf26c1540678e936.png

https://i-blog.csdnimg.cn/blog_migrate/453780ddd7e2451eb63d62391775d293.png

a 标签中的 display: block;样式会导致导出图片中 a 标签内的内容没有显示成功,需要手动修改样式

/deep/ .ant-pagination-item a {
display: unset;
}

二、html 方法直接把 html 生成 pdf

1、引入字体

点击下载项目到本地,打开下面的文件

https://i-blog.csdnimg.cn/blog_migrate/2003f5072476b26d261628dd73037908.png

打开 fontconverter,页面如下图

https://i-blog.csdnimg.cn/blog_migrate/9d8356d92a7cf2b25d0ea18671febb65.png

选择需要的字体的 ttf 文件,点击选择文件进行上传转换(一些字体可以在电脑本地找到地址:C:\Windows\Fonts)

https://i-blog.csdnimg.cn/blog_migrate/ccb7db04b82822ab1036b557f36f552d.png

上传后点击 Create 下载一个 js 文件,把这个文件放在项目中

https://i-blog.csdnimg.cn/blog_migrate/63896e119b3f8acb8e3781fcbb4f5c4b.png

在页面引入字体: require("@/utils/simhei-normal"); 字体转为 js 的时候都处理好了,只需要引入就可以直接使用了

https://i-blog.csdnimg.cn/blog_migrate/b14c7d6baa36a90f8d85a345cedcee13.png

在生成 pdf 之前使用 pdf.setFont("simhei"); 设置字体即可

2、生成 pdf

 var pdf = new jsPDF("x", "pt", [595, 750]);
pdf.setFont("simhei"); // 使用字体
const source = document.getElementsByClassName("content")[0];
var options = {
pagesplit: false, //设置是否自动分页
background: "#FFFFFF", //如果导出的 pdf 为黑色背景,需要将导出的 html 模块内容背景 设置成白色。
};
await pdf.html(source, {
callback: function (pdf1) {
pdf1.save("test.pdf");
},
margin: [30, 0, 30, 0],
});
pdf.save("test.pdf");