React專案實現匯出PDF的功能

web喵神發表於2022-06-06

在做web專案中,有時候會遇到pdf匯出的需求,現根據之前在公司的React專案中遇到的匯出PDF需求,整理一個demo出來。

匯出PDF需要用到兩個依賴包:html2canvas、jspdf

1、安裝html2canvas和jspdf

npm install html2canvas -S / yarn add html2canvas -S
npm install jspdf
-S / yarn add jspdf -S

 

2、把匯出PDF封裝成一個公共方法

1、在src/common目錄下新建exportPDF.js檔案

exportPDF.js:

import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';

/**
 * 匯出PDF
 * @param {匯出後的檔名} title 
 * @param {要匯出的dom節點:react使用ref} ele 
 */
export const exportPDF = async (title, ele) => {
  // 根據dpi放大,防止圖片模糊
  const scale = window.devicePixelRatio > 1 ? window.devicePixelRatio : 2;
  // 下載尺寸 a4 紙 比例
  let pdf = new jsPDF('p', 'pt', 'a4');
  let width = ele.offsetWidth;
  let height = ele.offsetHeight;
  console.log('height', height)
  console.log('aa', width, height, scale)

  const canvas = document.createElement('canvas');
  canvas.width = width * scale;
  canvas.height = height * scale;
  var contentWidth = canvas.width;
  var contentHeight = canvas.height;

  console.log('contentWidth', contentWidth, contentHeight)
  //一頁pdf顯示html頁面生成的canvas高度;
  var pageHeight = contentWidth / 592.28 * 841.89;
  //未生成pdf的html頁面高度
  var leftHeight = contentHeight;
  console.log('leftHeight', leftHeight)
  //頁面偏移
  var position = 0;
  //a4紙的尺寸[595.28,841.89],html頁面生成的canvas在pdf中圖片的寬高
  var imgWidth = 595.28;
  var imgHeight = 592.28 / contentWidth * contentHeight;
  const pdfCanvas = await html2canvas(ele, {
    useCORS: true,
    canvas,
    scale,
    width,
    height,
    x: 0,
    y: 0,
  });
  const imgDataUrl = pdfCanvas.toDataURL();

  if (height > 14400) { // 超出jspdf高度限制時
    const ratio = 14400 / height;
    // height = 14400;
    width = width * ratio;
  }

  // 縮放為 a4 大小  pdfpdf.internal.pageSize 獲取當前pdf設定的寬高
  height = height * pdf.internal.pageSize.getWidth() / width;
  width = pdf.internal.pageSize.getWidth();
  if (leftHeight < pageHeight) {
    pdf.addImage(imgDataUrl, 'png', 0, 0, imgWidth, imgHeight);
  } else {    // 分頁
    while (leftHeight > 0) {
      pdf.addImage(imgDataUrl, 'png', 0, position, imgWidth, imgHeight)
      leftHeight -= pageHeight;
      position -= 841.89;
      //避免新增空白頁
      if (leftHeight > 0) {
        pdf.addPage();
      }
    }
  }
  // 匯出下載 
  await pdf.save(`${title}.pdf`);
}

3、在react元件中使用匯出方法

在Article元件中使用匯出功能

3.1、Article.jsx元件的程式碼:

import React, { Component } from 'react';
import { Button } from 'antd';
import { exportPDF } from '@/common/exportPdf';
import img1 from '@/assets/img/bg.jpg';

/**
 * 文章
 */
class Article extends Component {
  constructor(props) {
    super(props);
    this.pdfRef = React.createRef();
  }

  // 點選匯出PDF
  onExportPDF = () => {
    exportPDF('測試匯出PDF', this.pdfRef.current)
  }

  render() {
    return (
      <div className="main-container" style={{ background: '#fff' }}>
        <div style={{ textAlign: 'center' }}>
          <Button type="primary" onClick={this.onExportPDF}>匯出PDF</Button>
        </div>
        <div ref={this.pdfRef} style={{ width: 800, padding: 30, boxSizing: 'border-box', margin: '0 auto', lineHeight: '30px', fontSize: 14 }}>
          <img src={img1} alt="" style={{ width: '100%' }} />
          <h2>aaa</h2>
          <div>
            據中國商飛公司訊息,昨天(5月14日)早上6時52分,一架編號為B-001J的C919大飛機從浦東機場第4跑道起飛,於9時54分安全降落,標誌著中國商飛公司即將交付首家使用者的首架C919大飛機首次飛行試驗圓滿完成。
            在3小時2分鐘的飛行中,試飛員與試飛工程師協調配合,完成了預定的各項任務,飛機狀態及效能良好。目前,C919大飛機試飛取證和交付準備工作正在有序推進。
            首家使用者、首架飛機、首次飛行,這些令人興奮的關鍵性字眼,預示著國產大飛機C919在首飛五年之後,即將迎來交付商業使用者的歷史性時刻。機身上的編號也表明,這不再是一架用於驗證飛行的原型機,而是即將交付的1號機。雖然這架試飛飛機的機身依然是中國商飛公司的塗裝,但在正式交付前,會換上首家使用者中國東方航空的噴漆。
            航空圈內傳播的視訊顯示,在此次試飛前6天,也就是5月8日,這架東航首架C919飛機已經在上海浦東機場第五跑道進行了低、中速滑行試驗,完成了飛機燃油、液壓系統和剎車功能檢查等專案。
            國產大飛機距離正式交付已經只有一步之遙了。中國人坐上自己設計生產的大型客機的夢想,在今年或將得以實現。
            前不久,在上海的抗疫保衛戰中,突發疾病去世的志願者孟慶功,就是中國商飛的型號副總設計師,同時也是中國商飛複合材料中心副主任。國產C919首架交付機的首次試飛成功的訊息,想必也是對他在天之靈最好的告慰了。
            自那之後,國人就一直在關注著國產大飛機的進展,期盼著定型交付,進入市場運營那天能早日到來。
            但研發一款具有國際主流水準的大型客機並非是一蹴而就的事情,即便是對於波音、空客這樣的國際航空巨頭來說,依然要經過複雜的流程,更何況中國在這方面的經驗還幾乎就是一張白紙。
            從首飛到交付的速度快慢,和機型成熟度以及創新程度也都有關係。在這一方面,作為中國商飛的競爭對手,波音和空客顯然經驗更足。以空客A320舉例,其首飛到交付僅相距1年多的時間,但這也是在空客擁有A300和A310兩款機型成功研發的基礎之上才達成的。
            雖然2017年到2018年間,C919的試飛工作進行不多。但從2018年年中開始,C919整體的取證試飛工作已經加快,並開始展開密集的飛行測試。自2019年起,6架C919在上海、閻良、東營、南昌等地進行飛行試驗,開展了一系列地面試驗和飛行試驗。2020年11月,C919獲型號檢查核準書(TIA),全面進入局方審定試飛階段。
            除了試飛取證,C919也先後在2020-2021的兩屆南昌飛行大會上公開亮相,其中一屆還進行了飛行表演。
            就研製進度而言,民用飛機主要會經歷立項、設計、樣機制造、試飛、適航審定、小批量交付和批量生產這幾個階段,而C919專案正處於適航審定階段,簡單來說,就是通過各種試驗,判斷飛機能否正常航行,如果通過驗證,就能拿到適航證,進而轉入產業化階段。
            在2022年上海兩會期間,中國商用飛機有限責任公司副總經理、總會計師吳永良曾表示,國產C919專案仍處於適航取證階段,預計將於2022年完成交付,具體的交付將等到取證完成後才具備條件。
            其實,在去年的9月,民航華東局就釋出訊息,東方航空首架C919進入總裝階段。當時華東局副局長呂新明提到,C919批生產首架機是在型號合格審定工作尚未完成之前開展生產許可審定工作。這也是民航局順應國產民機發展的需要和提升國產民機競爭力的重要舉措。
            “2022年,大飛機專案將由研製階段逐步轉入產業化階段。”今年2月7日,中國商飛董事長賀東風在幹部大會上表示。
            如今,即將交付首家使用者的首架C919大飛機首次飛行試驗圓滿完成,離取證完成從而實現交付的時間表又順利邁進了一步。
            C919國內單價不到1億美元
            國務院釋出的《“十四五”現代綜合交通運輸體系發展規劃》指出,我國將重點推動C919大型客機示範運營和ARJ21支線客機系列化發展。
            2021年3月1日,中國東方航空作為國產大飛機C919全球首家啟動使用者,與中國商飛公司在上海簽署了C919大型客機購機合同。當時公佈首批引進5架,東航也將成為全球首家運營C919大型客機的航空公司。2020年,東航下屬一二三航空開始運營國產ARJ21飛機。
          </div>
          <h2>bbb</h2>
          <div>
            據中國商飛公司訊息,昨天(5月14日)早上6時52分,一架編號為B-001J的C919大飛機從浦東機場第4跑道起飛,於9時54分安全降落,標誌著中國商飛公司即將交付首家使用者的首架C919大飛機首次飛行試驗圓滿完成。
            在3小時2分鐘的飛行中,試飛員與試飛工程師協調配合,完成了預定的各項任務,飛機狀態及效能良好。目前,C919大飛機試飛取證和交付準備工作正在有序推進。
            首家使用者、首架飛機、首次飛行,這些令人興奮的關鍵性字眼,預示著國產大飛機C919在首飛五年之後,即將迎來交付商業使用者的歷史性時刻。機身上的編號也表明,這不再是一架用於驗證飛行的原型機,而是即將交付的1號機。雖然這架試飛飛機的機身依然是中國商飛公司的塗裝,但在正式交付前,會換上首家使用者中國東方航空的噴漆。
            航空圈內傳播的視訊顯示,在此次試飛前6天,也就是5月8日,這架東航首架C919飛機已經在上海浦東機場第五跑道進行了低、中速滑行試驗,完成了飛機燃油、液壓系統和剎車功能檢查等專案。
            國產大飛機距離正式交付已經只有一步之遙了。中國人坐上自己設計生產的大型客機的夢想,在今年或將得以實現。
            前不久,在上海的抗疫保衛戰中,突發疾病去世的志願者孟慶功,就是中國商飛的型號副總設計師,同時也是中國商飛複合材料中心副主任。國產C919首架交付機的首次試飛成功的訊息,想必也是對他在天之靈最好的告慰了。
            自那之後,國人就一直在關注著國產大飛機的進展,期盼著定型交付,進入市場運營那天能早日到來。
            但研發一款具有國際主流水準的大型客機並非是一蹴而就的事情,即便是對於波音、空客這樣的國際航空巨頭來說,依然要經過複雜的流程,更何況中國在這方面的經驗還幾乎就是一張白紙。
            從首飛到交付的速度快慢,和機型成熟度以及創新程度也都有關係。在這一方面,作為中國商飛的競爭對手,波音和空客顯然經驗更足。以空客A320舉例,其首飛到交付僅相距1年多的時間,但這也是在空客擁有A300和A310兩款機型成功研發的基礎之上才達成的。
            雖然2017年到2018年間,C919的試飛工作進行不多。但從2018年年中開始,C919整體的取證試飛工作已經加快,並開始展開密集的飛行測試。自2019年起,6架C919在上海、閻良、東營、南昌等地進行飛行試驗,開展了一系列地面試驗和飛行試驗。2020年11月,C919獲型號檢查核準書(TIA),全面進入局方審定試飛階段。
            除了試飛取證,C919也先後在2020-2021的兩屆南昌飛行大會上公開亮相,其中一屆還進行了飛行表演。
            就研製進度而言,民用飛機主要會經歷立項、設計、樣機制造、試飛、適航審定、小批量交付和批量生產這幾個階段,而C919專案正處於適航審定階段,簡單來說,就是通過各種試驗,判斷飛機能否正常航行,如果通過驗證,就能拿到適航證,進而轉入產業化階段。
            在2022年上海兩會期間,中國商用飛機有限責任公司副總經理、總會計師吳永良曾表示,國產C919專案仍處於適航取證階段,預計將於2022年完成交付,具體的交付將等到取證完成後才具備條件。
            其實,在去年的9月,民航華東局就釋出訊息,東方航空首架C919進入總裝階段。當時華東局副局長呂新明提到,C919批生產首架機是在型號合格審定工作尚未完成之前開展生產許可審定工作。這也是民航局順應國產民機發展的需要和提升國產民機競爭力的重要舉措。
            “2022年,大飛機專案將由研製階段逐步轉入產業化階段。”今年2月7日,中國商飛董事長賀東風在幹部大會上表示。
            如今,即將交付首家使用者的首架C919大飛機首次飛行試驗圓滿完成,離取證完成從而實現交付的時間表又順利邁進了一步。
            C919國內單價不到1億美元
            國務院釋出的《“十四五”現代綜合交通運輸體系發展規劃》指出,我國將重點推動C919大型客機示範運營和ARJ21支線客機系列化發展。
            2021年3月1日,中國東方航空作為國產大飛機C919全球首家啟動使用者,與中國商飛公司在上海簽署了C919大型客機購機合同。當時公佈首批引進5架,東航也將成為全球首家運營C919大型客機的航空公司。2020年,東航下屬一二三航空開始運營國產ARJ21飛機。
          </div>
        </div>
      </div >

    );
  }
}

export default Article;

3.2、Article.jsx元件

 

 

4、匯出效果

 

相關文章