在做web项目中,有时候会遇到pdf导出的需求,现根据之前在公司的React项目中遇到的导出PDF需求,整理一个demo出来。

导出PDF需要用到两个依赖包:html2canvas、jspdf

1、安装html2canvas和jspdf

  1. npm install html2canvas -S / yarn add html2canvas -S

  2. npm install jspdf -S / yarn add jspdf -S

2、把导出PDF封装成一个公共方法

1、在src/common目录下新建exportPDF.js文件

exportPDF.js:

  1. import html2canvas from 'html2canvas';
  2. import jsPDF from 'jspdf';
  3.  
  4. /**
  5. * 导出PDF
  6. * @param {导出后的文件名} title
  7. * @param {要导出的dom节点:react使用ref} ele
  8. */
  9. export const exportPDF = async (title, ele) => {
  10. // 根据dpi放大,防止图片模糊
  11. const scale = window.devicePixelRatio > 1 ? window.devicePixelRatio : 2;
  12. // 下载尺寸 a4 纸 比例
  13. let pdf = new jsPDF('p', 'pt', 'a4');
  14. let width = ele.offsetWidth;
  15. let height = ele.offsetHeight;
  16. console.log('height', height)
  17. console.log('aa', width, height, scale)
  18.  
  19. const canvas = document.createElement('canvas');
  20. canvas.width = width * scale;
  21. canvas.height = height * scale;
  22. var contentWidth = canvas.width;
  23. var contentHeight = canvas.height;
  24.  
  25. console.log('contentWidth', contentWidth, contentHeight)
  26. //一页pdf显示html页面生成的canvas高度;
  27. var pageHeight = contentWidth / 592.28 * 841.89;
  28. //未生成pdf的html页面高度
  29. var leftHeight = contentHeight;
  30. console.log('leftHeight', leftHeight)
  31. //页面偏移
  32. var position = 0;
  33. //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
  34. var imgWidth = 595.28;
  35. var imgHeight = 592.28 / contentWidth * contentHeight;
  36. const pdfCanvas = await html2canvas(ele, {
  37. useCORS: true,
  38. canvas,
  39. scale,
  40. width,
  41. height,
  42. x: 0,
  43. y: 0,
  44. });
  45. const imgDataUrl = pdfCanvas.toDataURL();
  46.  
  47. if (height > 14400) { // 超出jspdf高度限制时
  48. const ratio = 14400 / height;
  49. // height = 14400;
  50. width = width * ratio;
  51. }
  52.  
  53. // 缩放为 a4 大小 pdfpdf.internal.pageSize 获取当前pdf设定的宽高
  54. height = height * pdf.internal.pageSize.getWidth() / width;
  55. width = pdf.internal.pageSize.getWidth();
  56. if (leftHeight < pageHeight) {
  57. pdf.addImage(imgDataUrl, 'png', 0, 0, imgWidth, imgHeight);
  58. } else { // 分页
  59. while (leftHeight > 0) {
  60. pdf.addImage(imgDataUrl, 'png', 0, position, imgWidth, imgHeight)
  61. leftHeight -= pageHeight;
  62. position -= 841.89;
  63. //避免添加空白页
  64. if (leftHeight > 0) {
  65. pdf.addPage();
  66. }
  67. }
  68. }
  69. // 导出下载
  70. await pdf.save(`${title}.pdf`);
  71. }

3、在react组件中使用导出方法

在Article组件中使用导出功能

3.1、Article.jsx组件的代码:

  1. import React, { Component } from 'react';
  2. import { Button } from 'antd';
  3. import { exportPDF } from '@/common/exportPdf';
  4. import img1 from '@/assets/img/bg.jpg';
  5.  
  6. /**
  7. * 文章
  8. */
  9. class Article extends Component {
  10. constructor(props) {
  11. super(props);
  12. this.pdfRef = React.createRef();
  13. }
  14.  
  15. // 点击导出PDF
  16. onExportPDF = () => {
  17. exportPDF('测试导出PDF', this.pdfRef.current)
  18. }
  19.  
  20. render() {
  21. return (
  22. <div className="main-container" style={{ background: '#fff' }}>
  23. <div style={{ textAlign: 'center' }}>
  24. <Button type="primary" onClick={this.onExportPDF}>导出PDF</Button>
  25. </div>
  26. <div ref={this.pdfRef} style={{ width: 800, padding: 30, boxSizing: 'border-box', margin: '0 auto', lineHeight: '30px', fontSize: 14 }}>
  27. <img src={img1} alt="" style={{ width: '100%' }} />
  28. <h2>aaa</h2>
  29. <div>
  30. 据中国商飞公司消息,昨天(514日)早上652分,一架编号为B-001JC919大飞机从浦东机场第4跑道起飞,于954分安全降落,标志着中国商飞公司即将交付首家用户的首架C919大飞机首次飞行试验圆满完成。
  31. 3小时2分钟的飞行中,试飞员与试飞工程师协调配合,完成了预定的各项任务,飞机状态及性能良好。目前,C919大飞机试飞取证和交付准备工作正在有序推进。
  32. 首家用户、首架飞机、首次飞行,这些令人兴奋的关键性字眼,预示着国产大飞机C919在首飞五年之后,即将迎来交付商业用户的历史性时刻。机身上的编号也表明,这不再是一架用于验证飞行的原型机,而是即将交付的1号机。虽然这架试飞飞机的机身依然是中国商飞公司的涂装,但在正式交付前,会换上首家用户中国东方航空的喷漆。
  33. 航空圈内传播的视频显示,在此次试飞前6天,也就是58日,这架东航首架C919飞机已经在上海浦东机场第五跑道进行了低、中速滑行试验,完成了飞机燃油、液压系统和刹车功能检查等项目。
  34. 国产大飞机距离正式交付已经只有一步之遥了。中国人坐上自己设计生产的大型客机的梦想,在今年或将得以实现。
  35. 前不久,在上海的抗疫保卫战中,突发疾病去世的志愿者孟庆功,就是中国商飞的型号副总设计师,同时也是中国商飞复合材料中心副主任。国产C919首架交付机的首次试飞成功的消息,想必也是对他在天之灵最好的告慰了。
  36. 自那之后,国人就一直在关注着国产大飞机的进展,期盼着定型交付,进入市场运营那天能早日到来。
  37. 但研发一款具有国际主流水准的大型客机并非是一蹴而就的事情,即便是对于波音、空客这样的国际航空巨头来说,依然要经过复杂的流程,更何况中国在这方面的经验还几乎就是一张白纸。
  38. 从首飞到交付的速度快慢,和机型成熟度以及创新程度也都有关系。在这一方面,作为中国商飞的竞争对手,波音和空客显然经验更足。以空客A320举例,其首飞到交付仅相距1年多的时间,但这也是在空客拥有A300A310两款机型成功研发的基础之上才达成的。
  39. 虽然2017年到2018年间,C919的试飞工作进行不多。但从2018年年中开始,C919整体的取证试飞工作已经加快,并开始展开密集的飞行测试。自2019年起,6C919在上海、阎良、东营、南昌等地进行飞行试验,开展了一系列地面试验和飞行试验。202011月,C919获型号检查核准书(TIA),全面进入局方审定试飞阶段。
  40. 除了试飞取证,C919也先后在2020-2021的两届南昌飞行大会上公开亮相,其中一届还进行了飞行表演。
  41. 就研制进度而言,民用飞机主要会经历立项、设计、样机制造、试飞、适航审定、小批量交付和批量生产这几个阶段,而C919项目正处于适航审定阶段,简单来说,就是通过各种试验,判断飞机能否正常航行,如果通过验证,就能拿到适航证,进而转入产业化阶段。
  42. 2022年上海两会期间,中国商用飞机有限责任公司副总经理、总会计师吴永良曾表示,国产C919项目仍处于适航取证阶段,预计将于2022年完成交付,具体的交付将等到取证完成后才具备条件。
  43. 其实,在去年的9月,民航华东局就发布消息,东方航空首架C919进入总装阶段。当时华东局副局长吕新明提到,C919批生产首架机是在型号合格审定工作尚未完成之前开展生产许可审定工作。这也是民航局顺应国产民机发展的需要和提升国产民机竞争力的重要举措。
  44. 2022年,大飞机项目将由研制阶段逐步转入产业化阶段。”今年27日,中国商飞董事长贺东风在干部大会上表示。
  45. 如今,即将交付首家用户的首架C919大飞机首次飞行试验圆满完成,离取证完成从而实现交付的时间表又顺利迈进了一步。
  46. C919国内单价不到1亿美元
  47. 国务院发布的《“十四五”现代综合交通运输体系发展规划》指出,我国将重点推动C919大型客机示范运营和ARJ21支线客机系列化发展。
  48. 202131日,中国东方航空作为国产大飞机C919全球首家启动用户,与中国商飞公司在上海签署了C919大型客机购机合同。当时公布首批引进5架,东航也将成为全球首家运营C919大型客机的航空公司。2020年,东航下属一二三航空开始运营国产ARJ21飞机。
  49. </div>
  50. <h2>bbb</h2>
  51. <div>
  52. 据中国商飞公司消息,昨天(514日)早上652分,一架编号为B-001JC919大飞机从浦东机场第4跑道起飞,于954分安全降落,标志着中国商飞公司即将交付首家用户的首架C919大飞机首次飞行试验圆满完成。
  53. 3小时2分钟的飞行中,试飞员与试飞工程师协调配合,完成了预定的各项任务,飞机状态及性能良好。目前,C919大飞机试飞取证和交付准备工作正在有序推进。
  54. 首家用户、首架飞机、首次飞行,这些令人兴奋的关键性字眼,预示着国产大飞机C919在首飞五年之后,即将迎来交付商业用户的历史性时刻。机身上的编号也表明,这不再是一架用于验证飞行的原型机,而是即将交付的1号机。虽然这架试飞飞机的机身依然是中国商飞公司的涂装,但在正式交付前,会换上首家用户中国东方航空的喷漆。
  55. 航空圈内传播的视频显示,在此次试飞前6天,也就是58日,这架东航首架C919飞机已经在上海浦东机场第五跑道进行了低、中速滑行试验,完成了飞机燃油、液压系统和刹车功能检查等项目。
  56. 国产大飞机距离正式交付已经只有一步之遥了。中国人坐上自己设计生产的大型客机的梦想,在今年或将得以实现。
  57. 前不久,在上海的抗疫保卫战中,突发疾病去世的志愿者孟庆功,就是中国商飞的型号副总设计师,同时也是中国商飞复合材料中心副主任。国产C919首架交付机的首次试飞成功的消息,想必也是对他在天之灵最好的告慰了。
  58. 自那之后,国人就一直在关注着国产大飞机的进展,期盼着定型交付,进入市场运营那天能早日到来。
  59. 但研发一款具有国际主流水准的大型客机并非是一蹴而就的事情,即便是对于波音、空客这样的国际航空巨头来说,依然要经过复杂的流程,更何况中国在这方面的经验还几乎就是一张白纸。
  60. 从首飞到交付的速度快慢,和机型成熟度以及创新程度也都有关系。在这一方面,作为中国商飞的竞争对手,波音和空客显然经验更足。以空客A320举例,其首飞到交付仅相距1年多的时间,但这也是在空客拥有A300A310两款机型成功研发的基础之上才达成的。
  61. 虽然2017年到2018年间,C919的试飞工作进行不多。但从2018年年中开始,C919整体的取证试飞工作已经加快,并开始展开密集的飞行测试。自2019年起,6C919在上海、阎良、东营、南昌等地进行飞行试验,开展了一系列地面试验和飞行试验。202011月,C919获型号检查核准书(TIA),全面进入局方审定试飞阶段。
  62. 除了试飞取证,C919也先后在2020-2021的两届南昌飞行大会上公开亮相,其中一届还进行了飞行表演。
  63. 就研制进度而言,民用飞机主要会经历立项、设计、样机制造、试飞、适航审定、小批量交付和批量生产这几个阶段,而C919项目正处于适航审定阶段,简单来说,就是通过各种试验,判断飞机能否正常航行,如果通过验证,就能拿到适航证,进而转入产业化阶段。
  64. 2022年上海两会期间,中国商用飞机有限责任公司副总经理、总会计师吴永良曾表示,国产C919项目仍处于适航取证阶段,预计将于2022年完成交付,具体的交付将等到取证完成后才具备条件。
  65. 其实,在去年的9月,民航华东局就发布消息,东方航空首架C919进入总装阶段。当时华东局副局长吕新明提到,C919批生产首架机是在型号合格审定工作尚未完成之前开展生产许可审定工作。这也是民航局顺应国产民机发展的需要和提升国产民机竞争力的重要举措。
  66. 2022年,大飞机项目将由研制阶段逐步转入产业化阶段。”今年27日,中国商飞董事长贺东风在干部大会上表示。
  67. 如今,即将交付首家用户的首架C919大飞机首次飞行试验圆满完成,离取证完成从而实现交付的时间表又顺利迈进了一步。
  68. C919国内单价不到1亿美元
  69. 国务院发布的《“十四五”现代综合交通运输体系发展规划》指出,我国将重点推动C919大型客机示范运营和ARJ21支线客机系列化发展。
  70. 202131日,中国东方航空作为国产大飞机C919全球首家启动用户,与中国商飞公司在上海签署了C919大型客机购机合同。当时公布首批引进5架,东航也将成为全球首家运营C919大型客机的航空公司。2020年,东航下属一二三航空开始运营国产ARJ21飞机。
  71. </div>
  72. </div>
  73. </div >
  74.  
  75. );
  76. }
  77. }
  78.  
  79. export default Article;

3.2、Article.jsx组件

4、导出效果

React项目实现导出PDF的功能的更多相关文章

  1. vue项目中导出PDF的两种方式

    参考大家导出的方式,基本上是如下两种: 1.使用 html2Canvas + jsPDF 导出PDF, 这种方式什么都好,就是下载的pdf太模糊了.对要求好的pdf这种方式真是不行啊! 2.调用浏览器 ...

  2. vue项目中导出Excel文件功能的前端代码实现

    在项目中遇到了两种不同情况, 1.get请求导出文件,实现起来相对简单 // 导出数据 exportData() { window.location.href = `/oes-content-mana ...

  3. 个人永久性免费-Excel催化剂功能第50波-批量打印、导出PDF、双面打印功能

    在倡导无纸化办公的今天,是否打印是一个碍眼的功能呢,某些时候的确是,但对于数据的留存,在现在鼓吹区块链技术的今天,仍然不失它的核心价值,数据报表.单据打印出来留存,仍然是一种不可或缺的数据存档和防篡改 ...

  4. JS导出PDF插件(支持中文、图片使用路径)

    在WEB上想做一个导出PDF的功能,发现jsPDF比较多人推荐,遗憾的是不支持中文,最后找到pdfmake,很好地解决了此问题.它的效果可以先到http://pdfmake.org/playgroun ...

  5. 使用itext导出pdf

    导出pdf这个功能是在工作中遇到的,写这个功能的时候遇到了不少的问题,比如中文乱码,不显示的问题,这些问题在我不断的测试,研究后都一一解决了. 第一步,先导入所需要的jar包 第一个jar包是用于解决 ...

  6. HTML页面导出PDF——高清版

    需要做一个导出PDF的功能,网上找有很多,但是一般导出来的都是比较模糊的那种,下面这个是高清版的,导出的PDF都是几M,跟正常手动导出的差不多,很清晰. 首先用到的JS有: <script ty ...

  7. iText导出PDF(图片,水印,页眉,页脚)

    项目需要导出PDF,导出的内容包含图片和文本,而且图片的数量不确定,在网上百度发现大家都在用iText,在官网发现可以把html转换为PDF,但是需要收费,那就只能自己写了. 在开始之前先在网上百度了 ...

  8. 导出pdf功能

    本程序下载地址: PDF是我们极其常用的文件格式,但对如何生成PDF,个人一直觉得很神秘,其实利用一些公开的PDF库,我们就可以直接生成PDF文件,而不用关注PDF文件的内部细节.我知道的PDF库有如 ...

  9. React+后端实现导出Excle表格的功能

    最近在做一个基于React+antd前端框架的Excel导出功能,我主要在后端做了处理,根据以下步骤,可以很容易就实现导出Excel表格数据的功能. 在做这类导出文件的功能,其实,在后端进行处理,会更 ...

随机推荐

  1. Wireshark查找与标记数据包

    查找数据包 按Ctrl-F. 查找数据包提供了4个选项: 显示过滤器(Display filter):该选项可以让你通过输入表达式进行筛选,并只找出那些满足该表达式的数据包.如:not ip, ip. ...

  2. VUE3 之 使用 Mixin 实现代码的复用 - 这个系列的教程通俗易懂,适合新手

    1. 概述 老话说的好:舍得舍得,先舍才能后得. 言归正传,今天我们来聊聊 VUE 中使用 Mixin 实现代码的复用. 2. Mixin 的使用 2.1 不使用 Mixin 的写法 <body ...

  3. datasets数据读取器

    #切分数据集 img_dir = train_parameters['img_dir'] file_name = train_parameters['file_name'] df = pd.read_ ...

  4. upsource 配置git仓库时的 rsa 问题

    在使用 upsource 时,当 通过 SSH-key 需要配置一个 git 仓库代码时,在使用本机已有配置的 rsa 是出现无法连接的问题.这是需要看下具体的提示,如下图的显示 其实关键的地方看这个 ...

  5. canvas 隐藏 踩坑

    当我在把canvas绘制完成时,要把canvas隐藏起来.试了display 和  opacity 都不行. 然后我用了 position: absolute; left:1000px; top:0; ...

  6. Xml外部实体注入漏洞

    Xml外部实体注入漏洞(XXE) Xml介绍 XML 不是 HTML 的替代. XML 和 HTML 为不同的目的而设计: XML 被设计为传输和存储数据,其焦点是数据的内容. HTML 被设计用来显 ...

  7. JS的URIencode方式

    BEGIN; 对需要传递的URL参数进行URLencode编码 刚开始浪费了很多时间都没搞出来,不知道怎么用.后面google到了不少解决方案,最终解决.转载下面内容: js对文字进行编码涉及3个函数 ...

  8. 这3个免费PPT素材网站,一定要收藏

    制作PPT,这三个网站的素材绝对够用! 1.象刀设计 https://www.101dao.com 象刀设计里面有非常多PPT模板,这个网站也是主打PPT素材. 分类很清晰,需要什么风格的素材能快速找 ...

  9. MATLAB地图工具箱学习心得(二)设计可变参数和位置拾取的“放大镜”式投影程序

    最近刚好因为一些原因整理这方面的内容,所以还是把这篇鸽了一年多的博客顺手写出来了∠( ᐛ 」∠)_.因为是当时课程设计的一部分,程序上难免会有一些不足和bug,在这里将设计的思路分享给大家. 本篇博客 ...

  10. Vagrant详细教程

    一.安装virtualBox 进入 VirtualBox 的主页,即可进入下载页面. VirtualBox 是一个跨平台的虚拟化工具,支持多个操作系统,根据自己的情况选择对应的版本下载即可. 在安装完 ...