使用html2pdf实现前端页面打印,批量打印导出为PDF

// 使用注意:
// 如果页面中有图片会因为跨域问题导致图片下载不下来
// 所以在图片标签中需要加入一些属性:crossOrigin 和 url后加一个随机后缀
// <Image crossOrigin="anonymous" src={`${faceInfo.user_face_url}?v=${new Date()}`} width={200} alt="" />
const { jsPDF } = window.jspdf
/**** @param {*} id 要下载部分页面的元素id* @param {*} htmlTitle 下载文件文件名称*/
export default function (id, htmlTitle = '标题') {let element = document.body;if (id) {element = document.getElementById(id);}return html2canvas(element, {logging: false,useCORS: true,}).then(function (canvas) {var pdf = new jsPDF('p', 'mm', 'a4'); // A4纸,纵向var ctx = canvas.getContext('2d');var a4w = 190;var a4h = 257; // A4大小,210mm x 297mm,四边各保留20mm的边距var imgHeight = Math.floor((a4h * canvas.width) / a4w); // 按A4显示比例换算一页图像的像素高度var renderedHeight = 0;while (renderedHeight < canvas.height) {var page = document.createElement('canvas');page.width = canvas.width;page.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',10,10,a4w,Math.min(a4h, (a4w * page.height) / page.width),); // 添加图像到页面,保留10mm边距renderedHeight += imgHeight;if (renderedHeight < canvas.height) {pdf.addPage();} // 如果后面还有内容,添加一个空页// delete page;}// pdf.save(htmlTitle);var pdfBase64Str = pdf.output('datauristring'); //获取base64Pdfvar myfile = dataURLtoFile(pdfBase64Str, htmlTitle + '.pdf'); //调用一下下面的转文件流函数return myfile;});
}/*
将base64转换为文件,接收2个参数,第一是base64,第二个是文件名字
最后返回文件对象
*/
const dataURLtoFile = (dataurl, filename) => {var arr = dataurl.split(','),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new File([u8arr], filename, { type: mime });
};
// 使用
import React, { useState, useEffect, useRef } from 'react';
import { Space, Button, Modal, Spin } from 'antd';
import { httpAdminTyreHandoverPhotoDetail } from '@/api'
import html2pdf from '@/utils/html2pdf';
import JSZip from 'jszip'
import { saveAs } from "file-saver";
import './style.less'
import ReactToPrint from 'react-to-print';
import { mmToPixels } from "@/utils/tools";const Index = ({ selectedIds, setShow }) => {const [data, setData] = useState({})const ref = useRef();const [pageLoading, set_pageLoading] = useState(false)useEffect(async () => {try{set_pageLoading(true)const list = await Promise.all(selectedIds.map(async id => {const res = await httpAdminTyreHandoverPhotoDetail({ id });return res.data;}))setData(list)set_pageLoading(false)} catch(e) {console.error(e)}}, [selectedIds])const [loading, setLoading] = useState(false)const butns = [<Button disabled={pageLoading}loading={loading} type="primary"onClick={async () => {setLoading(true)var zip = new JSZip();await Promise.all(data.map(async (item, index) => {const pdfFile = await html2pdf(`batch-export-box${index}`);zip.file(`文件:${item?.order_num}.pdf`, pdfFile);}))zip.generateAsync({ type: "blob" }).then(function (content) {saveAs(content, "文件.zip");});setLoading(false)   }}>导出PDF文件</Button>,<ReactToPrinttrigger={() => <Button type="primary" disabled={pageLoading}>打印</Button>}content={() => ref.current}/>,]// A4宽度转像素const widthPixels = mmToPixels(210); // 大约1485像素// A4高度转像素const heightPixels = mmToPixels(297); // 大约2105像素return ( <Modalopen={true}width='1200px'onCancel={() => setShow(false)}footer={[...butns,<Button onClick={() => setShow(false)}>取消</Button>]}title={<Space><span>批量打印</span>{butns[0]}{butns[1]}</Space>}><Spin spinning={pageLoading}><div ref={(e) => ref.current = e}><div style={{ width: '100%' }}>{data?.length ? data.map((item, index) => {return <divid={`batch-export-box${index}`}style={{ padding: '12px', pageBreakAfter: 'always', width:`${widthPixels}px` }}><Content info={item} /></div>}) : ''}</div></div></Spin></Modal>)
}export default Index;const Content = ({info}) => {return <div className='PDFDescriptions' style={{width: '100%'}} direction="vertical">内容
</div>
}

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

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

相关文章

一些和颜色相关网站

1.中国传统色 2.网页颜色选择器 3.渐变色网站 4.多风格色卡生成 5.波浪生成 6.半透明磨砂框

第123天:内网安全-域防火墙入站出站规则不出网隧道上线组策略对象同步

目录 案例一&#xff1a; 单机-防火墙-限制端口\协议出入站 案例二&#xff1a;不出网的解决思路 入站连接 隧道技术 案例三&#xff1a;域控-防火墙-组策略对象同步 案例四&#xff1a;域控-防火墙-组策略不出网上线 msf cs 案例一&#xff1a; 单机-防火墙-限制端口\…

PHP MySQL Update

PHP MySQL Update 在PHP开发中&#xff0c;与MySQL数据库的交互是至关重要的。其中&#xff0c;更新数据库中的数据是一项基本且常见的操作。本文将详细介绍如何使用PHP来更新MySQL数据库中的数据。 1. 环境准备 在开始之前&#xff0c;请确保您的开发环境满足以下条件&…

RabbitMQ的学习和模拟实现|sqlite轻量级数据库的介绍和简单使用

SQLite3 项目仓库&#xff1a;https://github.com/ffengc/HareMQ SQLite3 什么是SQLite为什么需要用SQLite官方文档封装Helper进行一些实验 什么是SQLite SQLite是一个进程内的轻量级数据库&#xff0c;它实现了自给自足的、无服务器的、零配置的、事务性的 SQL数据库引擎…

CTFSHOW game-gyctf web2

【2020年新春战“疫”】game-gyctf web2 参考https://www.cnblogs.com/aninock/p/15408090.html 说明&#xff1a;看见网上好像没多少人写&#xff0c;刚好玩到这道题了&#xff0c;就写一下吧。 一、利用入口 常规套路发现www.zip然后进行代码审计 index可以包含update&…

汽车技术智能化程度不断提升,线束可靠性如何设计?

随着汽车技术的高速发展&#xff0c;汽车自动化、智能化程度的逐步提高&#xff0c;人们对汽车的安全性、舒适性、娱乐性等要求也不断提高&#xff0c;加上汽车节能减排法规的不断严峻&#xff0c;整车电气设备不断增加&#xff0c;作为连接汽车各种电器设备“神经网络”的整车…

【Ubuntu】Ubuntu20修改MAC地址

文章目录 一、临时修改MAC地址&#xff08;重启后复原&#xff09;二、永久修改MAC地址 场景&#xff1a;在做虚拟机复制时&#xff0c;复制完的两台虚拟机存在相同MAC&#xff0c;导致无法分别分配IP。 解决&#xff1a;修改一台虚拟机的MAC地址。 一、临时修改MAC地址&#…

谷粒商城实战笔记-跨域问题

一&#xff0c;When allowCredentials is true, allowedOrigins cannot contain the special value “*” since that cannot be set on the “Access-Control-Allow-Origin” response header. To allow credentials to a set of origins, list them explicitly or consider u…

余弦退火示例pytorch

余弦退火学习率调度器是一种用于动态调整学习率的方法&#xff0c;能够在训练过程中逐渐降低学习率&#xff0c;从而有助于模型更好地收敛。我们可以通过PyTorch中的torch.optim.lr_scheduler.CosineAnnealingLR来实现这种调度器。 下面是一个包含3层Conv2d模型的示例&#xf…

数据清洗系统设计

设计一个高效的数据清洗系统旨在确保数据的质量&#xff0c;以便后续分析和决策过程可以基于准确、一致和完整的信息。以下是设计实时数据清洗系统时需要考虑的关键要素&#xff0c;结合之前提到的设计目标和原则&#xff1a; 1. 高效的数据处理 技术选型&#xff1a;采用并行…

Linux基于CentOS7【yum】【vim】的基础学习,【普通用户提权】

目录 yum生态 什么是yum yum是如何得知目标服务器的地址和下载链接 vim vim模式 命名模式 光标移动 插入模式 i键插 a键插 o键插 底行模式 批量化注释 批量化去注释 创建vim配置文件 例子 高亮功能&#xff1a; 缩进功能&#xff1a; 符号位自动补齐功能…

面试题002:Java的数据类型

基本数据类型&#xff1a;包括 整数类型&#xff08;byte、int、short、long&#xff09;、浮点数类型&#xff08;float、double&#xff09;、字符类型&#xff08;char&#xff09;、布尔类型&#xff08;boolean&#xff09;。 引用数据类型&#xff1a;包括数组&#xff0…

win10安装ElasticSearch7.x和分词插件

说明&#xff1a; 以下内容整理自网络&#xff0c;格式调整优化&#xff0c;更易阅读&#xff0c;希望能对需要的人有所帮助。 一 安装 Java环境 ElasticSearch使用Java开发的&#xff0c;依赖Java环境&#xff0c;安装 ElasticSearch 7.x 之前&#xff0c;需要先安装jdk-8。…

梅卡曼德高精度 DLP 结构光焊接专用 3D 相机

精度高&#xff0c;抗环境光、抗反光&#xff0c;成像效果好 自研蓝光 DLP 投影技术及双目结构光 3D 成像算法&#xff0c;相 机精度高&#xff0c;抗环境光、抗反光性能优异。在实际场景中&#xff0c; 可对各类复杂焊接件、焊缝高质量成像。 超小体积&#xff0c;超强适…

UFO:革新Windows操作系统交互的UI聚焦代理

人工智能咨询培训老师叶梓 转载标明出处 人机交互的便捷性和效率直接影响着我们的工作和生活质量。尽管现代操作系统如Windows提供了丰富的图形用户界面&#xff08;GUI&#xff09;&#xff0c;使得用户能够通过视觉和简单的点击操作来控制计算机&#xff0c;但随着应用程序功…

FTP传输的两种模式的技术原理和应用

文章目录 一、主动模式(Port Mode)二、被动模式(Pasv Mode)三、FTP的控制命令与数据传输四、FTP的安全性考虑SFTP 和 FTPS五、FTP服务器开启PASV模式的设置六、在IE浏览器中禁用PASV方式七、FTP客户端常见错误及解决办法1. 连接超时2. 数据传输中断3. 无法打开数据连接4. 权…

数据库分表实践

目录 前言 如何分表 分表带来的问题 跨库事务 分页查询&#xff0c;排序问题 联表问题 二次分表 一致性ID 前言 如果单表的数据量过大&#xff0c;则会影响查询效率。想要解决这个问题&#xff0c;显然&#xff0c;直接拆分就完事了。一张表的数据量过多&#xff0c;那…

分享一个最近在进行前后端联调时改了2天的bug...

场景再现 我们这边前端端口是8080 后端端口是8121 我们在前端里在首页面写了一个任务 当进入网页三秒后 发起一个叫getLoginUser的请求 我们的getLoginUser是调用的这里 一个异步请求 这边我们前端调用后端的接口也已经写好 我们先把后端跑起来 访问前端页面 接收到了这个…

数学建模学习(112):FAHP模糊层次分析法

文章目录 一、FAHP方法由来二、模糊层次分析法原理2.1 AHP缺陷2.2 模糊集理论2.3 模糊层次分析法(FAHP)三、模糊层次分析法步骤3.1 问题定义与层次结构建立3.2 构造模糊判断矩阵3.2.1 计算模糊判断矩阵的列和向量3.2.2 计算模糊综合向量3.2.3 计算模糊权重向量3.3 解模糊数3.…

搜维尔科技:Manus Metagloves使用精确的量子跟踪技术捕捉手部每一个细节动作

Manus Metagloves使用精确的量子跟踪技术捕捉手部每一个细节动作 搜维尔科技&#xff1a;Manus Metagloves使用精确的量子跟踪技术捕捉手部每一个细节动作