vue导出单页pdf

本文介绍了在Vue项目中如何利用html2canvas和jspdf库实现单页PDF导出,解决了因页面内容过长导致的分页问题。首先安装所需插件,然后在Vue组件中引入并修改滚动条样式。通过html2canvas捕获整个页面内容,再用jspdf生成PDF。当页面高度大于预设值时,调整图片缩放比例以适应PDF。此外,还提供了一个分页PDF的备用方案。
摘要由CSDN通过智能技术生成

vue项目导出单页pdf

提示:在vue项目中使用html2canvas+jspf导出单页(连续页不分页)pdf

安装插件

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

在需要导出的vue页面中引入

import html2canvas from ‘html2canvas’;
import jsPDF from ‘jspdf’;
import { Loading } from ‘element-ui’; //导出耗时,用来提示的loading

伪html结构

<template>
	<div class="main-page" id="dispatchReportPage">
	<!-- 子页面A-->
	<A/>
	<!-- 子页面B-->
	<B/>
	.....
	</div>
</template>

methods中导出pdf方法

		exportPDF() {
			this.$nextTick(() => {
				// 生成的pdf只有页面窗口可见的区域,有滚动条的下面没有生成出来,需在生成PDF前,改overflow属性auto为visible
				// 获取dom高度、宽度
				var shareContent = document.querySelector('#dispatchReportPage');
				var width = shareContent.offsetWidth / 4;
				var height = shareContent.offsetHeight / 4;
				let _this = this;
				// eslint-disable-next-line
                let loadingInstance = Loading.service({text: '正在导出,请稍等'});
				html2canvas(document.getElementById('dispatchReportPage'), {
					dpi: 900,
					// scrolly: 0,
					// width:eleW,//生成后的宽度
					// height:eleH,//生成后的高度
					// scrollx: -10,
					useCORS: true, //允许canvas画布内可以跨域请求外部链接图片, 允许跨域请求。

					// backgroundColor: null //避免图片有白色边框
				}).then((canvas) => {
					var context = canvas.getContext('2d');
					context.mozImageSmoothingEnabled = false;
					context.webkitImageSmoothingEnabled = false;
					context.msImageSmoothingEnabled = false;
					context.imageSmoothingEnabled = false;
					var pageData = canvas.toDataURL('image/jpeg', 1.0);
					var img = new Image();
					img.src = pageData;
					img.onload = ()=> {
						// 获取dom高度、宽度
						img.width = img.width / 2;
						img.height = img.height / 2;
						img.style.transform = 'scale(0.5)';
						if (width > height) {
							// 此可以根据打印的大小进行自动调节
							// eslint-disable-next-line
							var pdf = new jsPDF('l', 'mm', [width * 0.505, height * 0.545]);
						} else {
							// eslint-disable-next-line
							var pdf = new jsPDF('p', 'mm', [width * 0.505, height * 0.545]);
						}
						pdf.addImage(pageData, 'jpeg', 0, 0, width * 0.505, height * 0.545);
						pdf.save('名字'  + '.pdf');
						loadingInstance.close();
					};
				});
			});

			//
		},

1.采用**单页**导是由于页面由二十几页组成长度较高,且页面中子组件页面高度不固定,采用分页导出导致有的子组件页 面被截断

2.采用单页面导出整个页面,html2canvas导出是否有最大长度限制未知, pdf.addImage(pageData, 'jpeg', 0, 0, width * 0.505, height * 0.545),中height值可适当调整

3.页面中有滚动条时需要将带有滚动条的区域去掉滚动条再导出,overflow:visible

有bug欢迎留言讨论

番外分页pdf

   Vue.prototype.pageToPdf = function (ele, pdfFileName) {
            console.log(ele.clientHeight, 'clientHeight ')
            let loadingInstance = Loading.service({text: '正在导出,请稍等'});
            let eleW = ele.offsetWidth // 获得该容器的宽
            //   let eleH = ele.offsetHeight // 获得该容器的高
            let eleH = ele.scrollHeight // 获得该容器的高
            let eleOffsetTop = ele.offsetTop // 获得该容器到文档顶部的距离
            let eleOffsetLeft = ele.offsetLeft // 获得该容器到文档最左的距离
            var canvas = document.createElement('canvas')
            var abs = 0
            let win_in = document.documentElement.clientWidth || document.body.clientWidth // 获得当前可视窗口的宽度(不包含滚动条)
            let win_out = window.innerWidth // 获得当前窗口的宽度(包含滚动条)
            if (win_out > win_in) {
                // abs = (win_o - win_i)/2;    // 获得滚动条长度的一半
                abs = (win_out - win_in) / 2 // 获得滚动条宽度的一半
            }
            canvas.width = eleW * 2 // 将画布宽&&高放大两倍
            canvas.height = eleH * 2
            var context = canvas.getContext('2d')
            context.scale(2, 2) // 增强图片清晰度
            context.translate(-eleOffsetLeft - abs, -eleOffsetTop)
            window.pageYOffset = 0;
            document.documentElement.scrollTop = 0
            document.body.scrollTop = 0;
            html2canvas(ele, {
                dpi: 900,
                // scrolly: 0,
                // width:eleW,//生成后的宽度
                // height:eleH,//生成后的高度
                // scrollx: -10,
                useCORS: true, //允许canvas画布内可以跨域请求外部链接图片, 允许跨域请求。

                // backgroundColor: null //避免图片有白色边框

            }).then(canvas => {
                var contentWidth = canvas.width
                var contentHeight = canvas.height
                //一页pdf显示html页面生成的canvas高度;
                var pageHeight = (contentWidth / 552.28) * 841.89 // 这样写的目的在于保持宽高比例一致 pageHeight/canvas.width = a4纸高度/a4纸宽度// 宽度和canvas.width保持一致
                //未生成pdf的html页面高度
                var leftHeight = contentHeight + 10591
                //页面偏移
                var position = 0
                // 设置pdf的尺寸,pdf要使用pt单位 已知 1pt/1px = 0.75   pt = (px/scale)* 0.75
                // 2为上面的scale 缩放了2倍
                // var pdfX = ((contentWidth + 10) / 2) * 0.75
                // var pdfY = ((contentHeight + 500) / 2) * 0.75 // 500为底部留白
                var imgWidth = ((contentWidth + 10) / 2) * 0.75
                var imgHeight = (imgWidth / contentWidth) * contentHeight
                console.log(imgHeight)
                //a4纸的尺寸[595.28,841.89],单位像素,html页面生成的canvas在pdf中图片的宽高
                var pageData = canvas.toDataURL('image/jpeg', 1.0)
                console.log(pageData, '============================')

                var pdf = JsPDF('', 'px', [imgWidth , 874.2])
                //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                //当内容未超过pdf一页显示的范围,无需分页
                // pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
                // 分页

                while (leftHeight > 0) {
                    pdf.addImage(pageData, "JPEG", 5, position, imgWidth, imgHeight)
                    leftHeight -= pageHeight
                    position -= 874.8
                    //避免添加空白页
                    if (leftHeight > 0) {
                        pdf.addPage()
                    }
                }
                pdf.save(pdfFileName + '.pdf')
                this.$nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
                    loadingInstance.close();
                });
            })
        }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@才华有限公司

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值