vue使用html2canvas和jspdf将html转成pdf

作者:小伟0718

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

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>
</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组织架构树图组件vue-org-tree的使用解析
    Vue组织架构树图组件vue-org-tree的使用解析
    2022-08-08
  • ElementUI中利用table表格自定义表头Tooltip文字提示
    ElementUI中利用table表格自定义表头Tooltip文字提示
    2022-07-07
  • vue选择下拉框动态变化表单方式
    vue选择下拉框动态变化表单方式
    2022-08-08
  • Vue中使用stylus报错的解决
    Vue中使用stylus报错的解决
    2022-08-08
  • elementui中使用el-tabs切换实时更新数据
    elementui中使用el-tabs切换实时更新数据
    2022-08-08
  • 关于Vite项目打包后浏览器兼容性问题的解决方案
    关于Vite项目打包后浏览器兼容性问题的解决方案
    2022-08-08
  • Vue 中 provide和inject的使用
    Vue 中 provide和inject的使用
    2022-08-08
  • 使用vue和element-ui上传图片及视频文件方式
    使用vue和element-ui上传图片及视频文件方式
    2022-08-08
  • 美国设下计谋,用娘炮文化重塑日本,已影响至中国
    美国设下计谋,用娘炮文化重塑日本,已影响至中国
    2021-11-19
  • 时空伴随者是什么意思?时空伴随者介绍
    时空伴随者是什么意思?时空伴随者介绍
    2021-11-09
  • 工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    2021-11-05
  • 2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2021-10-26
  • 电脑版 - 返回首页

    2006-2023 脚本之家 JB51.Net , All Rights Reserved.
    苏ICP备14036222号