最近公司项目需要, 利用 vue 实现 PDF 导出, 从而保存到本地打印出来, 说起来好像也很容易, 具体要怎么实现呢?
1 , 我们要添加两个模块
第一个. 将页面 html 转换成图片
NPM install --save html2canvas
第二个. 将图片生成 PDF
- NPM install jspdf --save
- 2
, 定义全局函数
..
创建一个 htmlToPdf
.JS
文件在指定位置
.
我个人习惯放在
- ('src/utils/htmlToPdf')
- // 导出页面为 PDF 格式
- import html2Canvas from 'html2canvas'
- import JsPDF from 'jspdf'
- export default{
- install (Vue, options) {
- Vue.prototype.getPdf = function () {
- var title = this.htmlTitle
- html2Canvas(document.querySelector('#pdfDom'), {
- allowTaint: true
- }).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) {
- PDF.addImage(pageData, 'JPEG', 0, 0, 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(title + '.pdf')
- }
- )
- }
- }
- }
3, 在 main.JS 中使用我们定义的函数文件.
- import htmlToPdf from '@/components/utils/htmlToPdf'
- Vue.use(htmlToPdf)
- 4
, 在需要的导出的页面
.. 调用我们的 getPdf 方法即可.
- <div class="row" id="pdfDom" style="padding-top: 55px;background-color:#fff;">
- // 给自己需要导出的 ui 部分. 定义 id 为 "pdfDom". 此部分将就是 PDF 显示的部分
- </div>
- <button type="button" class="btn btn-primary"v-on:click="getPdf()"> 导出 PDF</button>
- export default {
- data () {
- return {
- htmlTitle: '页面导出 PDF 文件名'
- }
- }
- }
到这里大家会发现功能是可以实现了, 但是会有个致命的问题, 导出来的 PDF 打印出来还是比较模糊的, 那么, 针对这个问题, 我们要怎么解决呢?
我们的思路是: 将 canvas 的属性 width 和 height 属性放大为 2 倍, 最后将 canvas 的 CSS 样式 width 和 height 设置为原来 1 倍的大小即可, 也就是, 先将 canvas 高分辨率输出, 再来压缩导出打印, 即可, 废话不多说, 完整代码如下:
- // 导出页面为 PDF 格式
- import html2Canvas from 'html2canvas'
- import JsPDF from 'jspdf'
- export default{
- install (Vue, options) {
- Vue.prototype.getPdf = function (dom,title) {
- var title = title
- var c = document.createElement("canvas")
- var opts = {
- scale: 2,
- canvas: c,
- logging: true,
- width: document.querySelector(dom).width,
- height: document.querySelector(dom).height
- };
- c.width = document.querySelector(dom).width * 2
- c.height = document.querySelector(dom).height * 2
- c.getContext("2d").scale(2, 2);
- html2Canvas(document.querySelector(dom), 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) {
- PDF.addImage(pageData, 'JPEG', 0, 0, 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(title + '.pdf')
- }
- )
- }
- }
- }
来源: https://www.cnblogs.com/jsonYoung/p/9806903.html