vue将html生成pdf并分页
jspdf + html2canvas
此方案有很多的css兼容问题,比如虚线边框、svg、页数多了内容显示不全、部分浏览器兼容问题,光是解决这些问题就耗费了我不少岁月和精力
后面了解到新的技术方案:
jspdf + html-to-image
npm install --save html-to-image
npm install --save jspdf
原理都是一样,先将html转成图片,再分页生成pdf
区别在于html-to-image可以生成多种格式,并且没有发现html2canvas上的css兼容问题

我这里用的是toCanvas
新建公共js文件
// 导出页面为PDF格式
import JSPDF from "jspdf";
import { toCanvas } from 'html-to-image'/**** elementName: 需要输出PDF的DOM的id*/
export const ExportSavePdf = (elementName,pageTotal) =>{var element = document.getElementById(elementName)return new Promise((resolve) => {toCanvas(element,{ useCORS: true ,allowTaint:true}).then(function(canvas) {var pdf = new JSPDF("p", "mm", "a4") // A4纸,纵向var ctx = canvas.getContext("2d")ctx.scale(2, 2);var a4w = 210;var a4h = 297 // A4大小,210mm x 297mm,四边各保留20mm的边距var imgHeight = Math.floor(a4h * canvas.width / a4w) // 按A4显示比例换算一页图像的像素高度var renderedHeight = 0let pageNum = 0;while (renderedHeight < canvas.height ) {pageNum ++ var page = document.createElement("canvas")page.width = canvas.widthpage.height = Math.min(imgHeight, canvas.height - renderedHeight) // 可能内容不足一页// 用getImageData剪裁指定区域,并画到前面创建的canvas对象中page.getContext("2d").putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0)pdf.addImage(page.toDataURL("image/jpeg", 1.0), "JPEG", 0, 0, a4w, Math.min(a4h, a4w * page.height / page.width)) // 添加图像到页面,保留10mm边距renderedHeight += imgHeightif (renderedHeight < canvas.height && pageNum < pageTotal) { pdf.addPage() } // 如果后面还有内容,添加一个空页// delete page;}//这里可根据自己需求返回不同类型的数据resolve(pdf.output('blob'))}).catch(function (error) {console.error(error)resolve(false)})})
}
在vue页面引入后调用
//pageTotal表示当前pdf的总页数,这个可以在预览的时候计算出来
ExportSavePdf('pdfBox', _this.pageTotal).then((res) => {if (res === false) {this.$message.error('保存失败!');return;}//获取的blob格式数据let pdfBlob = res;//后面是将blob数据上传到oss,这里的可以根据自己需求来getOss({})});
当然也有部分兼容问题,下面是我项目中遇到的问题以及我的解决方案:
// 解决兼容问题,在保存之前调用,注意使用$nextTickcompatibilityProblem() {// 去掉所有标签中的包含“v:”的属性const elements = Array.from(document.querySelector('#pdfBox').getElementsByTagName('*'));for (var i = 0; i < elements.length; i++) {var attributes = elements[i].attributes;// 遍历当前标签的所有属性for (var j = attributes.length - 1; j >= 0; j--) {var attributeName = attributes[j].name;// 如果属性名称中包含 "v:",则移除该属性if (attributeName.includes('v:')) {elements[i].removeAttribute(attributeName);}}}// 去掉拼音a的宋体样式const songSpan = Array.from(document.querySelectorAll('#pdfBox span[style*="font-family:SimSun"]'));const aList = ['a', 'ā', 'á', 'ǎ', 'à'];const aSpan = songSpan.filter((item) => aList.indexOf(item.innerText) !== -1);for (let a of aSpan) {a.style.fontFamily = 'inherit';}// 解决图片跨域问题let imgs = Array.from(document.querySelectorAll('#pdfBox img'));for (let item of imgs) {item.onload = function () {const protocol = window.location.protocol.replace(':', '');if (item.getAttribute('src').split('://').length) {const imgProtocol = item.getAttribute('src').split('://')[0];const src = item.getAttribute('src');if (imgProtocol !== protocol) {item.setAttribute('src', src.replace(imgProtocol, protocol));}}item.setAttribute('crossorigin', 'anonymous');};}},
相关文章:
vue将html生成pdf并分页
jspdf html2canvas 此方案有很多的css兼容问题,比如虚线边框、svg、页数多了内容显示不全、部分浏览器兼容问题,光是解决这些问题就耗费了我不少岁月和精力 后面了解到新的技术方案: jspdf html-to-image npm install --save html-to-i…...
数字社会下的智慧公厕:构筑智慧城市的重要组成部分
智慧城市已经成为现代城市发展的趋势,而其中的数字化转型更是推动未来社会治理体系和治理能力现代化的必然要求。在智慧城市建设中,智慧公厕作为一种新形态的信息化公共厕所,扮演着重要角色。本文智慧公厕源头实力厂家广州中期科技有限公司&a…...
比较好玩的车子 高尔夫6
https://www.sohu.com/a/484063087_221273 四万多如愿收获手动挡高尔夫6,可靠性、经济性、操控性兼顾_搜狐汽车_搜狐网 2.基本上其他人也不知道到底是什么相关的车子信息...
智过网:非安全专业能否报考注安?哪些专业可以报考?
近年来,随着社会对安全生产管理的日益重视,注册安全工程师(简称注安)这一职业逐渐受到广大从业人员的青睐。然而,对于许多非安全专业的朋友来说,他们可能会困惑:非安全专业是否可以报考注安&…...
基于Whisper语音识别的实时视频字幕生成 (一): 流式显示视频帧和音频帧
Whishow Whistream(微流)是基于Whisper语音识别的的在线字幕生成工具,支持rtsp/rtmp/mp4等视频流在线语音识别 1. whishow介绍 whishow(微秀)是在线音视频流播放python实现,支持rtsp/rtmp/mp4等输入&…...
STM32+ESP8266水墨屏天气时钟:文字取模和图片取模教程
项目背景 本次的水墨屏幕项目需要显示一些图片和文字,所以需要对图片和文字进行取模。 取模步骤 1.打开取模软件 2.选择图形模式 3.设置字模选项 注意:本次项目采用的是水墨屏,并且是局部刷新的代码,所以设置字模选项可能有点…...
华为机试题
目录 第一章、HJ1计算字符串最后一个单词的长度,单词以空格隔开。1.1)描述1.2)解题第二章、算法题HJ2 计算某字符出现次数1.1)题目描述1.2)解题思路与答案第三章、算法题HJ3 明明的随机数1.1)题目描述1.2&a…...
【VUE】Vue3+Element Plus动态间距处理
目录 1. 动态间距调整1.1 效果演示1.2 代码演示 2. 固定间距2.1 效果演示2.2 代码演示 其他情况 1. 动态间距调整 1.1 效果演示 并行效果 并列效果 1.2 代码演示 <template><div style"margin-bottom: 15px">direction:<el-radio v-model"d…...
华为 2024 届校园招聘-硬件通⽤/单板开发——第一套(部分题目分享,完整版带答案,共十套)
华为 2024 届校园招聘-硬件通⽤/单板开发——第一套 部分题目分享,完整版带答案(有答案和解析,答案非官方,未仔细校正,仅供参考)(共十套)获取(WX:didadidadidida313,加我…...
自己整理的ICT云计算题库四
14. 【多选题】 CIFS 支持的认证方式是以下哪些选项? A: A 全局认证 B: B LADP 域 C: C 本地认证 D: D AD 域 答案 正确答案:ACD 解释 全局认证为先本地,后AD,再LADP 15. 【单选题】 华为 oceanstor v3 smarterase 在使用时…...
5.消息队列
消息队列 消息队列是一种常用的线程间通讯方式,用来传输数据。使用消息队列传输数据时有两种方法:拷贝:把数据、把变量的值复制进消息队列里;引用:把数据、把变量的地址复制进消息队列里。rtt使用拷贝值的方法。 …...
基于强化学习的对抗意图识别
源自:指挥与控制学报 作者:白亮, 肖延东, 齐景涛 “人工智能技术与咨询” 发布 摘 要 未来智能化战争复杂多变,敌我双方往往以对抗博弈情况出现,当我方作为攻击者时,如何有效隐藏我方意图实…...
vue canvas绘制信令图,动态显示标题、宽度、高度
需求: 1、 根据后端返回的数据,动态绘制出信令图 2、根据 dataStatus 返回值: 0 和 1, 判断 文字内容的颜色,0:#000,1:red 3.、根据 lineType 返回值: 0 和 1, 判断 箭…...
无影云电脑不能连接到本机的调试串口的解决方案
目录 概述 解决方案 云端电脑中的操作 本地USBDK驱动程序的更新 概述 我从1月份开始使用阿里的无影云电脑进行嵌入式开发板的测试,主要的原因有两个:一是平时使用的笔记本资源过于紧张,二是方便移动办公,这样我只要平时拿着开…...
gpt科普1 GPT与搜索引擎的对比
GPT(Generative Pre-trained Transformer)是一种基于Transformer架构的自然语言处理模型。它通过大规模的无监督学习来预训练模型,在完成这个阶段后,可以用于各种NLP任务,如文本生成、机器翻译、文本分类等。 以下是关…...
Element-plus使用中遇到的问题
el-input 设置typenumber,会出现上下箭头,在全局配置css样式即可解决,在app.vue中的css中加入:.table-clear-row {input::-webkit-outer-spin-button,input::-webkit-inner-spin-button {-webkit-appearance: none;}input[type&q…...
如何使用Arduino IDE对STM32F103C8T6进行编程
使用Arduino IDE对STM32F103C8T6进行编程调试,你需要进行一些准备工作和设置。以下是详细的操作步骤: 准备工作: 安装Arduino IDE:确保你已经安装了最新版本的Arduino IDE。可以从官方网站 https://www.arduino.cc/en/software 下…...
【迅为iMX6Q】开发板 Linux version 6.6.3 SD卡 启动
开发环境 win10 64位 VMware Workstation Pro 16 ubuntu 20.04 【迅为imx6q】开发板, 2G DDR RAM linux-imx 下载 使用 NXP 官方提供的 linux-imx,代码地址为: https://github.com/nxp-imx/linux-imx 使用 git 下载 linux-imxÿ…...
C语言每日一题(66)三数之和
题目链接 力扣15.三数之和 题目描述 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答…...
vue3-element-admin实现同一个菜单多标签
原框架代码: 赵志江/huzhushan-vue3-element-admin 目录 TagsBar实现 实现同一个菜单多标签 device/detail/:id,不同参数时页面缓存删不掉的问题 TagsBar实现 在src/layout/components/下新建目录Tagsbar,新建index.vue <template><div c…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
