vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > html2canvas jspdf将html转pdf

vue使用html2canvas和jspdf将html转成pdf

作者:小伟0718

在前端开发中, html转pdf是最常见的需求,下面这篇文章主要给大家介绍了关于vue如何使用html2canvas和jspdf将html转成pdf的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

A4尺寸

A4纸的尺寸是210mm×297mm。

分辨率是72像素/英寸时,A4纸的尺寸的图像的像素是595×842(推荐用这个大小比例)。

分辨率是150像素/英寸时,A4纸的尺寸的图像的像素是1240×1754。

分辨率是300像素/英寸时,A4纸的尺寸的图像的像素是2479×3508。

选择不同的分辨率图像像素大小也会随之变化

安装插件html2canvas和jspdf

npm install html2canvas--save
npm install jspdf --save

html2canvas可以通过获取HTML的某个元素,然后生成Canvas,能让用户保存为图片。

jsPDF 是一个基于 HTML5 的客户端解决方案,用于生成各种用途的 PDF 文档。

在项目中引入

在utils 中 新建htmltopdf.js

htmlToPdf.js

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default{
  install (Vue, options) {
    Vue.prototype.getPdf = function () {
      var pdfTitle = this.pdfTitle  //pdf的名称
      var pdfDom = document.querySelector('#pdfDom')
      html2Canvas(pdfDom, {
        allowTaint: true
      }).then(function (canvas) {
        console.log(canvas)
        const marginBottom = 34    // 项目页面显示微处理 以下用到的地方 可以忽略
        let canvasWidth = canvas.width 	//页面生成canvas宽度
        let canvasHeight = canvas.height + marginBottom //页面生成canvas高度
        let pageHeight = canvasWidth / 592.28 * 841.89 + marginBottom   //分页 每页的高度
        let allPageHeight = canvasHeight  // 所有页面的高度
        let position = 0 //偏移量
        let imgWidth = 595.28 //生成canvas 图片的宽度
        let imgHeight = 592.28 / canvasWidth * canvasHeight //生成canvas 图片的高度
        let pageData = canvas.toDataURL('image/jpeg', 3.0)
        // console.log(canvasWidth)
        // console.log(canvasHeight)
        // console.log(pageHeight)
        // console.log(allPageHeight)
        // console.log(position)
        // console.log(imgWidth)
        // console.log(imgHeight)
        // console.log(pageData)
        let PDF = new JsPDF('', 'pt', 'a4')
        if (allPageHeight < pageHeight) {
          PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        } else {
          // 循环生成分页
          while (allPageHeight > 0) {
            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
            allPageHeight = allPageHeight - pageHeight - marginBottom
            position = position - 841.89 - marginBottom
            if (allPageHeight > 0) {
              PDF.addPage() //添加新的一页
            }
          }
        }
        PDF.save(pdfTitle + '.pdf')  //保存pdf
      })
    }
  }
}

在main.ts 中 全局引入

main.ts

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import 'babel-polyfill'
import Vue from 'vue'
import App from './App.vue'
import router from './router/index.ts'
import store from './store/index.js'
import * as ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import htmlToPdf from '@/utils/htmlToPdf.js'
// 使用Vue.use()方法就会调用工具方法中的install方法
Vue.use(htmlToPdf)
// import 'swiper/dist/css/swiper.css'
// import * as VueAwesomeSwiper from 'vue-awesome-swiper'
// Vue.use(VueAwesomeSwiper)
Vue.config.productionTip = false
Vue.use(ElementUI)
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

vue 页面

<template>
  <div class="transcript-container clearfix transcript-detail" @mouseenter.stop="pdfFlag = false">
    <div class="creat-pdf clearfix" @click.stop="pdfFlag = true;getPdf('#pdfDom')">下载pdf</div>
    <div id="pdfDom" class="clearfix" style="width: 210mm;margin: auto;"> </div>
  </div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import { Getter, Action } from 'vuex-class'
@Component
export default class cousrseActivity extends Vue {
  @Getter commonData
  @Action transcriptDetail
  $refs: {
    onePage: HTMLElement,
    twoPage: HTMLElement
  }
  pdfTitle: string = ''
}
</script>
//对打印 做的 兼容
<style media="print" type="text/css">
  @page {
    size: auto;
    margin: 0mm;
  }
  /* 在chrome下可以使用background属性 */
  body {
    -webkit-print-color-adjust: exact;
  }
  @media print {
    .transcript-container.transcript-detail .transcript-wrap {
      margin-bottom: 0;
    }
  }
</style>

遇到的问题

多行省略号

多行省略号 在html2canvas 时 由于不能解析 display: -webkit-box; 会导致生成的图片 错误

.ellipsis{
  overflow : hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;      /* 可以显示的行数,超出部分用...表示*/
  -webkit-box-orient: vertical;
 }

目前 我这边正常显示时 使用多行省略号 在打印时 将 display: -webkit-box;改成display:blcok 就能正常显示了

图片模糊 生成的pdf 不清楚

解决办法: 将canvas的属性width和height属性放大为2倍,也就是,先将canvas高分辨率输出,再来压缩导出打印

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default{
  install (Vue, options) {
    Vue.prototype.getPdf = function () {
      var pdfTitle = this.pdfTitle
      var pdfDom = document.querySelector('#pdfDom')
      var c = document.createElement('canvas')
      html2Canvas(pdfDom, {
        useCORS: true,
        scale: 2,
        canvas: c,
        logging: true,
        width: pdfDom.width,
        height: pdfDom.height
      // allowTaint: true
      }).then(function (canvas) {
        console.log(canvas)
        const marginBottom = 34
        let canvasWidth = canvas.width
        let canvasHeight = canvas.height + marginBottom * 2
        console.log(canvasWidth)
        console.log(canvasHeight)
        let pageHeight = canvasWidth / 592.28 * 841.89 + marginBottom * 2
        let allPageHeight = canvasHeight
        let position = 0
        let imgWidth = 595.28
        let imgHeight = 592.28 / canvasWidth * canvasHeight
        let pageData = canvas.toDataURL('image/jpeg', 3.0)
        // console.log(canvasWidth)
        // console.log(canvasHeight)
        // console.log(pageHeight)
        // console.log(allPageHeight)
        // console.log(position)
        // console.log(imgWidth)
        // console.log(imgHeight)
        // console.log(pageData)
        let PDF = new JsPDF('', 'pt', 'a4')
        if (allPageHeight < pageHeight) {
          PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        } else {
          while (allPageHeight > 0) {
            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
            allPageHeight = allPageHeight - pageHeight - marginBottom
            position = position - 841.89 - marginBottom
            if (allPageHeight > 0) {
              PDF.addPage()
            }
          }
        }
        PDF.save(pdfTitle + '.pdf')
      })
    }
  }
}

处理过的图片 能清晰一点 但是生成的pdf 也大了一倍

图片跨域 Tained canvases may not be exported

在test 服务器上 一点问题都没有 可以正常下载 一大包到线上 就开始报跨域的错误

百度了一下 基本都是一样的 复制来 复制去 给的办法 还是没发处理跨域的问题

看了一下html2canvas api 发现了 一个属性 proxy 代理完的图片 但是还是报跨域的问题 生成的pdf 还是没有图片

最后发现 页面里边的图片可以正产显示 只有外域的图片不能显示 本域的图片用base64显示的 外域的图片是不是也能用base64显示

base64 Data URL scheme 支持的类型:

将外域 的图片弄成base64 后 生成的pdf里边的图片 可以正常显示了 也不报跨域的问题了

总结

到此这篇关于vue使用html2canvas和jspdf将html转成pdf的文章就介绍到这了,更多相关html2canvas jspdf将html转pdf内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文