纯前端--原生js将html页面变成pdf文件(html2canvas+jsPDF)

这篇具有很好参考价值的文章主要介绍了纯前端--原生js将html页面变成pdf文件(html2canvas+jsPDF)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、html2canvas – 将dom变成图片:

下载或者安装html2canvas:官网

1、将文档放在本地,用原生js进行引用和使用。

① 新建一个名为 html2canvas.min.js 的文件,并且将线上的内容进行复制。
② 引入 js 文件:

// js直接引入 -- 未尝试
<script type="text/javascript" src="XXX/html2canvas.js"></script>


// layui使用
// 首先在html2canvas.js文件中添加exports
layui.define([],function(exports){
    // 复制的内容...
    exports('html2canvas',html2canvas);
})
// 其次进行自定义插件的引入
layui.define(['appsmenu'],function (exports) {
	exports("conf", {
	    // 第三方扩展
		extend: {
			// 引入html转图片的插件
			html2canvas: "lay/extends/html2canvas.min",
		}
	}
})
2、使用 npm 进行安装使用:

待续。。。

二、jsPDF – 将图片变成pdf:

下载或者安装jsPDF :

  • github
  • 中文网站
  • CDN
    • Jspdf.es.js:ES 2015 模块格式。
    • Jspdf.umd.js:UMD模块格式,用于 AMD 或脚本标签加载。
    • Jspdf.polyfills.js:Internet Explorer等旧浏览器所需的兼容文件。
1、将文档放在本地,用原生js进行引用和使用。

① 新建一个名为 jsPDF.min.js 的文件,并且将线上(我找到的都不能用)或者资源 的内容进行复制。
② 引入 js 文件:

// js直接引入 -- 未尝试
<script type="text/javascript" src="XXX/jsPDF.js"></script>
// CDN引入 -- 未尝试
<script type="text/javascript" src="https://cdn.staticfile.org/jspdf/2.5.1/jspdf.umd.min.js"></script>


// layui使用
// 首先在jsPDF.min.js文件中添加exports
layui.define([],function(exports){
    exports('jsPDF',jsPDF);
})
// 其次进行自定义插件的引入
layui.define(['appsmenu'],function (exports) {
	exports("conf", {
	    // 第三方扩展
		extend: {
			// 引入图片转pdf的插件
			jsPDF: "lay/extends/jsPDF.min",
		}
	}
})
2、使用 npm 进行安装使用:

待续。。。

三、普通使用(html2canvas+jsPDF):

1、 layui 或者原生js使用:
// html:
<div id="box">
    <button id="btn">下载为pdf</button>
    内容....
</div>
// js:
// layui引入:
layui.define(['html2canvas', 'jsPDF'], function (exports) {
	var html2canvas = layui.html2canvas; // 引入html转图片
	var jsPDF = layui.jsPDF; // 引入图片转pdf
	// 初始化
	var init = function() {
		// 点击下载按钮
		document.getElementById("btn").onclick=function(){
				html2canvas(document.getElementById("box"),{
					allowTaint: false, // 是否允许跨域图像。会污染画布,导致无法使用canvas.toDataURL 方法
					backgroundColor: '#fff', // 画布背景色(如果未在DOM中指定)。设置null为透明
					useCORS: true, // 是否尝试使用CORS从服务器加载图像
					dpi: 192, // 导出pdf清晰度
					scale: window.devicePixelRatio * 3, // 用于渲染的比例。默认为浏览器设备像素比率。
				}).then(canvas => {
					// html生成图片的数据
					var imageData = canvas.toDataURL('image/jpeg', 1.0);
					// 原本的html页面的宽高
					const canvasWidth = canvas.width;
					const canvasHeight = canvas.height;
					// 当分辨率是72像素/英寸时,A4纸像素长宽分别是842×595
					var a4Width = 595; // A4 宽度
					var a4Height = (595 / canvasWidth) * canvasHeight; // A4总高度
					// 生成pdf的一页显示html的高度
					let pageHeight = canvasWidth / 595 * 842;
					// 未生成pdf的html页面高度,最初是整体的高度
					let restHeight = canvasHeight;
					// 页面上下偏移的大小
					var position = 0;
					/**
					 * 参数1:方向:l:横向  p:纵向
					 * 参数2:单位:"pt"、"mm"、"cm"、"m"、"in"、"px"
					 * 参数3:格式:默认为a4
					*/
					var pdf = new jsPDF('p', 'pt', 'a4');
					// 当内容未超过pdf一页显示的范围,无需分页
					if (restHeight < pageHeight) {
						/**
						 * 将图像添加到PDF中
						 * 参数1:图片的url
						 * 参数2:图片的格式
						 * 参数3:图片上下偏移的大小
						 * 参数4:原始宽度
						 * 参数5:原始高度
						*/ 
						pdf.addImage(imageData, 'JPEG', 0, position, a4Width, a4Height );
					} else {
						while(restHeight > 0) {
							pdf.addImage(imageData, 'JPEG',0, position, a4Width, a4Height)
							restHeight -= pageHeight;
							position -= 842;
							if(restHeight > 0) {
								// 在PDF文档中添加新页面
								pdf.addPage();
							}
						}
					}
					// 保存为pdf格式的文件
					pdf.save('生成的pdf文件.pdf')
				})
			}
	}
	
	var Class = {
		init: function (options) {
			init();
			return this;
		}
	}
	exports('XXX', Class);
)}
2、 vue/react 框架进行使用:

待续。。。

四、模块分割(html2canvas+jsPDF – 文字会截断,除了让后端做,没找到别的解决办法,感觉后端的插件比前端的更好用…):

参考链接:https://blog.csdn.net/qq_32244819/article/details/109678481文章来源地址https://www.toymoban.com/news/detail-719177.html

具体代码:
	// 点击下载按钮
	document.getElementById("btn").onclick=function(){
		outPutPdfFn()
	}
	// 导出方法
	var outPutPdfFn = function() {
		const A4_WIDTH = 592.28; // A4纸的宽
		const A4_HEIGHT = 841.89; // A4纸的高
		console.log('正在导出pdf,请稍候...');
		let target = document.getElementById('box'); // 需要打印的页面的dom
		let pageHeight = target.scrollWidth / A4_WIDTH * A4_HEIGHT; // 根据比例换算一页的高度
		// 获取分割的dom,即class类名为splitItem的dom
		let splitItemAll = document.getElementsByClassName('splitItem');
		// 进行分割操作,当分块的内容超出a4纸的高度,则在这个块之前插入一个空白的块,将原有的块下移进行分割
		for (let i = 0; i < splitItemAll.length; i++) {
			// 计算当前模块需要分成几部分
			let modulesNum = Math.ceil((splitItemAll[i].offsetTop + splitItemAll[i].offsetHeight) / pageHeight);
			if (isSplit(splitItemAll, i, modulesNum * pageHeight)) {
				let divParent = splitItemAll[i].parentNode; // 获取当前需要分割块的父节点
				let newNode = document.createElement('div');
				newNode.className = 'emptyDiv';
				newNode.style.background = '#ffffff';
				// 计算需要插入块的高度
				let _H = modulesNum * pageHeight - (splitItemAll[i].offsetTop + splitItemAll[i].offsetHeight);
				newNode.style.height = _H + 'px';
				newNode.style.width = '100%';
				let nextDom = splitItemAll[i].nextSibling; // 获取当前需要分割块的下一个兄弟节点
				// 判断兄弟节点是否存在
				console.log(nextDom);
				if (nextDom) {
					// 存在则将新节点插入到下一个兄弟节点的前面
					divParent.insertBefore(newNode, nextDom);
				} else {
					// 不存在则直接添加
					divParent.appendChild(newNode);
				}
			}
		}
		getPdf('导出pdf', 'box')
	}
	/**
	 * 计算当前内容是否跨越了a4大小,以此分割
	 * @params nodes 拿到的所有需要分割的dom
	 * @params index 当前需要分割内容的索引
	 * @params pageHeight A4纸的高度
	*/
	var isSplit = function(nodes, index, pageHeight) {
		// 当前需要分割的内容:内容高度+内容距离页面定位父元素(/body)的高度 < 页面的高度
		// 当前需要分割的内容的下一个兄弟节点:内容高度+内容距离页面定位父元素(/body)的高度 > 页面的高度
		if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) {
			return true;
		}
		return false;
	}
	// 导出pdf
	var getPdf = function(title, dom) {
		html2canvas(document.getElementById(dom),{
			allowTaint: false, // 是否允许跨域图像。会污染画布,导致无法使用canvas.toDataURL 方法
			backgroundColor: '#fff', // 画布背景色(如果未在DOM中指定)。设置null为透明
			useCORS: true, // 是否尝试使用CORS从服务器加载图像
			dpi: 192, // 导出pdf清晰度
			scale: window.devicePixelRatio * 3   // 用于渲染的比例。默认为浏览器设备像素比率。增加清晰度
		}).then(canvas => {
			// html生成图片的数据
			var imageData = canvas.toDataURL('image/jpeg', 1.0);
			// 原本的html页面的宽高
			const canvasWidth = canvas.width;
			const canvasHeight = canvas.height;
			// 当分辨率是72像素/英寸时,A4纸像素长宽分别是842×595
			var a4Width = 592.28; // A4 宽度
			var a4Height = (592.28 / canvasWidth) * canvasHeight; // A4总高度
			// 生成pdf的一页显示html的高度
			let pageHeight = canvasWidth / 592.28 * 841.89;
			// 未生成pdf的html页面高度,最初是整体的高度
			let restHeight = canvasHeight;
			// 页面上下偏移的大小
			var position = 0;
			/**
			 * 参数1:方向:l:横向  p:纵向
			 * 参数2:单位:"pt"、"mm"、"cm"、"m"、"in"、"px"
			 * 参数3:格式:默认为a4
			*/
			var pdf = new jsPDF('p', 'pt', 'a4');
			// 当内容未超过pdf一页显示的范围,无需分页
			if (restHeight < pageHeight) {
				/**
				 * 将图像添加到PDF中
				 * 参数1:图片的url
				 * 参数2:图片的格式
				 * 参数3:图片上下偏移的大小
				 * 参数4:原始宽度
				 * 参数5:原始高度
				*/ 
				pdf.addImage(imageData, 'JPEG', 0, 0, position, a4Height );
			} else {
				while(restHeight > 0) {
					pdf.addImage(imageData, 'JPEG',0, position, a4Width, a4Height)
					restHeight -= pageHeight;
					position -= 841.89;
					if(restHeight > 0) {
						// 在PDF文档中添加新页面
						pdf.addPage();
					}
				}
			}
			// 保存为pdf格式的文件
			pdf.save(`${title}.pdf`)
		})
	}

五、echarts图表模糊的解决办法:

// 方法一:初始化echarts的时候,添加清晰度配置 devicePixelRatio
echarts.init(chartDom, null, { devicePixelRatio: window.devicePixelRatio * 3 });
// 方法二:使用svg渲染,这个效果更好,就是需要调整grid,不然图表不完整
// echarts.init(chartDom, null, { renderer: "svg" })

到了这里,关于纯前端--原生js将html页面变成pdf文件(html2canvas+jsPDF)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • html2canvas和jspdf实现html导出pdf文件

    实现原理 先使用html2canvas对页面进行截图,再使用jspdf将截图生成pdf文件 html2canvas:通过纯JS对浏览器页面进行截图 jspdf:一个基于 HTML5 的客户端解决方案,用于在客户端 JavaScript 中生成 pdf文件 的库 安装html2canvas和pdf 截图源码 1. 截长图不分页 2. 截图分页 导出pdf源码 函数调

    2024年02月12日
    浏览(59)
  • 前端生成pdf之html2canvas+jsPDF,以及解决图片不显示bug

    开发背景: 需要给页面中相应的内容生成pdf,查找文档后发现要用到两个插件。html2canvas 以及 jsPDF html2canvas 给dom结构转化为canvas,然后生成各种类型图片 jsPDF 把canvas 生成的图片url 转化为pdf 参数 image:表示要插入的图片资源,可以是图片文件的路径或者base64编码字符串。

    2024年02月02日
    浏览(54)
  • 【前端】html2canvas生成图片空白排查data:;(js vue react uniapp)

    因为要做一个分享图,就用到了html2canvas,一开始是好好的,今天随便测了下,发现图片显示不出来了。打印了下,生成的图片链接变成了 data:; 。后面一步一步地排查,发现是页面内容太多了,删减一点内容就能显示出来。然后我又去认真看了下html2canvas的各个参数,发现可

    2024年02月03日
    浏览(59)
  • js将html页面转为pdf

    在 JavaScript 中,可以使用以下两种方法将 HTML 页面转换为 PDF 文件: 使用第三方库,如 jsPDF 或 html2canvas。 使用浏览器的内置功能,如 window.print() 方法,可以将 HTML 页面转换为 PDF 文件。 下面是使用 jsPDF 的例子: 使用 window.print() 方法的例子: 在浏览器中,你可以使用快捷键

    2024年02月15日
    浏览(52)
  • Vue基于html2canvas和jspdf生成pdf文件,解决jspdf中文乱码及自动换行等问题

    在做项目时有这么一个需求,需要将当前页面指定区域的内容导出pdf到本地。借助了两个插件分别是html2canvas.js和pdf.js来实现。使用过程中遇到的问题及解决方法 解决一些问题: 导出按A4纸大小排列 预留页面边距的问题 内容过多自动分页的问题 直接使用jspdf中文乱码的问题

    2024年01月25日
    浏览(62)
  • html 点击按键跳转至百度/其他html页面(原生js)

    本文提供两种方式,以实现: 在html中,点击按键,跳转至另一html页面,或跳转至百度等网页。 方法一:通过超链接标签a实现:               在button外添加父标签,超链接a:                       跳转至百度:                        跳转至另

    2024年02月13日
    浏览(33)
  • 基于前端技术原生HTML、JS、CSS 电子病历编辑器源码

    电子病历系统采取结构化与自由式录入的新模式,自由书写,轻松录入。实现病人医疗记录(包含有首页、病程记录、检查检验结果、医嘱、手术记录、护理记录等等。)的保存、管理、传输和重现,取代手写纸张病历。不仅实现了纸质病历的电子化储存,而且实现了病历的

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

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

    2024年02月12日
    浏览(47)
  • 前端刷新页面的五种方法(含原生js、vue和react)

    1、window.history.go(0)方法 2、location.reload()方法 3、location.href=location.href方法 4、vue-router方法 5、react-router方法

    2024年02月16日
    浏览(51)
  • 原生HTML+CSS+JS制作自己的导航主页(前端大作业,源码+步骤详解)

    链接:https://pan.baidu.com/s/1uaRCJXyIrY56NXabau4wjw?pwd=LDL6 提取码:LDL6 咕咕了好久啦,今天使用原生HTML+CSS+JS做一个很简单的个人定制的导航主页吧! 先看下完整的效果图吧! 接下来的文章将逐步带领大家制作,现在太晚了,就精简了下,删除了部分动画效果,项目整体非常简单!

    2024年01月22日
    浏览(48)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包