react页面指定dom转pdf导出

      • 1. 使用jsPDF+html2canvas将页面转成图片然后导出
      • 2. 自定义创建iframe调用iframe.print()进行页面打印转pdf导出
      • 3. 使用react-to-print插件打印pdf

1. 使用jsPDF+html2canvas将页面转成图片然后导出

缺点:页面过长可能会导出失败,并且由于电脑分辨率的问题导致导出文件模糊不清

实现代码:

import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';export function downToPdf(className: string, name: string) {let elements = document.getElementsByClassName(className); // 获取指定类名的元素if (elements.length === 0) {return;}let element: any = elements[0]; // 使用第一个匹配到的元素let w = element.offsetWidth; // 获取容器的宽度let h = element.offsetHeight; // 获取容器的高度let canvas = document.createElement("canvas");canvas.width = w;canvas.height = h;// 默认横向没有滚动条的情况,因为offsetLeft有无滚动条的时候存在差值,因此// translate的时候,要把这个差值去掉html2canvas(element, {  // 设置option可去除灰色色块allowTaint: false,useCORS: true,scale: 1.2, // 用于渲染的比例。默认为浏览器设备像素比率backgroundColor: '#F5F5F5',windowWidth: element.scrollWidth,windowHeight: element.scrollHeight}).then(function (canvas) {let contentWidth = canvas.width;let contentHeight = canvas.height;// 一页pdf显示html页面生成的canvas高度let pageHeight = (contentWidth / 592.28) * 841.89;// 未生成pdf的html页面高度let leftHeight = contentHeight;// 页面偏移let position = 0;// a4纸的尺寸[595.28,841.89]pt,html页面生成的canvas在pdf中图片的宽高let imgWidth = 595.28;let imgHeight = (592.28 / contentWidth) * contentHeight - 56.7;  // 上下边距10mmlet pageData = canvas.toDataURL("image/jpeg", 1.0);let pdf = new jsPDF("p", "pt", "a4");// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)// 当内容未超过pdf一页显示的范围,无需分页if (leftHeight < pageHeight) {pdf.addImage(pageData, "JPEG", 0, 28.35, imgWidth, imgHeight);} else {// 分页while (leftHeight > 0) {pdf.addImage(pageData, "JPEG", 0, position + 28.35, imgWidth, imgHeight);leftHeight -= pageHeight; // 加上页面高度和上下的页面距position -= 841.89;// 避免添加空白页if (leftHeight > 0) {pdf.addPage();}}}pdf.save(name + ".pdf");});
}

2. 自定义创建iframe调用iframe.print()进行页面打印转pdf导出

缺点:对于echarts图表可能出现样式问题

代码实现:

export const printPDF = (dom: any) => {// 将canvas元素转换为图片convertCanvasToImages(dom);
};// 写入iframe
function writeIframe(dom: any) {const iframe: any = document.createElement("iframe");iframe.style.position = "absolute";iframe.style.width = "0";iframe.style.height = "0";iframe.style.top = "-10px";iframe.style.left = "-10px";document.body.appendChild(iframe);const doc: any = iframe.contentDocument;doc.open();doc.write(getStyle() + getHtml(dom));doc.close();iframe.onload = function () {iframe.contentWindow.print();setTimeout(() => {document.body.removeChild(iframe);}, 100);};
}// 获取样式
function getStyle() {const styles = document.querySelectorAll("style,link");let str = "";for (let i = 0; i < styles.length; i++) {str += styles[i].outerHTML;}str += `<style>@media print {html,body{height: auto;margin: 0;}body{zoom: 100%;}img{max-width: 100% !important;height: auto !important;page-break-inside: auto;break-inside: auto;}@page {margin: 0;}}</style>`;return str;
}// 获取dom
function getHtml(dom: any) {return dom.outerHTML;
}// 将canvas元素转换为图片
function convertCanvasToImages(dom: any) {const canvasElements = dom.querySelectorAll('canvas');let convertedCount = 0;if (canvasElements.length === 0) {writeIframe(dom);return;}canvasElements.forEach((canvas: any) => {const img = document.createElement('img');img.src = canvas.toDataURL('image/png');img.style.width = '100%';img.style.height = 'auto';canvas.parentNode.replaceChild(img, canvas);convertedCount++;if (convertedCount === canvasElements.length) {writeIframe(dom);}});
}

3. 使用react-to-print插件打印pdf

缺点:对于大量echarts图表可能会随机几个出现样式问题

代码实现:

  1. 下载: yarn add react-to-print
  2. 引入插件

import {useReactToPrint} from “react-to-print”;

  1. 使用
import React, { useRef } from 'react';
import { useReactToPrint } from 'react-to-print';const PrintComponent = React.forwardRef((props, ref) => {return (<div ref={ref} style={{ width: '100%', height: 'auto' }}>{/* 你的长内容 */}<div>Page 1</div><div>Page 2</div><div>Page 3</div>{/* 更多内容 */}</div>);
});const App = () => {const printRef = useRef();// 打印功能const handlePrint = useReactToPrint({content: () => printRef.current,pageStyle: `@page {size: A4;margin: 0;}@media print {body, html {height: auto;overflow: initial !important;  // 重要,如果不分页需要加上margin: 0;}body{zoom: 100%;}img{max-width: 100% !important;height: auto !important;page-break-inside: auto;break-inside: auto;}}`,removeAfterPrint: true,documentTitle: `报告名称`,});return (<div><PrintComponent ref={printRef} /><button onClick={handlePrint}>打印</button></div>);
};export default App;

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

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

相关文章

音视频开发入门教程(2)配置FFmpeg编译 ~共210节

在上一篇博客介绍了安装&#xff0c;音视频开发入门教程&#xff08;1&#xff09;如何安装FFmpeg&#xff1f;共210节-CSDN博客 感兴趣的小伙伴&#xff0c;可以继续跟着老铁&#xff0c;一起开始音视频剪辑功能&#xff0c;&#x1f604;首先查看一下自己的电脑是几核的&…

SCSA第七天

防火墙的可靠性 因为防火墙上不仅需要同步配置信息&#xff0c;还需要同步状态信息&#xff08;会话表等&#xff09;&#xff0c;所以&#xff0c;防火墙不能 像路由器那样单纯的靠动态协议来实现切换&#xff0c;需要用到双机热备技术。 1&#xff0c;双机 --- 目前双机热…

Golang面试题整理(持续更新...)

文章目录 Golang面试题总结一、基础知识1、defer相关2、rune 类型3、context包4、Go 竞态、内存逃逸分析5、Goroutine 和线程的区别6、Go 里面并发安全的数据类型7、Go 中常用的并发模型8、Go 中安全读写共享变量方式9、Go 面向对象是如何实现的10、make 和 new 的区别11、Go 关…

破解反爬虫策略 /_guard/auto.js(二)实战

这次我们用上篇文章讲到的方法来真正破解一下反爬虫策略&#xff0c;这两个案例是两个不同的网站&#xff0c;一个用的是 /_guard/auto.js&#xff0c;另一个用的是/_guard/delay_jump.js。经过解析发现这两个网站用的反爬虫策略基本是一模一样&#xff0c;只不过在js混淆和生成…

HTML2048小游戏(最新版)

比上一篇文章的2048更好一点。 控制方法&#xff1a;WASD键&#xff08;小写&#xff09;或页面上四个按钮 效果图如下&#xff1a; 源代码在图片后面 源代码 HTML <!DOCTYPE html> <html lang"en"> <head><meta charset&…

pyspark使用 graphframes创建图的方法

1、安装graphframes的步骤 1.1 查看 spark 和 scala版本 在终端输入&#xff1a; spark-shell --version 查看spark 和scala版本 1.2 在maven库中下载对应版本的graphframes https://mvnrepository.com/artifact/graphframes/graphframes 我这里需要的是spark 2.4 scala 2.…

golang性能调试工具net/http/pprof

代码引入net/http/pprof&#xff1a; package mainimport ("fmt""net/http"_ "net/http/pprof" )func main() {go func() {fmt.Println(http.ListenAndServe(":9192", nil))}() }编译启动后&#xff0c;通过页面访问&#xff1a; ht…

什么是AGI?以及AGI最新技术如何?

首先&#xff0c;AGI是Artificial General Intelligence的缩写&#xff0c;意为人工通用智能。AGI指的是一种拥有与人类相当智能水平的人工智能系统&#xff0c;能够在各种不同的任务和环境中进行智能决策和问题解决。与目前大多数人工智能系统只能在特定领域下执行特定任务不同…

生成式 AI 的发展方向,是 Chat 还是 Agent?

生成式AI的发展方向并非局限于单一的Chat&#xff08;聊天&#xff09;或Agent&#xff08;智能代理&#xff09;&#xff0c;而是两者可以相互补充和融合。以下是关于生成式AI发展方向的详细分析&#xff1a; 一、Chat方向的发展 技术基础&#xff1a;Chat方向的生成式AI主要…

Kafka Producer之ACKS应答机制

文章目录 1. 应答机制2. 等级03. 等级14. 等级all5. 设置等级6. ISR 1. 应答机制 异步发送的效率高&#xff0c;但是不安全&#xff0c;同步发送安全&#xff0c;但是效率低。 无论哪一种&#xff0c;有一个关键的步骤叫做回调&#xff0c;也就是ACKS应答机制。 其中ACKS也分…

线性表的链式存储结构————双链表(java)

线性表的链式存储结构————双链表&#xff08;java&#xff09; 文章目录 线性表的链式存储结构————双链表&#xff08;java&#xff09;双链表双链表的创建插入数据元素头插法尾插法 求链表的长度输出双链表删除双链表中的指定元素总代码运行效果用Java内部类实现双链表…

Tecnomatix Plant Simulation 这本书的翻译

这本书我准备自己翻译一下&#xff0c;一是学习这个软件&#xff0c;而是提高一下英文能力。 翻译主要是利用chatgpt 书名《Tecnomatix Plant Simulation Modeling and Programming by Means of Examples》 通过示例进行建模和编程 第二版 目录 前言 1 基础知识 1.1 介绍…

【精品资料】物业行业BI大数据解决方案(43页PPT)

引言&#xff1a;物业行业BI&#xff08;Business Intelligence&#xff0c;商业智能&#xff09;大数据解决方案是专为物业管理公司设计的一套综合性数据分析与决策支持系统。该解决方案旨在通过集成、处理、分析及可视化海量数据&#xff0c;帮助物业企业提升运营效率、优化资…

AI学习指南机器学习篇-t-SNE算法原理

AI学习指南机器学习篇-t-SNE算法原理 1. 引言 在机器学习领域&#xff0c;如何对高维数据进行可视化一直是一个重要的问题。高维空间中的数据往往难以直观地进行理解和分析。t-SNE&#xff08;t-Distributed Stochastic Neighbor Embedding&#xff09;算法就是一种用于降维和…

U盘文件夹失踪?两大数据恢复策略全解析

在数字化信息爆炸的今天&#xff0c;U盘作为我们日常工作中不可或缺的存储工具&#xff0c;承载着大量重要数据和文件。然而&#xff0c;当您突然发现U盘中的一个重要文件夹神秘消失时&#xff0c;那份焦急与无助感油然而生。本文旨在深入探讨U盘文件夹失踪的原因&#xff0c;并…

实验七:图像的复原处理

一、实验目的 熟悉常见的噪声及其概率密度函数。熟悉在实际应用中比较重要的图像复原技术,会对退化图像进行复原处理。二、实验原理 1. 图像复原技术,说简单点,同图像增强那样,是为了以某种预定义的方式来改进图像。在具体操作过程中用流程图表示,其过程就如下面所示: 2…

ppt文本框复制到word自动缩进的问题

ppt里的字是无缩进的&#xff1a; 复制粘贴到word中&#xff0c;突然出现2字符缩进&#xff1a; 微软官方嘴硬说没问题我也是无语&#xff01;&#xff01;word保留原格式复制后&#xff0c;出现莫名其妙的缩进 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直…

CSS3实现提示工具的渐入渐出效果及CSS3动画简介

上一篇文章用CSS3实现了一个提示工具&#xff0c;本文介绍如何利用CSS3实现提示工具以渐入的方式呈现&#xff0c;以渐出的方式消失。 CSS3主要可以通过两个样式来实现动画效果&#xff1a;animation和transition。 其中&#xff0c;animation需要自己定义一组关键帧从而实现…

Ubuntu22.04安装CUDA+CUDNN+Conda+PyTorch

步骤&#xff1a; 1、安装显卡驱动&#xff1b; 2、安装CUDA&#xff1b; 3、安装CUDNN&#xff1b; 4、安装Conda&#xff1b; 5、安装Pytorch。 一、系统和硬件信息 1、Ubuntu 22.04 2、显卡&#xff1a;4060Ti 二、安装显卡驱动 &#xff08;已经安装的可以跳过&a…

mac M1 创建Mysql8.0容器

MySLQ8.0 拉取m1镜像 docker pull mysql:8.0创建挂载文件夹并且赋予权限 sudo chmod 777 /Users/zhao/software/dockerLocalData/mysql 创建容器并且挂载 docker run --name mysql_8 \-e MYSQL_ROOT_PASSWORDadmin \-v /Users/zhao/software/dockerLocalData/mysql/:/var/l…