uni-app vue 在手机APP中将页面转为图片、保存为PDF文件、打开文件

一、安装插件

npm i html2canvas
npm i jspdf

二 、将第一个script 节点的 lang 为 renderjs

三、引入插件

	import html2canvas from 'html2canvas'
	import { jsPDF } from 'jspdf';

四、HTML内容

		
			
				样品名称
				456
			
			
				日期
				2023-04-24
			
			
				单位
				单位
			
		

五、生成图片并获取base64格式文件

const detail = document.getElementById(
	'detail') //获取到html包含此页面的外层标签,detail为页面中需要导出为pdf的最外层标签的id名
const imgHeight = detail.clientHeight;
const imgWidth = detail.clientWidth;

html2canvas(detail,{//对应的dom元素id(class也可以)
	allowTaint: true,//是否允许跨域图像渲染画布
	useCORS:true,//是否尝试使用 CORS 从服务器加载图像 解决图片跨域问题
}).then((canvas) => {
	// console.log(canvas);
	return new Promise((resolve, reject) => {
		console.log(4);
		setTimeout(() => {
			console.log(5);
			resolve(canvas)
		}, 500) 
	}).then((canvas) => {
		console.log(6);
		
		//生成的canvas实例
		var contentWidth = canvas.width;//所选元素宽度
		var contentHeight = canvas.height;//所选元素高度
		//一页pdf显示html页面生成的canvas高度;
		var pageHeight = contentWidth / 595.28 * 841.89;
		//未生成pdf的html页面高度
		var leftHeight = contentHeight;
		//pdf页面偏移
		var position = 0;
		//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
		var imgWidth = 555.28;
		var imgHeight = 555.28 / contentWidth * contentHeight;
		var pageData = canvas.toDataURL('image/jpeg', 1.0);//转成jpg格式
		var pdf = new jsPDF('', 'pt', 'a4');//生成pdf实例
		//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
		//当内容未超过pdf一页显示的范围,无需分页
		if (leftHeight < pageHeight) {
			pdf.addImage(pageData, 'JPEG', 20, 0, imgWidth, imgHeight);
		} else {
			while (leftHeight > 0) {
				pdf.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
				leftHeight -= pageHeight;
				position -= 841.89;
				//避免添加空白页
				if (leftHeight > 0) {
					pdf.addPage();
				}
			}
		}

		var blob = pdf.output("datauristring");
        
        // 在renderjs中无法使用uni和plus对象,这里调用另一个script中的方法
		this.$ownerInstance.callMethod('downPdf', blob);
		
	}).catch((r) => {
		console.log(r);
	})
});

六、再写一个普通的script

七、定义base64转文件方法(仅支持安卓)

/**
 * base64字符串转成文件
 * @param {String} base64Str // 允许包含前缀
 * @param {String} fileName // 文件名称:1663061363470.xlsx
 * @param {Object} callback  // 返回本地路径径URL,file:///xxx/doc/1663062980631.xlsx
 */
function base64ToFile(base64Str, fileName, callback) {

	// 去除base64前缀
	var index = base64Str.indexOf(',')
	var base64Str = base64Str.slice(index + 1, base64Str.length)

	plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
		fs.root.getFile(fileName, {
			create: true
		}, function(entry) {

			// 获得本地路径URL,file:///xxx/doc/1663062980631.xlsx
			var fullPath = entry.fullPath;

			var Base64 = plus.android.importClass("android.util.Base64");
			var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");
			var out = new FileOutputStream(fullPath);
			// 此处Base64.decode有长度限制,如果不能满足需求,可以考虑换成官方原生插件市场的【Base64转文件】
			var bytes = Base64.decode(base64Str, Base64.DEFAULT);
			out.write(bytes);
			out.close();
			// 回调  
			callback && callback(entry.toLocalURL());
		})
	})
}

八、在export default中定义要被调用的方法

export default {
	methods: {
		downPdf(path) {
			var fileName = (new Date()).valueOf() + '.pdf';
			base64ToFile(path, fileName, function(path) {
				console.log('result', path);
				plus.runtime.openFile(path); //用第三方程序打开文件
			})
		}
	}
}

你可能感兴趣的:(vue,uni-app,uni-app,pdf,vue.js)