Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲最新在线,国产久7精品视频,18hdxxxx国产在线

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          將JavaScript代碼轉(zhuǎn)換為漂亮的SVG流程圖-js2flowchart

          js2flowchart 是一個(gè)可視化庫,可將任何JavaScript代碼轉(zhuǎn)換為漂亮的SVG流程圖。你可以輕松地利用它學(xué)習(xí)其他代碼、設(shè)計(jì)你的代碼、重構(gòu)代碼、解釋代碼。這樣一個(gè)強(qiáng)大的神器,真的值得你擁有,看下面截圖就知道了,有沒有很強(qiáng)大。

          Github

          https://github.com/Bogdan-Lyashenko/js-code-to-svg-flowchart

          安裝使用

          • 安裝
          yarn add js2flowchart
          
          • 使用

          index.html

          <!DOCTYPE html>
          <html lang="en">
          <head>
           <meta charset="UTF-8">
           <meta name="viewport" content="width=device-width, initial-scale=1.0">
           <meta http-equiv="X-UA-Compatible" content="ie=edge">
           <title>fly測試</title>
          </head>
          <body>
           <div style="width:50%;float:left">
           <p id="svgImage"></p>
           </div>
           <div style="width:50%;float:left">
           <textarea name="" id="jsContent" style="width: 90%;height:900px" oninput="createSVG()">
           </textarea>
           </div>
           <script src="./node_modules/js2flowchart/dist/js2flowchart.js"></script>
           <script src="./index.js"></script>
          </body>
          </html>
          

          index.js

          createSVG = () => {
           document.getElementById("svgImage").innerHTML = null;
           let code = document.getElementById("jsContent").value;
           const { createFlowTreeBuilder, createSVGRender } = js2flowchart;
           const flowTreeBuilder = createFlowTreeBuilder(),
           svgRender = createSVGRender();
           const flowTree = flowTreeBuilder.build(code),
           shapesTree = svgRender.buildShapesTree(flowTree);
           const svg = shapesTree.print();
           document.getElementById("svgImage").innerHTML = svg;
          };
          createSVG();
          

          我們直接在文本域中輸入自己的代碼,如下,左邊會直接生成流程圖,這只是一個(gè)簡單的示例:

          js2flowchart的特性以及適用場景(來自官網(wǎng)翻譯)

          js2flowchart獲取您的JS代碼并返回SVG流程圖,適用于客戶端/服務(wù)器,支持ES6。

          主要特點(diǎn):

          • 定義抽象級別以僅渲染導(dǎo)入/導(dǎo)出,類/函數(shù)名稱,函數(shù)依賴性以逐步學(xué)習(xí)/解釋代碼。
          • 自定義抽象級別支持創(chuàng)建自己的抽象級別
          • 表示生成器,以生成不同抽象級別的SVG列表
          • 定義流樹修改器以映射眾所周知的API,例如[] .map,[]。forEach,[] .filter到方案上的循環(huán)結(jié)構(gòu)等。
          • 銷毀修飾符,用于在方案上用一個(gè)形狀替換代碼塊
          • 自定義流樹修改器支持創(chuàng)建自己的流修改器
          • 流樹忽略過濾器完全省略一些代碼節(jié)點(diǎn),如日志行
          • 聚焦節(jié)點(diǎn)或整個(gè)代碼邏輯分支突出顯示方案的重要部分
          • 模糊節(jié)點(diǎn)或整個(gè)代碼邏輯分支以隱藏不太重要的東西
          • 定義的樣式主題支持選擇您喜歡的樣式
          • 自定義主題支持創(chuàng)建自己的主題,更好地適合您的上下文顏色
          • 自定義顏色和樣式支持提供方便的API來更改特定樣式而無需樣板

          用例場景:

          • 通過流程圖解釋/記錄您的代碼
          • 通過視覺理解學(xué)習(xí)其他代碼
          • 為有效JS語法簡單描述的任何進(jìn)程創(chuàng)建流程圖

          以上所有功能可以直接到github上詳細(xì)了解,用法太多,這里就不在介紹了!

          vscode擴(kuò)展

          這么強(qiáng)大的東西,有人肯定說如果在開發(fā)的時(shí)候?qū)崟r(shí)看到流程圖有助于理解代碼,官網(wǎng)提供了插件(我在最新版中測試失效了,不知道是否是我使用的有問題還是插件本身的問題),如果感興趣的可以到擴(kuò)展商店搜索code-flowchart。如果測試成功,歡迎到評論區(qū)分享。以下是我vscode版本和官網(wǎng)的插件使用截圖。

          如果利用好這個(gè)插件,可以開發(fā)出Chrome插件,以及其他JavaScript編輯器或者IDEA的插件,由于官方github已經(jīng)幾個(gè)月沒更新了,所以還不知道未來會不會支持!

          總結(jié)

          js2flowchart是一個(gè)比較實(shí)用的Javascript插件,可以用來做很多事情,不管是自己寫代碼。還是閱讀別人的代碼,都無疑是一大助力,能夠幫助我們提升我們的代碼能力,更容易的閱讀代碼,這樣學(xué)習(xí)起來就快了,希望對你有所幫助!如果有什么好的建議,也可以到評論區(qū)分享!

          者開源了一個(gè)Web思維導(dǎo)圖,在做導(dǎo)出為圖片的功能時(shí)走了挺多彎路,所以通過本文來記錄一下。

          思維導(dǎo)圖的節(jié)點(diǎn)和連線都是通過 svg渲染的,作為一個(gè)純 js 庫,我們不考慮通過后端來實(shí)現(xiàn),所以只能思考如何通過純前端的方式來實(shí)現(xiàn)將svg或html轉(zhuǎn)換為圖片。

          使用img標(biāo)簽結(jié)合canvas導(dǎo)出

          我們都知道 img 標(biāo)簽可以顯示 svg,然后 canvas 又可以渲染 img,那么是不是只要將svg渲染到img標(biāo)簽里,再通過canvas導(dǎo)出為圖片就可以呢,答案是肯定的。

          const svgToPng = async (svgStr) => {
              // 轉(zhuǎn)換成blob數(shù)據(jù)
              let blob = new Blob([svgStr], {
                type: 'image/svg+xml'
              })
              // 轉(zhuǎn)換成data:url數(shù)據(jù)
              let svgUrl = await blobToUrl(blob)
              // 繪制到canvas上
              let imgData = await drawToCanvas(svgUrl)
              // 下載
              downloadFile(imgData, '圖片.png')
          }

          svgStr是要導(dǎo)出的svg字符串,比如:

          然后通過Blob構(gòu)造函數(shù)創(chuàng)建一個(gè)類型為image/svg+xml的blob數(shù)據(jù),接下來將blob數(shù)據(jù)轉(zhuǎn)換成data:URL:

          const blobToUrl = (blob) => {
              return new Promise((resolve, reject) => {
                  let reader = new FileReader()
                  reader.onload = evt => {
                      resolve(evt.target.result)
                  }
                  reader.onerror = err => {
                      reject(err)
                  }
                  reader.readAsDataURL(blob)
              })
          }

          其實(shí)就是base64格式的字符串。

          接下來就可以通過img來加載,并渲染到canvas里進(jìn)行導(dǎo)出:

          const drawToCanvas = (svgUrl) => {
              return new Promise((resolve, reject) => {
                const img = new Image()
                // 跨域圖片需要添加這個(gè)屬性,否則畫布被污染了無法導(dǎo)出圖片
                img.setAttribute('crossOrigin', 'anonymous')
                img.onload = async () => {
                  try {
                    let canvas = document.createElement('canvas')
                    canvas.width = img.width
                    canvas.height = img.height
                    let ctx = canvas.getContext('2d')
                    ctx.drawImage(img, 0, 0, img.width, img.height)
                    resolve(canvas.toDataURL())
                  } catch (error) {
                    reject(error)
                  }
                }
                img.onerror = e => {
                  reject(e)
                }
                img.src = svgUrl
              })
          }

          canvas.toDataURL()方法返回的也是一個(gè)base64格式的data:URL字符串:

          最后就可以通過a標(biāo)簽來下載:

          const downloadFile = (file, fileName) => {
            let a = document.createElement('a')
            a.href = file
            a.download = fileName
            a.click()
          }

          實(shí)現(xiàn)很簡單,效果也不錯(cuò),不過這樣就沒問題了嗎,接下來我們插入兩張圖片試試。

          處理存在圖片的情況

          第一張圖片是使用base64的data:URL方式插入的,第二張圖片是使用普通url插入的:

          導(dǎo)出結(jié)果如下:

          可以看到,第一張圖片沒有問題,第二張圖片裂開了,可能你覺得同源策略的問題,但實(shí)際上換成同源的圖片,同樣也是裂開的,解決方法很簡單,遍歷svg節(jié)點(diǎn)樹,將圖片都轉(zhuǎn)換成data:URL的形式即可:

          // 操作svg使用了@svgdotjs/svg.js庫
          const transfromImg = (svgNode) => {
              let imageList = svgNode.find('image')
              let task = imageList.map(async item => {
                // 獲取圖片url
                let imgUlr = item.attr('href') || item.attr('xlink:href')
                // 已經(jīng)是data:URL形式不用轉(zhuǎn)換
                if (/^data:/.test(imgUlr)) {
                  return
                }
                // 轉(zhuǎn)換并替換圖片url
                let imgData = await drawToCanvas(imgUlr)
                item.attr('href', imgData)
              })
              await Promise.all(task)
              return svgNode.svg()// 返回svg html字符串
          }

          這里使用了前面的drawToCanvas方法來將圖片轉(zhuǎn)換成data:URL,這樣導(dǎo)出就正常了:

          到這里,將純 svg 轉(zhuǎn)換為圖片就基本沒啥問題了。

          處理存在foreignObject標(biāo)簽的情況

          svg提供了一個(gè)foreignObject標(biāo)簽,可以插入html節(jié)點(diǎn),實(shí)際上,筆者就是使用它來實(shí)現(xiàn)節(jié)點(diǎn)的富文本編輯效果的:

          接下來使用前面的方式來導(dǎo)出,結(jié)果如下:

          明明顯示沒有問題,導(dǎo)出時(shí)foreignObject內(nèi)容卻發(fā)生了偏移,這是為啥呢,其實(shí)是因?yàn)槟J(rèn)樣式的問題,頁面全局清除了margin和padding,以及將box-sizing設(shè)置成了border-box:

          那么當(dāng)svg存在于文檔樹中時(shí)是沒有問題的,但是導(dǎo)出時(shí)使用的是svg字符串,是脫離于文檔的,所以沒有這個(gè)樣式覆蓋,那么顯示自然會出現(xiàn)問題,知道了原因,解決方法有兩種,一是遍歷所有嵌入的html節(jié)點(diǎn),手動(dòng)添加內(nèi)聯(lián)樣式,注意一定要給所有的html節(jié)點(diǎn)都添加,只給svg、foreignObject或最外層的html節(jié)點(diǎn)添加都是不行的;第二種是直接在foreignObject標(biāo)簽里添加一個(gè)style標(biāo)簽,通過style標(biāo)簽來加上樣式,并且只要給其中一個(gè)foreignObject標(biāo)簽添加就可以了,兩種方式看你喜歡哪種,筆者使用的是第二種:

          const transformForeignObject = (svgNode) => {
              let foreignObjectList = svgNode.find('foreignObject')
              if (foreignObjectList.length > 0) {
                  foreignObjectList[0].add(SVG(`<style>
                  * {
                      margin: 0;
                      padding: 0;
                      box-sizing: border-box;
                  }
                  </style>`))
              }
              return svgNode.svg()
          }

          導(dǎo)出結(jié)果如下:

          可以看到,一切正常。

          關(guān)于兼容性的問題,筆者測試了最新的chrome、firefox、opera、safari、360急速瀏覽器,運(yùn)行都是正常的。

          踩坑記錄

          前面介紹的是筆者目前采用的方案,看著實(shí)現(xiàn)其實(shí)非常簡單,但是過程漫長且坎坷,接下來,開始我的表演。

          foreignObject標(biāo)簽內(nèi)容在firefox瀏覽器上無法顯示

          對于svg的操作筆者使用的是svg.js庫,創(chuàng)建富文本節(jié)點(diǎn)的核心代碼大致如下:

          import { SVG, ForeignObject } from '@svgdotjs/svg.js'
          
          let html = `<div>節(jié)點(diǎn)文本</div>`
          let foreignObject = new ForeignObject()
          foreignObject.add(SVG(html))
          g.add(foreignObject)

          SVG方法是用來將一段html字符串轉(zhuǎn)換為dom節(jié)點(diǎn)的。

          在chrome瀏覽器和opera瀏覽器上渲染非常正常,但是在firefox瀏覽器上foreignObject標(biāo)簽的內(nèi)容完全渲染不出來:

          檢查元素也看不出有任何問題,并且神奇的是只要在控制臺元素里編輯一下嵌入的html內(nèi)容,它就可以顯示了,百度搜索了一圈,也沒找到解決方法,然后因?yàn)閒irefox瀏覽器占有率并不高,于是這個(gè)問題就擱淺了。

          使用img結(jié)合canvas導(dǎo)出圖片里foreignObject標(biāo)簽內(nèi)容為空

          chrome瀏覽器雖然渲染是正常的:

          但是使用前面的方式導(dǎo)出時(shí)foreignObject標(biāo)簽內(nèi)容卻是跟在firefox瀏覽器里顯示一樣是空的:

          firefox能忍這個(gè)不能忍,于是嘗試使用一些將html轉(zhuǎn)換為圖片的庫。

          使用html2canvas、dom-to-image等庫

          使用html2canvas:

          import html2canvas from 'html2canvas'
          
          const useHtml2canvas = async (svgNode) => {
              let el = document.createElement('div')
              el.style.position = 'absolute'
              el.style.left = '-9999999px'
              el.appendChild(svgNode)
              document.body.appendChild(el)// html2canvas轉(zhuǎn)換需要被轉(zhuǎn)換的節(jié)點(diǎn)在文檔中
              let canvas = await html2canvas(el, {
                  backgroundColor: null
              })
              mdocument.body.removeChild(el)
              return canvas.toDataURL()
          }

          html2canvas可以成功導(dǎo)出,但是存在一個(gè)問題,就是foreignObject標(biāo)簽里的文本樣式會丟失:

          這應(yīng)該是html2canvas的一個(gè)bug,不過看它這issues數(shù)量和提交記錄:

          指望html2canvas改是不現(xiàn)實(shí)的,于是又嘗試使用dom-to-image:

          import domtoimage from 'dom-to-image'
          
          const dataUrl = domtoimage.toPng(el)

          發(fā)現(xiàn)dom-to-image更不行,導(dǎo)出完全是空白的:

          并且它上一次更新時(shí)間已經(jīng)是五六年前,所以沒辦法,只能回頭使用html2canvas。

          后來有人建議使用dom-to-image-more,粗略看了一下,它是在dom-to-image庫的基礎(chǔ)上修改的,嘗試了一下,發(fā)現(xiàn)確實(shí)可以,于是就改為使用這個(gè)庫,然后又有人反饋在一些瀏覽器上導(dǎo)出節(jié)點(diǎn)內(nèi)容是空的,包括firefox、360,甚至chrome之前的版本都不行,筆者只能感嘆,太難了,然后又有人建議使用上一個(gè)大版本,可以解決在firefox上的導(dǎo)出問題,但是筆者試了一下,在其他一些瀏覽器上依舊存在問題,于是又在考慮要不要換回html2canvas,雖然它存在一定問題,但至少不是完全空的。

          解決foreignObject標(biāo)簽內(nèi)容在firefox瀏覽器上無法顯示的問題

          用的人多了,這個(gè)問題又有人提了出來,于是筆者又嘗試看看能不能解決,之前一直認(rèn)為是firefox瀏覽器的問題,畢竟在chrome和opera上都是正常的,這一次就想會不會是svgjs庫的問題,于是就去搜它的issue,沒想到,還真的搜出來了issue,大意就是因?yàn)橥ㄟ^SVG方法轉(zhuǎn)換的dom節(jié)點(diǎn)是在svg的命名空間下,也就是使用document.createElementNS方法創(chuàng)建的,導(dǎo)致部分瀏覽器渲染不出來,歸根結(jié)底,這還是不同瀏覽器對于規(guī)范的不同實(shí)現(xiàn)導(dǎo)致的:

          你說chrome很強(qiáng)吧,確實(shí),但是無形中它阻止了問題的暴露。

          知道了原因,那么修改也很簡單了,只要將SVG方法第二個(gè)參數(shù)設(shè)為true即可,或者自己來創(chuàng)建節(jié)點(diǎn)也可以:

          foreignObject.add(document.createElemnt('div'))

          果然,在firefox瀏覽器上正常渲染了。

          解決img結(jié)合canvas導(dǎo)出圖片為空的問題

          解決了在firefox瀏覽器上foreignObject標(biāo)簽為空的問題后,自然會懷疑之前使用img結(jié)合canvas導(dǎo)出圖片時(shí)foreignObject標(biāo)簽為空會不會也是因?yàn)檫@個(gè)問題,同時(shí)了解了一下dom-to-image庫的實(shí)現(xiàn)原理,發(fā)現(xiàn)它也是通過將dom節(jié)點(diǎn)添加到svg的foreignObject標(biāo)簽中實(shí)現(xiàn)將html轉(zhuǎn)換成圖片的,那么就很搞笑了,我本身要轉(zhuǎn)換的內(nèi)容就是一個(gè)嵌入了foreignObject標(biāo)簽的svg,使用dom-to-image轉(zhuǎn)換,它會再次把傳給它的svg添加到一個(gè)foreignObject標(biāo)簽中,這不是套娃嗎,既然dom-to-image-more能通過foreignObject標(biāo)簽成功導(dǎo)出,那么不用它必然也可以,到這里基本確信之前不行就是因?yàn)槊臻g的問題。

          果然,在去掉了dom-to-image-more庫后,重新使用之前的方式成功導(dǎo)出了,并且在firefox、chrome、opera、360等瀏覽器中都不存在問題,兼容性反而比dom-to-image-more庫好。

          總結(jié)

          雖然筆者的實(shí)現(xiàn)很簡單,但是dom-to-image-more這個(gè)庫實(shí)際上有一千多行代碼,那么它到底多做了些什么呢,點(diǎn)個(gè)關(guān)注,我們下一篇文章再見。

          著 Web 技術(shù)的發(fā)展,有很多需要將 HTML 內(nèi)容轉(zhuǎn)換為 PDF 文檔并下載的場景,比如常見的收據(jù)、發(fā)票、電子報(bào)告、對賬清單、文檔翻譯等等。

          本文將研究當(dāng)前比較流行的基于 Node.js 技術(shù)棧的 HTML 轉(zhuǎn) PDF 庫:Puppeteer、jsPDF 和 PDFKit,大綱如下:

          • Puppeteer 及優(yōu)缺點(diǎn)
          • jsPDF 及優(yōu)缺點(diǎn)
          • PDFKit 及優(yōu)缺點(diǎn)
          • Puppeteer vs jsPDF vs PDFKit 功能對比

          1.Puppeteer

          1.1.使用 Puppeteer 生成 PDF

          Puppeteer 是谷歌開發(fā)的一個(gè) Node.js 庫,為控制無頭(或完整)Chrome 或 Chromium 瀏覽器提供了一個(gè)高級 API。它是最流行的開源 HTML 到 PDF 轉(zhuǎn)換器,支持 HTML、CSS 和 JavaScript。

          Puppeteer 允許您自動(dòng)化Web瀏覽器中的各種任務(wù),例如 Web 抓取、網(wǎng)站測試、截圖創(chuàng)建和 PDF 生成。它利用 Chrome 或 Chromium Web 瀏覽器的功能將 HTML 內(nèi)容呈現(xiàn)為 PDF 文件。

          下面使用 Puppeteer 快速初始化一個(gè)項(xiàng)目:

          nvm use 20.6.1
          
          mkdir puppeteer-demo
          
          cd puppeteer-demo
          
          npm init -y
          
          npm install puppeteer
          
          touch index.js
          
          

          index.js 中添加如下代碼:

          import puppeteer from 'puppeteer';
          
          (async () => {
            const browser = await puppeteer.launch({
              headless: 'new',
            });
          
            const page = await browser.newPage();
          
            await page.setContent(
              `<!DOCTYPE html>
              <html lang="en">
              <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Document</title>
              </head>
              <body>
                <style>
                  body {
                    display: grid;
                    place-items: center;
                    margin: 0;
                    background-color: #ccc;
                    min-height: 100vh;
                  }
                </style>
                <h1>Hello, Puppeteer!</h1>
              </body>
              </html>`
            );
          
            await page.pdf({ path: 'result.pdf', format: 'A4' });
          
            await browser.close();
          })();
          

          在上面的代碼中,我們導(dǎo)入 Puppeteer 庫,啟動(dòng)無頭 Chromium 瀏覽器,并在瀏覽器中創(chuàng)建一個(gè)新頁面。我們還會根據(jù)頁面內(nèi)容和指定選項(xiàng)(如路徑和格式)生成 PDF,生成完成后關(guān)閉瀏覽器并釋放資源。

          1.2.優(yōu)點(diǎn)

          • 您可以完全控制要在 PDF 中包含網(wǎng)頁的哪些部分。您可以指定具體的元素、部分或整個(gè)頁面
          • Puppeteer 提供了自定義選項(xiàng),如指定頁面大小、邊距、頁眉和頁腳,使您可以根據(jù)特定需求定制 PDF 布局
          • Puppeteer 可以捕捉 PDF 中的交互元素,如超鏈接和表單字段,適用于生成交互式 PDF 文件。

          1.3.缺點(diǎn)

          • 使用 Puppeteer 生成的 PDF 有時(shí)可能比使用類似庫生成的PDF要大。這會影響下載時(shí)間和存儲成本。
          • 使用 Puppeteer 渲染復(fù)雜或大型網(wǎng)頁可能會消耗資源,導(dǎo)致PDF生成變慢和內(nèi)存使用增加。

          2.PDFKit

          PDFKit 是 JavaScript 生態(tài)系統(tǒng)中最古老和最成熟的 PDF庫 之一。目前仍得到良好維護(hù)并定期更新。該庫通常使用 Node.js 在服務(wù)器端環(huán)境中創(chuàng)建和操作 PDF 文檔。它允許您通過定義每個(gè)頁面的內(nèi)容、布局和格式來以程序方式生成PDF文件。

          PDFKit 提供了用于 PDF 文檔生成的高級 API,并支持各種功能,使其成為創(chuàng)建自定義 PDF 的多功能工具。作為 PDFKit 的包裝器,已開發(fā)出多個(gè) PDF 庫,支持自定義字體和圖像嵌入。

          2.1.使用 PDFKit 生成 PDF

          讓我們來快速初始化一個(gè) PDFKit 項(xiàng)目:

          nvm use 20.6.1
          
          mkdir pdfkit-demo
          
          cd pdfkit-demo
          
          npm init -y
          
          npm install pdfkit
          
          touch index.js
          

          index.js 中添加如下代碼:

          import fs from 'node:fs';
          import PDFDocument from 'pdfkit';
          
          const doc = new PDFDocument();
          
          const stream = fs.createWriteStream('example.pdf');
          
          doc.pipe(stream);
          doc.fontSize(12).text('Hello, PDFKit!', { align: 'center' });
          doc.end();
          
          stream.on('finish', () => {
            console.log('success');
          });
          

          執(zhí)行 node index.js 后,可以看到 PDF 可以生成生成,并觸發(fā) finish 事件的回調(diào)函數(shù)執(zhí)行,打印出了 success

          2.2.優(yōu)點(diǎn)

          • 由于它是開源的,并由社區(qū)積極維護(hù),PDFkit 可以不斷改進(jìn)和更新
          • PDFKit 可對 PDF 文檔的內(nèi)容、布局和格式進(jìn)行精細(xì)控制。您可以根據(jù)自己的特定需求創(chuàng)建高度定制的 PDF 文檔
          • PDFKit 是根據(jù)用戶請求、數(shù)據(jù)或其他服務(wù)器端進(jìn)程動(dòng)態(tài)生成 PDF 的絕佳選擇

          2.3.缺點(diǎn)

          • 創(chuàng)建具有高級布局和功能的復(fù)雜 PDF 可能具有挑戰(zhàn)性,可能需要充分了解庫的 API
          • 對于新手來說,PDFKit 的學(xué)習(xí)曲線可能比更直接的 HTML 到 PDF 轉(zhuǎn)換工具更陡峭,因?yàn)樗枰獙ξ臋n結(jié)構(gòu)進(jìn)行更多的手動(dòng)控制

          3.jsPDF

          jsPDF 是一個(gè)流行的 JavaScript PDF 生成器,允許用戶動(dòng)態(tài)在 Web 瀏覽器中生成 PDF 文件。這個(gè)庫維護(hù)良好,穩(wěn)定易用,并且有豐富的文檔。

          jsPDF 在客戶端操作,非常適合在 Web 應(yīng)用程序中生成 PDF ,無需在服務(wù)器端生成。它可以修改現(xiàn)有布局,并允許用戶通過自定義來控制他們的 PDF。還可以用來編輯現(xiàn)有的 PDF 文檔或從頭創(chuàng)建一個(gè),包括圖像、表格和形狀等內(nèi)容。

          3.1.使用 jsPDF 生成 PDF

          示例中使用官方提供的 CDN 地址 https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js

          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>Document</title>
              <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
            </head>
            <body>
              <style>
                body {
                  display: grid;
                  place-items: center;
                  margin: 0;
                  background-color: #ccc;
                  min-height: 100vh;
                }
              </style>
              <h1>Hello, jsPDF!</h1>
              <script>
                document.addEventListener("DOMContentLoaded", function () {
                  const pdf = new window.jsPDF();
                  const element = document.body;
          
                  pdf.html(element, {
                    callback: function (pdf) {
                      // Save the PDF to a file or display it
                      pdf.save("output.pdf");
                    },
                  });
                });
              </script>
            </body>
          </html>
          
          

          文檔地址:http://raw.githack.com/MrRio/jsPDF/master/docs/index.html

          3.2.優(yōu)點(diǎn)

          • jsPDF 完全在客戶端(頁面)上運(yùn)行,這使它成為在 Web 應(yīng)用程序中生成 PDF 的一個(gè)很好的選擇,而無需外部服務(wù)
          • jsPDF 相對易于使用,尤其是對于基本的 PDF 生成任務(wù)。您只需幾行 JavaScript 代碼即可創(chuàng)建 PDF 文檔
          • 由于 jsPDF 是一個(gè) JavaScript 庫,它可以與 Web 應(yīng)用程序無縫集成,并可以與其他 JavaScript 庫和框架一起使用

          3.3.缺點(diǎn)

          • 在客戶端生成 PDF 可能會耗費(fèi)大量資源,尤其是大型或復(fù)雜文檔。這會影響瀏覽器性能或?qū)е聝?nèi)存消耗問題
          • jsPDF 在現(xiàn)代 Web 瀏覽器中得到廣泛支持,但在舊的瀏覽器或具有較少 JavaScript 支持的環(huán)境中可能無法按預(yù)期工作
          • 與 PDFKit 等服務(wù)器端 PDF 生成庫不同,jsPDF 具有有限的高級功能和能力。它可能不適用于復(fù)雜的PDF要求。

          4.Puppeteer、jsPDF 和 PDFKit 功能比較

          為便于大家參考,下面總結(jié)了 Puppeteer、jsPDF 和 PDFKit 庫在 PDF 生成、文件大小、瀏覽器集成和社區(qū)支持方面的比較:

          5.結(jié)論

          當(dāng)為 HTML 轉(zhuǎn) PDF 需求選擇實(shí)現(xiàn)方案時(shí),可以參考以上實(shí)現(xiàn)方案。如果你想從頭開始生成 PDF,PDFKit 可能是你最好的選擇。要通過 HTML 或者 SVG 內(nèi)容快速轉(zhuǎn)換為 PDF,jsPDF 可能更合適。對應(yīng)網(wǎng)頁渲染和交互式內(nèi)容,強(qiáng)烈建議你選擇 Puppeteer。

          最后,方案選擇在很大程度上還取決于你的項(xiàng)目類型、規(guī)范及開發(fā)者個(gè)人喜好。


          如果文章對你有幫助,歡迎關(guān)注和轉(zhuǎn)發(fā),感謝你的支持!


          主站蜘蛛池模板: 日本国产一区二区三区在线观看 | 亚洲一区二区三区免费在线观看| 日韩电影一区二区三区| 亚洲制服丝袜一区二区三区| 日本强伦姧人妻一区二区| 国产在线精品一区二区中文 | 国产精品一区二区久久精品无码| 久久无码人妻一区二区三区午夜 | 国产精品一区二区三区99 | 国产精品高清视亚洲一区二区| 国模无码一区二区三区不卡| 日韩精品一区二区三区中文3d | 亚洲AV无码一区东京热久久| 精品女同一区二区三区免费播放| 在线观看国产一区二三区| 亚洲综合色自拍一区| 亚洲福利精品一区二区三区| 亚洲AV噜噜一区二区三区| 精品一区二区三区在线成人| 波多野结衣AV无码久久一区| 色多多免费视频观看区一区| 精品人妻无码一区二区三区蜜桃一| 亚洲AV色香蕉一区二区| 国产成人精品无人区一区| 国产在线观看一区二区三区四区 | 亚洲一区二区无码偷拍| 色偷偷av一区二区三区| 国产av成人一区二区三区| 久久精品国产第一区二区| 一区二区不卡视频在线观看| 国产成人精品视频一区| 麻豆国产在线不卡一区二区 | 丰满人妻一区二区三区视频| 国产传媒一区二区三区呀| 丰满爆乳无码一区二区三区| 午夜福利无码一区二区| 亚洲av无码一区二区三区在线播放| 91精品福利一区二区| 伊人无码精品久久一区二区| 亚洲综合av一区二区三区| 精品无码国产一区二区三区麻豆|