在uni中使用vue3写h5的pdf导出

这篇具有很好参考价值的文章主要介绍了在uni中使用vue3写h5的pdf导出。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

先安装依赖

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

把dom转canvas,屏幕截图基于 DOM,因此可能不是 100% 准确到真实表示,因为它不会制作实际的屏幕截图,而是根据页面上可用的信息构建屏幕截图。

components/pdf  创建pdf文件夹


import html2canvas from 'html2canvas'
import JsPDF from 'jspdf'

export default {
	install: (Vue, options) => {
		/**
		 * targetDom: 需要打印的dom对象
		 * name:pdf的名字
		 * callback: 回调函数
		 */
		Vue.config.globalProperties.$createPdf = (targetDom, name, callback) => {
			console.log(window.devicePixelRatio * 4)
			// a4纸的尺寸[592.28,841.89]
			uni.showLoading({
				title: '导出中'
			})
			const A4_WIDTH = 592.28
			const A4_HEIGHT = 841.89
			// 每页pdf 相对于A4纸张的页面所对应的高度
			let pageHeight = targetDom.scrollWidth / A4_WIDTH * A4_HEIGHT
			//将dom对象复制一份出来,我们要对dom对象的大小进行调整,不能影响原页面dom对象的样式
			let cloneDom = targetDom.cloneNode(true)
			cloneDom.style.width = targetDom.scrollWidth + 'px'
			cloneDom.style.background = '#FFFFFF'
			// cloneDom.style.display = 'none'
			document.body.appendChild(cloneDom)
			//这里划重点,将页面中的预计生成一页的div设置一个单独的class,然后根据class获取到所有的节点,即可大致知道将要生成多少页的PDF
			let pages = cloneDom.childNodes
			//遍历一次这些节点
			for (let i = 0; i < pages.length; i++) {
				//判断每个页面的节点对象,高度是否大于或小于实际的PDF的高度,如果大于PDF每页的高度,那这个节点最少也要生成2页的PDF,切不能影响下面的节点的,用节点对象的高度/PDF每页的高度,向上取整获取到倍数,然后设置该节点的高度为:PDF每页的高度*倍数,如果节点高度小于PDF每页的高度,直接将该节点高度设置成PDF每页的高度即可
                //  有可能pages[i]下没有offsetHeight属性 得判断
				if (pages[i].offsetHeight > pageHeight) {
					// let num = Math.ceil(pages[i].offsetHeight / pageHeight)
					console.log(pages[i].style,'*-*-*-')
					// pages[i].style.height = pageHeight * num + 'px'
				} else {
					// pages[i].style.height = pageHeight + 'px'
				}
				//页面中每页的div之间有间隔,将这个间隔去掉
				// pages[i].style.marginBottom = 0 + 'px'
			}
			html2canvas(cloneDom, {
				scale: 4, // 提升画面质量,但是会增加文件大小
				useCORS: true, // 允许跨域图片 当图片是链接地址时,需加该属性,否组无法显示图片
				imageTimeout: 0, // 图片加载延迟,默认延迟为0,单位毫秒
				height: cloneDom.scrollHeight, // canvas的高度设定,这里的宽高要用复制出来的dom对象的宽高,不能用原dom对象,因为我们已经将dom的高度整体拉高了
				width: cloneDom.scrollWidth, // canvas的宽度设定
				windowWidth: document.body.scrollWidth,
				windowHeight: document.body.scrollHeight,
				dpi: 172, // 将分辨率提高到特定的DPI
				logging: false,
				allowTaint: false,
			}).then(canvas => {
				document.body.removeChild(cloneDom) // 移除节点否者会多出一份
				const _this = this;
				//未生成pdf的html页面高度
				var leftHeight = canvas.height;
				var a4Width = 555.28 // 原A4宽 592 因为要设置边距 20 ,这里要减掉 40
				var a4Height = 801.89 // 原A4高   841 因为要设置边距 20 ,这里要减掉 40
				//一页pdf显示html页面生成的canvas高度;
				var a4HeightRef = Math.floor(canvas.width / a4Width * a4Height);

				//pdf页面偏移
				var position = 0;

				var pageData = canvas.toDataURL('image/jpeg', 1.0);

				var pdf = new JsPDF('x', 'pt', 'a4');
				var index = 1,
					canvas1 = document.createElement('canvas'),
					height;
				pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen');

				function createImpl(canvas) {
					if (leftHeight > 0) {
						index++;
						var checkCount = 0;
						if (leftHeight > a4HeightRef) {
							var i = position + a4HeightRef;
							for (i = position + a4HeightRef; i >= position; i--) {
								var isWrite = true
								for (var j = 0; j < canvas.width; j++) {
									var c = canvas.getContext('2d').getImageData(j, i, 1, 1).data

									if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
										isWrite = false
										break
									}
								}
								if (isWrite) {
									checkCount++
									if (checkCount >= 10) {
										break
									}
								} else {
									checkCount = 0
								}
							}
							height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
							if (height <= 0) {
								height = a4HeightRef;
							}
						} else {
							height = leftHeight;
						}

						canvas1.width = canvas.width;
						canvas1.height = height;

						// console.log(index, 'height:', height, 'pos', position);

						var ctx = canvas1.getContext('2d');
						ctx.drawImage(canvas, 0, position, canvas.width, height, 0, 0, canvas.width,
							height); // 边距这里设置0,不然又黑边

						var pageHeight = Math.round(a4Width / canvas.width * height);
						// pdf.setPageSize(null, pageHeight)
						if (position != 0) {
							pdf.addPage();
						}
						// 设置 20px 边距
						pdf.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 20, 20, a4Width, a4Width / canvas1
							.width * height);
						leftHeight -= height;
						position += height;
						// $('.pdfProgress').text(index + 1);
						// $('.pdfTotal').text(index + Math.ceil(leftHeight / a4HeightRef));
						if (leftHeight > 0) {

							for (let i = 0; i < 6; i++) {
								for (let j = 0; j < 5; j++) {
									const left = (j * 120) + 20;
									// pdf.addImage(base64,'JPEG', left, i*150, 20, 30); // 关掉水印
								}
							}
							setTimeout(createImpl, 500, canvas);
						} else {
							pdf.save('下载pdf文件名' + '.pdf');
							uni.hideLoading()
						}
					}
				}

				//当内容未超过pdf一页显示的范围,无需分页
				if (leftHeight < a4HeightRef) {
					pdf.addImage(pageData, 'JPEG', 20, 20, a4Width, a4Width / canvas.width * leftHeight);
					pdf.save('下载pdf文件名' + '.pdf')
					uni.hideLoading()
				} else {
					try {
						pdf.deletePage(0);
						setTimeout(createImpl, 500, canvas);

					} catch (err) {
						console.log(err);
					}
				}
			})
		}
	}
}

 建议使用这一种

import html2canvas from 'html2canvas'
import JsPDF from 'jspdf'

export default {
	install: (Vue, options) => {
		/**
		 * targetDom: 需要打印的dom对象
		 * name:pdf的名字
		 * callback: 回调函数
		 */
		Vue.config.globalProperties.$createPdf = async(targetDom, name, callback) => {
			 var shareContent = targetDom;
			  var width = shareContent.offsetWidth / 4;
			  var height = shareContent.offsetHeight / 4;
			  let canvas = await html2canvas(targetDom, { useCORS: true });
			  var context = canvas.getContext("2d");
			  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");
			  pdf.save(name + ".pdf");
			 
			  return false
		}
	}
}

在main文件中引入

import htmlToPdf from '@/components/pdf/pdf.js'

app.use(htmlToPdf);

在需要的页面绑定id  事件文章来源地址https://www.toymoban.com/news/detail-586252.html

	import {
		getCurrentInstance
	} from 'vue';

	const {
		appContext
	} = getCurrentInstance();

// 下载报告
	const down = () => {
        let target = document.querySelector('#targetDom'); //ID获取节点对象
		appContext.config.globalProperties.$createPdf(target, '报告');
}

到了这里,关于在uni中使用vue3写h5的pdf导出的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3 -- PDF展示、添加签名(带笔锋)、导出

    实现功能的时候采用了两个方案,主要是第一个方案最后的实现效果并不太理想,但实现起来比较简单,要求不高时可以使用。 该 DEMO 会一次性加载并展示所有的 PDF 页面,目的是方便在手机上观看时上下滑动,如果要做成上一页下一页的效果,需要自行实现。 我是用开源项

    2024年02月04日
    浏览(29)
  • vue3.2 导出pdf文件或表格数据

    要在Vue 3中导出PDF文件,你可以使用第三方库来处理PDF生成和导出。一个常用的库是jspdf,它允许你在客户端或服务器端生成PDF文档。 以下是在Vue 3中使用jspdf库导出PDF文件的基本步骤: 第一步首先,安装jspdf库。你可以使用npm或yarn来安装它: npm install jspdf --save  或  pnpm in

    2024年02月09日
    浏览(34)
  • 基于uni-app+vue3跨端「h5+小程序+App」仿制chatGPT模板实例

    uni-chatgpt 一款uniapp+vite4+uview-plus多端ChatGPT模板实例。 全新首发的一款多端仿制chatgpt智能对话实战项目,基于 uniApp+Vue3+Pinia+uViewUI+MarkdownIt 等技术开发搭建项目。支持编译到 h5+小程序+APP端 ,支持markdown语法解析及代码高亮。 全屏沉浸式顶部导航条+底部tabbar 支持解析h5+小程序

    2024年02月12日
    浏览(71)
  • vue3+Ts 开发H5项目在线浏览pdf/word/pptx/xlsx文件方法分享

    pdf需要pdfh5这个插件才可以在线浏览,所以我们先下载插件; pdfh5官方地址 注意 “pdfh5”: “^1.4.7” 有问题会出现插件不能完全加载出现504错误 请切换版本下载 “pdfh5”: \\\"^1.4.2\\\"版本 其实很简单 就只用处理一下pdf类型的文件就可以了 其他文件 office 有一个自带的线上网站可以拼

    2024年02月16日
    浏览(57)
  • uni-app vue3 封装socket 兼容微信小程序 钉钉小程序 H5 App 全局唯一

    前端小伙伴使用uni-app开发长连接通信的时候都会有以下疑问 在网上搜到的封装socket都没讲怎么全局公用一个呢? 同一个 子协议或者我我们叫type类型型我想在两个页面都接受使用怎么做呢? 目前能搜到的socket 封装好像都没讲清楚这个东西,或者压根没考虑 下面给大家详细

    2024年02月13日
    浏览(61)
  • uniapp系列-超详细教你在uni-app+vue3里通过web-view组件传递信息打开H5页面写入localstorage并解决兼容性

    web-view 是一个 web 浏览器组件,可以用来承载网页的容器,会自动铺满整个页面(nvue 使用需要手动指定宽高)。 点击这里直达官网文档 点击这里下载我的代码demo 本文最下面还有一些 常见或者奇怪问题解决方案 哦~ 之前开发好的H5页面,不想重新开发,想要直接放进项目用

    2024年02月09日
    浏览(55)
  • vue中使用html2canvas+jsPDF实现pdf的导出

    html2canvas依赖 jspdf依赖 pdf导出 以导出横向,A4大小的pdf为例 规律:1. html2canvas 中,在保持jsPDF中的宽高不变的情况下,设置html2canvas中的 width 和 height 值越小,导出的pdf越显示不全(会被放大,只能看到局部),反之值越大,导出的pdf越显示完整(值也不能过大,过大在pdf中就显

    2024年02月12日
    浏览(45)
  • uniapp小程序,H5,Editor组件封装、使用及回显(vue3)

    官网链接:editor | uni-app官网 (dcloud.net.cn)

    2024年02月01日
    浏览(42)
  • 使用ExcelJS实现excel的前端导出功能(Vue3+TS)

    ExcelJS :读取,操作并写入电子表格数据和样式到 XLSX 和 JSON 文件。一个 Excel 电子表格文件逆向工程项目。 github中文文档:https://github.com/exceljs/exceljs/blob/master/README_zh.md  封装excel.ts工具文件 表格页面调用excel工具文件 

    2024年02月14日
    浏览(53)
  • 在uni-app使用vue3进行store全局数据共享

    在uni-app中使用vue3进行store的全局数据共享,网上文章太杂了,记录一下自己写的一个最简单易懂的例子,以供自己后面需要用到时候可以最直观的知道到底怎么实现 在index.js中写入代码如下(示例): uni-app好像内置vuex,不需要额外下载,如果记错了的话就得先去下载好 代

    2024年02月09日
    浏览(85)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包