赞
踩
简单的记录一下再vue中使用html2canvas结合jsPDF实现对页面转pdf功能的实现,主要是通过html2canvas将页面转化为高清的图片,后在进行导出pdf,话不多说,直接上代码
注意:如果使用的是uniapp的话,需要将div替换成view,以下代码可直接使用
第一步:通过npm安装html2canvas和jsPDF
- npm install --save htmlcanvas2
- npm install --save jspdf
第二步:则是在需要的页面引入后,通过$refs获取需要转成pdf容器的dom元素 ,通过html2canvas将页面转化为高清图片后在通过jsPDF导出为pdf文件(以下代码复制可直接使用)
- <template>
- <div>
- <div @click="print" class="btn">转PDF</div>
- <div ref="box" class="box">
- <div class="item" v-for="item in data">{{item.title}}</div>
- </div>
- </div>
- </template>
-
- <script>
- import html2canvas from 'html2canvas'
- import jsPDF from 'jspdf'
- export default {
- data() {
- return {
- data: [{
- title: '这是第一页',
- }, {
- title: '这是第二页',
- }]
- }
- },
- components: {
-
- },
- methods: {
- async print() {
- const el = this.$refs.box.$el
- html2canvas(el, {
- logging: false,
- background: '#fff',
- allowTaint: true,
- taintTest: false,
- height: el.scrollHeight,
- width: el.scrollWidth,
- useCORS: true, //允许canvas画布内可以跨域请求外部链接图片, 允许跨域请求。
- dpi: 300, // 提升导出的文件的分辨率
- scale: 5
- }).then(canvas => {
- var canvasWidth = canvas.width; //图片容器宽度
- var canvasHeight = canvas.height; //图片容器高度
- let pagesHeight = '' //页面高度
- let leftHeight = canvasHeight //未生成pdf的高度
- var position = 0 //页面偏移
- var imgWidth = 0
- var imgHeight = 0
- pagesHeight = canvasWidth / 592.28 * 841.89
- imgWidth = 592.28;
- imgHeight = 592.28 / canvasWidth * canvasHeight;
- var pdf = new jsPDF('', 'pt', 'a4', true);
- var pageData = canvas.toDataURL('image/jpeg', 1.0);
- //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
- //当内容未超过pdf一页显示的范围,无需分页
- if (leftHeight < pagesHeight) {
- pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight, '', 'FAST')
- } else {
- while (leftHeight > 0) {
- pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight, '',
- 'FAST')
- leftHeight -= pagesHeight;
- position -= 841.89;
- //避免添加空白页
- if (leftHeight > 0) {
- pdf.addPage();
- }
- }
- }
- pdf.save('1')
- //此处为保存到本地的pdf操作,如果需要上传到服务器的话,则在这个位置加入第三步代码替换pdf.save('1')
- })
- },
- }
- }
- </script>
- <style>
- .btn {
- height: 50px;
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: palegreen;
- }
-
- .box {
- background-color: paleturquoise;
- font-size: 18px;
- font-weight: 700;
- width: 592px;
- }
-
- .box .item {
- height: 841px;
- }
- </style>
第三步:以上代码只能简单的实现转pdf后下载到本地,如果需要实现通过后端接口上传到服务器的话, 则需要转base64后通过转文件流的形式调用后端接口上传到服务器
①将此处代码替换第二步中的pdf.save('1')
- let base64 = pdf.output("datauristring")
- let file = this.convertBase64ToFile(base64, '转pdf的文件名称')
②以下方法为将pdf转化为file文件流代码
- // base64转文件
- convertBase64ToFile(urlData, filename) {
- var arr = urlData.split('base64,');
- var type = arr[0].match(/:(.*?);/)[1];
- var fileExt = type.split('/')[1];
- var bstr = atob(arr[1]);
- var n = bstr.length;
- var u8arr = new Uint8Array(n);
- while (n--) {
- u8arr[n] = bstr.charCodeAt(n);
- }
- return new File([u8arr], filename + "." + fileExt, {
- type: type
- });
- },
第四步:可以结合element中的upLoad实现上传,以下实例为使用uniapp中的uni.uploadFile()实现文件的上传
①uniapp中的uni.uploadFile()实现文件的上传
- uni.uploadFile({
- url: 'xxxx', //上传地址
- file: file, //文件对应第三步中的let file = this.convertBase64ToFile(base64, '转pdf的文件名称')
- name: 'file',
- formData: {
- id: '123456',
- }, //其他参数
- success: () => {
-
- } //成功后的回调
- })
②其他上传实现可参考element组件或者原生请求方式(后续有时间再进行更新)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。