vue中使用html2canvas配合jspdf导出pdf(以及在导出时遇到的导出样式问题)

指定页面中导出为pdf格式并打包,使用html2canvas先转为图片格式,在利用jspdf转为pdf,最后下载打包为本地压缩包

yarn add html2canvas
yarn add jspdf
1. 注册一个插件并挂载
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {install(Vue, options) {Vue.prototype.getPdf = function (dom) {return new Promise((resolve, reject) => {html2Canvas(dom.$el, {allowTaint: true,scale: 2,dpi: 300,}).then(function (canvas) {let contentWidth = canvas.width;let contentHeight = canvas.height;let pdfWidth = 595.28; // A4 width in pixelslet pdfHeight = (pdfWidth / contentWidth) * contentHeight;let pageData = canvas.toDataURL('image/jpeg', 1.0);let PDF = new JsPDF('p', 'pt', 'a4');let scale = pdfWidth / contentWidth;PDF.addImage(pageData, 'JPEG', 0, 0, pdfWidth, pdfHeight);let remainingHeight = pdfHeight;while (remainingHeight < contentHeight) {PDF.addPage();let offsetY = -remainingHeight * scale;PDF.addImage(pageData, 'JPEG', 0, offsetY, pdfWidth, pdfHeight);remainingHeight += pdfHeight;}PDF.save('export.pdf'); //直接下载// resolve(PDF.output('blob')); //转为blob格式 返回合并下载}).catch(reject);});};}
}
2. 页面使用
DownPDFAndFile(){this.getPdf('传入ref或者是id')
}

以上正常导出步骤 封装方法 使用 但是如果你的项目中用的是rem布局或者是适配方法,样式或者字体没有显示出来被盖掉请往下看

3.由于在项目中用rem做了适配导致样式变形

在这里插入图片描述

4. 我们可以在html2canvas生成图片时把对应的样式或者添加类名,在生成图片前修改样式,转换为pdf后恢复初始样式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
/*** @param {*} 添加样式类名*/
function removeChildrenWithClass(parent, className) {var children = parent.childNodes;if (parent.classList && parent.classList.contains('form_view_item')) {parent.childNodes.forEach((item) => {item.className += ' is_to_print'})}for (var i = 0; i < children.length; i++) {if (children[i].classList && children[i].classList.contains('isprint')) {children[i].style.display = 'block'if (children[i].classList.contains('is_toprint')) children[i].style.display = 'block'}if (children[i].classList && children[i].classList.contains('form_view_title')) {children[i].style.marginTop = '25px'}if (children[i].classList && children[i].classList.contains(className)) {children[i].style.display = 'none'} else if (children[i].childNodes) {removeChildrenWithClass(children[i], className);}}
}
/*** @param {*} 恢复初始样式*/
function restoreOriginalState(parent, className) {var children = parent.childNodes;if (parent.classList && parent.classList.contains('form_view_item')) {parent.childNodes.forEach((item) => {item.classList.remove('is_to_print');});}for (var i = 0; i < children.length; i++) {if (children[i].classList && children[i].classList.contains(className)) {children[i].style.display = '';}if (children[i].classList && children[i].classList.contains('form_view_title')) {children[i].style.marginTop = '';}if (children[i].classList && children[i].classList.contains('isprint')) {children[i].style.display = 'none';}if (children[i].childNodes) {restoreOriginalState(children[i], className);}}
}
export default {install(Vue, options) {Vue.prototype.getPdf = function (dom) {return new Promise((resolve, reject) => {removeChildrenWithClass(dom.$el, 'noprint');html2Canvas(dom.$el, {allowTaint: true,//如果不要求清晰度可以去掉scale: 2,  //按比例增加分辨率 dpi: 300, //将分辨率提高到特定的 DPI}).then(function (canvas) {restoreOriginalState(dom.$el, 'noprint')let contentWidth = canvas.width;let contentHeight = canvas.height;let pdfWidth = 595.28; // A4 width in pixelslet pdfHeight = (pdfWidth / contentWidth) * contentHeight;let pageData = canvas.toDataURL('image/jpeg', 1.0);let PDF = new JsPDF('p', 'pt', 'a4');let scale = pdfWidth / contentWidth;PDF.addImage(pageData, 'JPEG', 0, 0, pdfWidth, pdfHeight);let remainingHeight = pdfHeight;while (remainingHeight < contentHeight) {PDF.addPage();let offsetY = -remainingHeight * scale;PDF.addImage(pageData, 'JPEG', 0, offsetY, pdfWidth, pdfHeight);remainingHeight += pdfHeight;}PDF.save('export.pdf'); //直接下载// resolve(PDF.output('blob')); //转为blob格式 返回合并下载}).catch(reject);});};}
}
5. 修改完后导出正常

在这里插入图片描述

6. 如果需求是直接下载以下就忽略,如果需求是打包为本地压缩包请继续
// 引入使用attachDownload方法
// 下载事件
async DownPDFAndFile() {const pdfinfo = await this.getPdf('传入ref或者是id')const pdfList = [//参数字段自行修改 为attachDownload 中的字段对应{id: "...",data: pdfinfo,},];const ImageList = []const VideoList = []const ImageAndVideoAndPdfList = [...pdfList,...ImageList,...VideoList]const { downloadStatus } = await this.is_downFile(ImageAndVideoAndPdfList);// downloadStatus 这个状态为下载状态 true为完成 可以自行添加业务},
// 下载方法
async is_downFile(list) {if (list.length > 0) {const config = {downloadList: list,suffix: "病历编辑.zip",};const { downloadStatus } = await attachDownload(config);return { downloadStatus };}},
7. 打包下载使用的是JSZip 和 FileSaver
yarn add jszip
yarn add file-saver
// attachDownload.js
import JSZip from "jszip";
import FileSaver from "file-saver";
export async function attachDownload(config) {const { downloadList, suffix } = configconst zip = new JSZip();const cache = {};let downloadStatus = falseconst downloadPromises = downloadList.map(async (item) => {try {if (item.url) {let data;if(item.type=='.pdf'){data = item.data;}else{data = await getImgArrayBuffer(item.url);}zip.folder(suffix).file(`${item.Title}_${item.FileID}` + item.type, data, { binary: true });cache[item.id] = data;} else {throw new Error(`文件${item.fileName}地址错误,下载失败`);}} catch (error) {console.error("文件获取失败", error);}});try {await Promise.all(downloadPromises);const content = await zip.generateAsync({ type: "blob" });FileSaver.saveAs(content, suffix);downloadStatus = truereturn {downloadStatus}} catch (error) {console.error("文件压缩失败", error);}
}
async function getImgArrayBuffer(url) {const response = await fetch(url);if (!response.ok) {throw new Error(`请求失败: ${response.status}`);}return await response.blob();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/451619.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【OpenCV人脸检测】写了个智能锁屏小工具!人离开电脑自动锁屏

文章目录 1. 写在前面2. 设计思路3. 人脸检测4. 程序实现 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋…

图论练习1

内容&#xff1a;&#xff0c;拆点&#xff0c;分层&#xff0c;传递&#xff0c;带限制的最小生成树 [HNOI2015]菜肴制作 题目链接 题目大意 有个限制&#xff0c;号菜肴在号前完成在满足限制的条件下&#xff0c;按照出菜( 是为了满足的限制 ) 解题思路 由限制&#xf…

TQ15EG开发板教程:使用vivado2023.1建立hello world工程

1:打开软件建立工程 2:使用vivado创建设计模块并生成bit文件 3:导出硬件平台&#xff0c;使用vitis建立工程 4:使用vitis创建应用程序项目 5:硬件设置与调试 1:打开软件建立工程 打开VIVADO2023.1 创建一个新的工程 输入项目名称和地址&#xff0c;下面那个选项为是否…

EasyX图形库学习(二、文字输出)

目录 一、文字绘制函数 字体属性结构体:logfont 文字输出 outtextxy 在指定位置输出字符串。 ​编辑 但如果直接使用,可能有以下报错&#xff1a; 三种解决方案&#xff1a; 将一个int类型的分数,输出到图形界面上 如果直接使用&#xff1a; 会把score输入进去根据A…

CICD注册和使用gitlab-runner常见问题

1、现象 fatal: unable to access https://github.com/homebrew/brew/: 2、解决 git config --global --unset http.proxy git config --global --unset https.proxy 查看gitlab-runner是否成功&#xff1a; userusers-MacBook-Pro ~ % gitlab-runner -h 查看gitlab-run…

C语言实现跳表(附源码)

最近在刷一些链表的题目&#xff0c;在leetcode上有一道设计跳表的题目&#xff0c;也是通过查阅各种资料&#xff0c;自己实现出来&#xff0c;感觉这是种很神奇的数据结构。 一.简介 跳表与红黑树&#xff0c;AVL树等&#xff0c;都是一种有序集合&#xff0c;那既然是有序…

大数据信用报告在线查询平台哪个好?

随着大数据技术在金融风控的运用&#xff0c;大数据信用越来越被人熟知&#xff0c;由于线下没有查询大数据信用的地方&#xff0c;想要查询大数据信用报告只有在线上查询&#xff0c;那大数据信用报告在线查询平台哪个好呢?本文贷你一起去了解市面上比较好的三个平台。 大数据…

分布式任务调度框架XXL-JOB详解

分布式任务调度 概述 场景: 如12306网站根据不同车次设置放票时间点&#xff0c;商品成功发货后向客户发送短信提醒等任务,某财务系统需要在每天上午10天前统计前一天的账单数据 任务的调度是指系统为了完成特定业务&#xff0c;基于给定的时间点&#xff0c;时间间隔&#…

情人节适合送哪些礼物?2024年情人节送礼指南大推荐!

情人节即将来临&#xff0c;这是一年一度表达爱意的时刻。在这个特殊的日子里&#xff0c;送上一份精心挑选的礼物&#xff0c;将会让爱意更加深刻。但是&#xff0c;肯定会有朋友会困惑于选择哪种礼物能够最好地表达您的心意。不用担心&#xff0c;今天小编就为大家精心准备了…

图书管理系统设计

工程链接放在这里 https://download.csdn.net/download/Samature/88805507使用 注意事项 登录 登录有初始账号&#xff1a;yzb 密码&#xff1a;123123123 后续可以自己加 保存的用户信息位置和题目 library是图书馆内容 users是用户名 可能遇到的bug 暂无&#xff0c;有的…

【Python】【完整代码】解析Excel 文件中的内容并检查是否包含某字符串,并返回判断结果

示例&#xff1a; 开发需求&#xff1a;解析Excel 文件中的内容并检查是否包含 "Fail" 字符&#xff0c;若没有则返回True&#xff0c;若有则返回False 实现代码&#xff1a; #!/usr/bin/env python3 # -*- encoding: utf-8 -*-File : check_excel_for_fail.py Ti…

filebeat采集中断与变慢问题分析

4、未采集的那段时间内无以下日志&#xff0c;这段时间内数据源正常&#xff0c;应能被正常采集到。 5、相关进程资源&#xff0c;服务器磁盘、cpu、内存无明显异常。 6、日志中断前有如下报错。 2022-02-15T15:22:22.2230800 INFO log/harvester.go:254 Harvester started fo…