狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

html2canvas + jsPDF,如何將DOM完美“復刻”到PDF?

admin
2025年7月11日 18:28 本文熱度 81

?本文轉載于稀土掘金技術社區,作者:zhEng
https://juejin.cn/post/7482392388608720908

小王盯著屏幕,感覺頭發又要掉幾根。

“王哥,又在跟打印、導出 PDF 較勁呢?”,剛入職的小李端著咖啡,幸災樂禍地問。

“別提了!甲方爸爸這次要求更變態,不僅要指定區域打印、導出 PDF、在線預覽,還要保證和頁面上的 DOM 元素一模一樣!”,小王揉了揉太陽穴,“這簡直是逼我用 html2canvas + jsPDF 搞像素魔法啊!”

“王哥,這套路我都熟透了!”,小李喝了口咖啡,慢悠悠地說,“先用 html2canvas 把指定的 DOM 元素轉換成 canvas,然后用 jsPDF 的 addImage 方法把 canvas 生成的圖片添加到 PDF 里,最后根據 type 參數判斷是下載、打印還是預覽,對吧?”

“沒錯,流程就是這么個流程”,小王無奈地嘆了口氣,“但問題是,理想很豐滿,現實很骨感!html2canvas 生成的 canvas,要么模糊得像打了馬賽克,要么就是顏色失真;jsPDF 的 addImage 方法更坑,位置、大小、比例,稍微一不對,整個 PDF 就亂成一鍋粥!這哪是像素魔法,簡直是像素災難!”

“王哥,你說的這些坑,我都踩過!”,一直默默研究的小張突然抬起頭,推了推眼鏡,“我最近發現,想要用 html2canvas + jsPDF 完美‘復刻’ DOM,關鍵在于細節!”

html2canvas:配置是關鍵,細節決定成敗

“首先,html2canvas 的配置至關重要!”,小張開始講解,“useCORS: true 必須加上,否則跨域圖片直接 GG。scale 參數也不能亂用,要根據實際情況調整,才能保證 canvas 的清晰度。如果 DOM 元素里有復雜的 CSS 樣式,比如 box-shadowborder-radius還要開啟 foreignObjectRendering: true,才能正確渲染。”

jsPDF:精雕細琢,方能成就完美

“然后,jsPDF的addImage 方法也要精雕細琢!”,小張繼續說道,“addImage 的坐標和寬高,必須和 canvas 的實際尺寸對應,否則就會出現拉伸、變形。如果 PDF 需要分頁,還要計算好每頁的高度,避免內容被截斷。”

性能優化:讓“像素魔法”飛起來

“最后,性能優化也不能忽視!”,小張補充道,“html2canvas 轉換 DOM 的時候,會遍歷整個 DOM 樹,非常耗時。可以嘗試使用 ignoreElements 選項,忽略一些不必要的元素,或者使用 onclone 鉤子,在轉換之前對 DOM 進行一些預處理,減少轉換的復雜度。”

“張哥,聽君一席話,勝讀十年書啊!”,小李佩服得五體投地。

另辟蹊徑:Print-JS,另一種選擇

“其實,除了 html2canvas + jsPDF,還有一些其他的選擇”,小王沉吟道,“比如 Print-JS,它可以直接打印指定的 DOM 元素,而且樣式也比較接近原始頁面。但是Print-JS 對于一些復雜的布局,可能無法完美支持。”

總結:沒有銀彈,只有最合適的方案

“所以,我們要根據實際情況,選擇最合適的方案”,小王總結道,“對于簡單的頁面,Print-JS 可能更便捷;對于需要高度還原的復雜頁面,html2canvas + jsPDF 才是王道。關鍵是要掌握各種像素魔法,才能將 DOM 完美復刻到 PDF!”

相信各位看官已經對 html2canvas + jsPDF 這套方案有了更深入的了解。那么,useCORSscaleforeignObjectRendering 這些 html2canvas 的配置參數該如何設置?jsPDF 的 addImage 方法又有哪些技巧?

接下來,就讓我們一起深入研究這些問題,看看如何用 html2canvas + jsPDF 這套像素魔法,將 DOM 完美“復刻”到 PDF,實現打印、導出、預覽pdf的終極目標!

1.安裝依賴

html2canvas[1]:1.4.1
jspdf[2]:2.5.1
print-js[3]:1.6.0

npm install html2canvas jspdf print-js --save

2. 創建utils.js文件

import print from 'print-js';
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';

const htmlToPdf = ({
  id, // 需要轉為pdf的html容器的id 必填
  title, // download下載時文件的名稱 選填
  type, // 類型 download 下載,print 打印,preview 預覽
  canvasParams, // 畫布(html2Canvas)的相關參數
  printParams, // 打印(print-js)的相關參數
  pdfPageCallback // pdf的分頁的自定義方法,處理完分頁需要把pdf對象返回 選填
}) => {
  return new Promise((resolve, reject) => {
    html2Canvas(document.querySelector(`#${id}`),{
      taintTestfalse// 在渲染前測試圖片
      background"#fff",
      useCORStrue// 開啟跨域配置
      foreignObjectRenderingtrue// 
      scalewindow.devicePixelRatio
    }, (canvasParams || {})).then((canvas) => {
        let PDF = new JsPDF('''pt''a4');
        if(typeof pdfPageCallback === 'function') {
          PDF = pdfPageCallback(canvas, JsPDF);
        } else {
          // 內容的寬度
          let contentWidth = canvas.width; 
          // 內容高度
          let contentHeight = canvas.height;
          // 一頁pdf顯示html頁面生成的canvas高度,a4紙的尺寸[595.28,841.89];
          let pageHeight = (contentWidth / 592.28) * 841.89;
          // 未生成pdf的html頁面高度
          let leftHeight = contentHeight;
          // 頁面偏移
          let position = 0;
          //a4紙的尺寸[595.28,841.89],html頁面生成的canvas在pdf中圖片的寬高
          let imgWidth = 595.28;
          let imgHeight = (592.28 / contentWidth) * contentHeight;
          // canvas轉圖片數據
          let pageData = canvas.toDataURL('image/jpeg'1.0);
          // 判斷是否需要分頁
          if (leftHeight < pageHeight) {
            PDF.addImage(pageData, 'JPEG'00, imgWidth, imgHeight);
          } else {
            while (leftHeight > 0) {
              PDF.addImage(pageData, 'JPEG'0, position, imgWidth, imgHeight);
              leftHeight -= pageHeight;
              position -= 841.89;
              if (leftHeight > 0) {
                // 新增一頁
                PDF.addPage();
              }
            }
          }
        }
      const blob = PDF.output('blob');
      const fileURL = URL.createObjectURL(blob);
      switch (type) {
        case 'download':
          PDF.save(`${title || new Date().getTime()}.pdf`);
          break;
        case 'print':
          printJS({
            printable: fileURL,
            type'pdf',
            headernull,
          },(printParams || {})));
          break;
        case 'preview':
          window.open(fileURL, '_bank');
          break;
        default:
          break;
      }
      resolve({ blob, fileURL });
    }).catch(err => {
      reject(err);
    });
  });
};

export default htmlToPdf;

3.具體使用

import htmlToPdf from '@/utils.js'
// 下載pdf
const data = {
   id:'container',
   type:'download',
   title:'PDF下載'
}
// 打印pdf
const data = {
   id:'container',
   type:'print',
}
// 預覽pdf
const data = {
   id:'container',
   type:'preview',
}
htmlToPdf(data);


該文章在 2025/7/11 18:28:04 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved