vue+jspdf+html2canvas导出PDF文件,并将字体放大
今天开始实现日结单这个功能,日结单是允许打印的,所以我们需要将日结单以PDF的形式导出,我做的是Vue单页应用,于是查找了一番Vue如何导出PDF,看了几篇博客,实现了PDF的导出。主要实现思路是通过html2canvas和jspdf这两个模块,先将页面转换成图片,再将图片放入PDF文件中。
一、首先添加两个模块:
cnpm install html2canvas --save
cnpm install jspdf --save
二、定义全局函数..创建一个htmlToPdf.js文件在指定位置,比如你可以放在(‘@/components/utils/htmlToPdf‘),该文件内容如下
// 导出页面为PDF格式
import html2canvas from "html2canvas"
import JSPDF from "jspdf"
export default {
install(Vue, options) {
Vue.prototype.ExportSavePdf = function(htmlTitle, currentTime) {
var element = document.getElementById("pdfCentent")
html2canvas(element, {
logging: false
}).then(function(canvas) {
var pdf = new JSPDF("p", "mm", "a4") // A4纸,纵向
var ctx = canvas.getContext("2d")
var a4w = 170;
var a4h = 257 // A4大小,210mm x 297mm,四边各保留20mm的边距,显示区域170x257
var imgHeight = Math.floor(a4h * canvas.width / a4w) // 按A4显示比例换算一页图像的像素高度
var renderedHeight = 0
while (renderedHeight < canvas.height) {
var 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)
pdf.addImage(page.toDataURL("image/jpeg", 1.0), "JPEG", 10, 10, a4w, Math.min(a4h, a4w * page.height /
page.width)) // 添加图像到页面,保留10mm边距
renderedHeight += imgHeight
if (renderedHeight < canvas.height) {
pdf.addPage()
} // 如果后面还有内容,添加一个空页
// delete page;
}
pdf.save(htmlTitle + currentTime)
})
}
}
}
三、在main.js文件中引用我们定义的全局函数
import htmlToPdf from ‘@/components/utils/htmlToPdf‘
Vue.use(htmlToPdf)
四、在组件中使用即可
<template>
<div>
<div id="pdfContent">
<p>需要生成pdf的内容</p>
</div>
<el-button type="danger" @click="getPdf(htmlTitle,currentTime)">导出PDF</el-button>
</div>
</template>
<script>
export default {
data() {
return {
htmlTitle:‘PDF名称‘,
currentTime:‘‘
}
},
methods: {
}
}
</script>
<style>
</style>
实际效果如下图所示:
这样子其实已经差不多了,但是可能是我的笔记本分辨率太高了,我觉得字体有些小,我想到的有两种解决方案:
① 设置组件中元素的style,将font-size调大
② 将图片的内容进行放大,但不改变图片的高和宽
毫无疑问肯定选第二种,因为我们是先在网页上进行日结单的预览,然后再点击打印按钮进行打印,如果在页面上把字体调大,预览的时候体验会非常差。
看了一篇博客,对我的帮助很大, https://www.cnblogs.com/jsonYoung/p/9806903.html,虽然这个老哥的htmlToPdf.js文件内容是有问题的,但是他的思路很正确,将canvas的属性width和height属性放大为2倍,最后将canvas的css样式width和height设置为原来1倍的大小即可。
我修改了一下这位老哥的htmlToPdf.js文件,代码如下:
// 导出页面为PDF格式
import html2Canvas from ‘html2canvas‘
import JsPDF from ‘jspdf‘
export default {
install(Vue, options) {
Vue.prototype.getPdf = function(title) {
var element = document.getElementById("pdfContent")
var title = title; //PDF文件标题
var c = document.createElement("canvas");//创建照片
var opts = {
scale: 2,
canvas: c,
logging: true,
width: element.clientWidth,
height: element.clientHeight
};
//照片高度和宽度是页面元素的两倍
c.width = element.clientWidth * 2
c.height = element.clientHeight * 2
c.getContext("2d").scale(2, 2);
html2Canvas(element, opts)
.then(function(canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL(‘image/jpeg‘, 1.0)
let PDF = new JsPDF(‘‘, ‘pt‘, ‘a4‘)
if (leftHeight < pageHeight) {
//第一个20是img和pdf页面的左边距,第二个20是img与pdf页面的上边距
PDF.addImage(pageData, ‘JPEG‘, 20, 20, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, ‘JPEG‘, 20, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save(title + ‘.pdf‘)
})
}
}
}
组件代码如下:
<template>
<div>
<div id="pdfContent">
<p>需要生成pdf的内容</p>
</div>
<el-button type="danger" @click="getPdf(title)">导出PDF</el-button>
</div>
</template>
<script>
export default {
data() {
return {
title:‘PDF名称‘,
}
},
methods: {
}
}
</script>
<style>
</style>
最终效果如图所示,左边的字体是经过放大的,我个人觉得是满足我的需求了,字体不大不小,之前那个字体就太小了。看着不舒服。
文章来自:https://www.cnblogs.com/N1ckeyQu/p/11382195.html