html2canvas jspdf将html转pdf
小伟0718 人气:0A4尺寸
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里边的图片 可以正常显示了 也不报跨域的问题了
总结
加载全部内容