vue使用html2canvas和jspdf将html转成pdf

 更新时间:2022年03月04日 09:50:08   作者:小伟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 支持的类型:

  • data:,文本数据
  • data:text/plain,文本数据
  • data:text/html,HTML代码
  • data:text/html;base64,base64编码的HTML代码
  • data:text/css,CSS代码
  • data:text/css;base64,base64编码的CSS代码
  • data:text/JavaScript,Javascript代码
  • data:text/javascript;base64,base64编码的Javascript代码
  • data:image/gif;base64,base64编码的gif图片数据
  • data:image/png;base64,base64编码的png图片数据
  • data:image/jpeg;base64,base64编码的jpeg图片数据

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

总结

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

相关文章

  • 关于vue-admin-element中的动态加载路由

    关于vue-admin-element中的动态加载路由

    这篇文章主要介绍了关于vue-admin-element的动态加载路由,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • vue动态绘制四分之三圆环图效果

    vue动态绘制四分之三圆环图效果

    这篇文章主要介绍了vue动态绘制四分之三圆环图效果,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • Vue之Computed依赖收集与更新原理分析

    Vue之Computed依赖收集与更新原理分析

    这篇文章主要介绍了Vue之Computed依赖收集与更新原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • vue中组件的过渡动画及实现代码

    vue中组件的过渡动画及实现代码

    这篇文章主要介绍了vue中组件的过渡动画,并通过实例代码给大家介绍了过渡动画的实例代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-11-11
  • 详解vue中router-link标签所必备了解的属性

    详解vue中router-link标签所必备了解的属性

    这篇文章主要介绍了vue中router-link标签所必备了解的属性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • vue的路由守卫和keep-alive后生命周期详解

    vue的路由守卫和keep-alive后生命周期详解

    这篇文章主要为大家详细介绍了vue路由守卫和keep-alive,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Vue中的计算属性computed传参方式

    Vue中的计算属性computed传参方式

    这篇文章主要介绍了Vue中的计算属性computed传参方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Vue学习之路之登录注册实例代码

    Vue学习之路之登录注册实例代码

    本篇文章主要介绍了Vue学习之路之登录注册实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 使用vue-element-admin框架调用后端接口及跨域的问题

    使用vue-element-admin框架调用后端接口及跨域的问题

    这篇文章主要介绍了使用vue-element-admin框架调用后端接口及跨域的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Vue 打包的静态文件不能直接运行的原因及解决办法

    Vue 打包的静态文件不能直接运行的原因及解决办法

    这篇文章主要介绍了Vue 打包的静态文件不能直接运行的原因及解决办法,帮助大家更好的理解和学习vue框架,感兴趣的朋友可以了解下
    2020-11-11

最新评论