者:訣九 前端名獅
轉發鏈接:https://mp.weixin.qq.com/s/BMg8bFUwa4gmm6v2acAe7Q
著 Web 技術的發展,有很多需要將 HTML 內容轉換為 PDF 文檔并下載的場景,比如常見的收據、發票、電子報告、對賬清單、文檔翻譯等等。
本文將研究當前比較流行的基于 Node.js 技術棧的 HTML 轉 PDF 庫:Puppeteer、jsPDF 和 PDFKit,大綱如下:
Puppeteer 是谷歌開發的一個 Node.js 庫,為控制無頭(或完整)Chrome 或 Chromium 瀏覽器提供了一個高級 API。它是最流行的開源 HTML 到 PDF 轉換器,支持 HTML、CSS 和 JavaScript。
Puppeteer 允許您自動化Web瀏覽器中的各種任務,例如 Web 抓取、網站測試、截圖創建和 PDF 生成。它利用 Chrome 或 Chromium Web 瀏覽器的功能將 HTML 內容呈現為 PDF 文件。
下面使用 Puppeteer 快速初始化一個項目:
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();
})();
在上面的代碼中,我們導入 Puppeteer 庫,啟動無頭 Chromium 瀏覽器,并在瀏覽器中創建一個新頁面。我們還會根據頁面內容和指定選項(如路徑和格式)生成 PDF,生成完成后關閉瀏覽器并釋放資源。
PDFKit 是 JavaScript 生態系統中最古老和最成熟的 PDF庫 之一。目前仍得到良好維護并定期更新。該庫通常使用 Node.js 在服務器端環境中創建和操作 PDF 文檔。它允許您通過定義每個頁面的內容、布局和格式來以程序方式生成PDF文件。
PDFKit 提供了用于 PDF 文檔生成的高級 API,并支持各種功能,使其成為創建自定義 PDF 的多功能工具。作為 PDFKit 的包裝器,已開發出多個 PDF 庫,支持自定義字體和圖像嵌入。
讓我們來快速初始化一個 PDFKit 項目:
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');
});
執行 node index.js 后,可以看到 PDF 可以生成生成,并觸發 finish 事件的回調函數執行,打印出了 success 。
jsPDF 是一個流行的 JavaScript PDF 生成器,允許用戶動態在 Web 瀏覽器中生成 PDF 文件。這個庫維護良好,穩定易用,并且有豐富的文檔。
jsPDF 在客戶端操作,非常適合在 Web 應用程序中生成 PDF ,無需在服務器端生成。它可以修改現有布局,并允許用戶通過自定義來控制他們的 PDF。還可以用來編輯現有的 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
為便于大家參考,下面總結了 Puppeteer、jsPDF 和 PDFKit 庫在 PDF 生成、文件大小、瀏覽器集成和社區支持方面的比較:
當為 HTML 轉 PDF 需求選擇實現方案時,可以參考以上實現方案。如果你想從頭開始生成 PDF,PDFKit 可能是你最好的選擇。要通過 HTML 或者 SVG 內容快速轉換為 PDF,jsPDF 可能更合適。對應網頁渲染和交互式內容,強烈建議你選擇 Puppeteer。
最后,方案選擇在很大程度上還取決于你的項目類型、規范及開發者個人喜好。
如果文章對你有幫助,歡迎關注和轉發,感謝你的支持!
ode.js 自發布以來,已成為業界重要破局者之一。Uber、Medium、PayPal 和沃爾瑪等大型企業,紛紛將技術棧轉向 Node.js。Node.js 支持開發功能強大的應用,例如實時追蹤 App、視頻 / 文本聊天引擎、社交媒體 App 等,當前已成為開發人員熱衷的一項技能。本文作者基于自身實施經歷,給出一張 Node.js 學習路線圖。建議開發人員考慮深入掌握 Node.js 之前,必須明確自己構建的目標,否則容易半途而廢。目標導向有助于在學習中聚焦關鍵技能,而非糾結于是否值得去學習。
JavaScript
對于一名前端開發人員,在考慮掌握后端技能時,無需花費大量的精力學習去 JavaScript。而對于完全小白,如果想要在盡可能短的時間內掌握 Node.js,在深入前必須領會如下概念:
此外,Node.js 中涉及大量的異步編程處理,推薦掌握如下概念:
npm 軟件包管理
Node 軟件包管理(Node Package Manager,npm)提供當前規模最大的注冊軟件庫,其中提供 80 多萬種軟件包。正確使用 npm,可極大地降低軟件包管理的復雜度,非常便于解決應用開發中的依賴問題。
npm 提供三個組成模塊:
npm 還可管理各版本的代碼及依賴。如果使用 npx,無需下載軟件包即可運行軟件包。
Node.js 基礎知識
事件發射器(Event Emitter):做為 Node.js 中的對象,Event Emitter 在操作執行完成后發送消息,觸發特定的事件。開發人員也可編寫代碼,監聽 Event Emitter 發出的事件。例如,一旦完成特定的前端操作,諸如鼠標點擊、按鍵和鼠標移動等交互操作,需在后端做進一步處理。這時后端的 Node.js 環境使用 EventEmitter 類,構建相應的事件處理模塊,用于處理操作事件。
回調(Callback):回調是特定任務執行完成后調用的函數,不影響其它代碼的同時執行,避免了異步處理產生阻塞。鑒于 Node.js 中需處理大量的異步任務,因此回調無處不在。回調是實現應用無縫快速執行的關鍵,其運作機制如下圖所示:
Buffer 類:設計用于處理原始二進制數據的 Node.js 類,操作 V8 引擎外分配的內存。Buffer 類實現為大小不可調整的整數數組,并提供一整套二進制數據操作方法。例如,對于表示范圍在 0 到 255 之間字節值的內存中整數,使用 console.log() 輸出該 Buffer 實例,會給出一系列十六進制值。
模塊系統(Module System):使用 Node.js 生態系統提供的模塊,可實現一些復雜功能。模塊是可復用的 JavaScript 代碼,實現特定的功能。
版本管理系統:掌握 git、GitHub 等的使用。開發中,應盡量避免交叉修改代碼導致的更改不可逆。因此,在大型項目中需使用版本控制系統管理。要熟悉版本控制系統的使用,開發人員應該具備扎實的基礎知識。
HTTP/HTTPS 協議:一位優秀的 Node.js 開發人員,應具備傳輸協議數據傳輸的基礎知識,因為每位后端開發人員都需要深入理解 HTTP/HTTPS 的工作機制。HTTPS 使用稱為 TLS(Transport Layer Security)的加密協議加密通信。后端環境中有大量要學習的知識點,這對于 Web 小白是頗具難度的。簡而言之,基本的 Web 通信主要包括六種請求方法:
注意:本文僅列出了部分推薦 Web 框架。使用 Node.js 構建個人項目時,為降低學習難度,推薦從中選定一種框架,否則學習難度很高。
Express.js:提供構建應用所需的最小化接口和工具,非常靈活易用,大量 npm 模塊可直接插入 Expresss 使用。
Meteor.js:一種構建 JavaScript 應用的萬事通框架,提供內建的 MongoDB,支持 GraphQL。運行 meteor create myapp,即可生成一個具有 MongoDB 后端的 HTML/JavaScript 頁面。使用 Meteor.js 可有效助降低項目開發時間,并簡化項目的維護。當然如果只是構建一個簡單的 Web 應用,還是推薦使用 Express。
Sails.js:一種支持快速構建 REST API、單頁應用(SPA)和實時 APP 的 MVC 框架。如果開發人員考慮實操一些重要技能,例如使用 WebSockets 支持實時操作,使用按約定編程(convention over configuration)方法等,推薦學習 Sails.js。
Koa.js:如果開發人員考慮構建一個經得起時間考驗、易于維護的魯棒應用,Koa.js 無疑是很好的選擇。Koa 應用實現為包含一組中間件函數數組的對象,其中函數以堆棧方式執行。
Nest.js:該框架繼承了 Angular 的理念,使用 TypeScript 構建,并且在底層使用了 Express.js,因此兼容大多數 Express 中間件。Nest 提供很好的模塊化結構,代碼組織在不同模塊中,進而構建高效、良好擴展的應用。
學習 Node.js 需要掌握大量的后端技能。對于一名小白,開始可選擇 MySQL 等數據庫。只有厘清后端系統設計的基礎知識,才能根據項目的需求,考慮在 MySQL 等基本 SQL 數據庫之外選取后端。
注意:關系數據庫依然是主流。例如,在建模產品、類比、標簽等時依然主要使用關系表結構。類似于電子表格,關系表由行和列組成。
關系數據庫管理系統
SQL Server:微軟的關系數據庫產品,支持標準 ANSI SQL,也提供產品獨有的 SQL 實現。
MySQL:一款優秀的關系數據庫管理系統,時由 Oracle 提供的開源后端軟件,具備按需改進代碼的靈活性。MySQL 可很好地替代 Oracle、Microsoft SQL server 等商業數據庫產品。
PostgreSQL:具有大規模開發團隊支持的開源產品,可運行在 Linux、UNIX 和 Windows 等大多數主流操作系統上。PostgreSQL 支持絕大多數標準 SQL 查詢,還提供復雜 SQL 查詢、外鍵、觸發器、事務、MVCC、流復制等特性。
MariaDB:MySQL 的改進版,額外內建了多種特性、安全和性能改進。簡而言之,MariaDB 性能優于 MySQL,推薦在大型應用中使用 MariaDB。例如,MariaDB 的大型連接池支持超過 20 萬的并發連接,顯著優于 MySQL。
云數據庫服務
Azure CosmosDB:一種全球分布式數據庫服務,支持遠程管理數據。對于大型應用,云數據庫在擴展型和可管理性上具有優勢。Microsoft Azure 完全簡化了可擴展和分布能力,在同一后端上支持多種數據模型,即可同時用于文檔、鍵值、關系和圖模型。該服務不依賴于任何模式,因此可稱為 NoSQL 數據庫,但可使用支持 ACID 交易的查詢語言。
Amazon DynamoDB:非常適用于具有 SQL 經驗的用戶,提供全托管 NoSQL 數據庫服務,具有高性能,可預測,擴展性很好。DynamoDB 支持創建關系表,可存儲并檢索任何規模的數據,提供任何服務等級的請求。
NoSQL 數據庫
MongoDB:面向文檔的 NoSQL 數據庫,適用于大規模數據存儲。類似于表是關系數據庫的基礎,MongoDB 使用集合(Collection)和文檔(Document)。其中,文檔包含了鍵值對,是 MongoDB 的基本數據單元。集合包含一系列文檔和函數,對標關系數據庫中的表。
Redis:可用于數據庫、緩存和消息代理(Message Broker)。Redis 使用字符串、哈希、列表、集合、位圖、hyperloglog 和時空索引等數據結構,以鍵值形式存儲數據。下面舉例說明:
假設應用必須處理授權用戶的不同操作。每次驗證用戶身份,都必須獲取應用中訪問權限控制模塊的授權。實現此類安全機制的方案很多。例如,標準的 JOSE(JavaScript 對象簽名和加密)框架可確保應用數據的安全性。但面對多種授權時,應用同樣很難擴展。除了發送授權列表給用戶,另一種解決方案是將用戶授權以某種形式的數據庫存儲。授權以鍵值對(也稱為令牌)形式提供,用戶必須提供鍵值進行驗證。
Apache Cassandra:Facebook 創建的高度可擴展、高性能的分布式數據庫,設計針對物理上分布的海量數據,實現無單點故障的存儲。不同于其它關系數據庫系統,Cassandra 在分布式設計上參考了 Amazon DynamoDB,數據模型使用 Google BigTable。
LiteDB:一款超輕量級、高性能的 .NET NoSQL 嵌入數據庫,實現無服務器的文檔存儲。LiteDB 使用于小型的桌面應用、Web 應用,可根據每個用戶的每個賬戶建立一個獨立數據庫。
搜索引擎
注意:為什么需要了解搜索引擎技術,下面舉例說明。如果使用谷歌搜索引擎,它本身就是一個完整的 Web 應用。對于 Solr 和 ElasticSearch 等后端框架,它們會對所有類型數據集創建索引,進而在服務器提供搜索功能。Solr 支持百萬級用戶的搜索引擎網站。
ElasticSearch:一種基于 Apache Lucene 使用 Java 開發的搜索和分析引擎,實現海量數據的實時存儲和分析。其高性能來自于對索引而非文本的搜索,核心基于結構化文檔,而非關系表和模式,提供豐富的 REST API 存儲和搜索數據。ElasticSearch 可認為是一臺處理 JSON 請求并返回 JSON 數據的服務器。
Solr:提供包括字段搜索、布爾查詢、短語查詢、模糊查詢、語法檢查、自動填全等高級實時搜索功能。
注意:緩存使用內存中存儲文件拷貝,降低網絡調用,提供更快的網絡響應。
內存緩存
該技術大多數情況下使用服務器的內存,因此通常稱為內存緩存。服務器的一部分內存用作緩存,存儲降低應用網絡調用所需的所有數據。Node.js 提供的節點緩存(node-cache)和內存緩存(memory-cache)軟件庫,很好地處理了 Node 服務器上的內存緩存。
分布式緩存
分布式緩存將多個網絡內存整合為單一的內存數據存儲,進而用于緩存最終數據,提供對數據的快速訪問。該技術尤其適用于大規模數據和大量網絡調用的情況,通過在群集中添加更多的服務器實現緩存容量的增量擴展和擴容。Redis 是目前最廣為使用的 分布式內存,推薦進一步了解 Memcached。
模板引擎支持在應用開發中使用靜態模板文件,并在運行時替換模板文件中的變量為實際值,生成發送給客戶的 HTML 文件。下面列出了一些廣為使用的模板引擎。
Socket.io:對于起步接觸后端開發的學習者,了解 Socket.io 的實時通信需要補充很多知識,主要底層邏輯在客戶端和服務器之間。Socket.io 支持客戶和服務器間的雙向數據流,可視為實現兩個終端間實時通信的同步數據流行為。這需要客戶在瀏覽器支持 Socket.IO,并且服務器端繼承了 Socket.IO 軟件包,進而數據才能以 JSON 請求的形式發送。
REST
在 REST 提出之前,API 使用遠程過程調用(RPC)開發,類似于本地執行的代碼。期間許多技術使用了類似于 RPC 的技術棧,并未從根本上解決問題,直到 REST 提出以更好的方式構建基于 Web 的 API。
REST 架構使用基本 HTTP 調用進行通信,避免了使用 COBRA、COM +,RPC 等復雜方式通信。在 REST 中,調用是基于消息的,依賴 HTTP 標準描述消息。在 Node.js 生態中,推薦使用 node-rest-client 和 Axios。這兩個軟件庫為快速 Web 應用提供了很好的支持。
GraphQL
GraphQL 可很好地替代 REST。它使用 API 優先為客戶準確提供所請求的數據,是一種靈活并且對開發人員友好的替代方案,可使用 GraphiQL IDE 部署。GraphQL 具有多項優點,包括在不影響現有查詢情況下添加和禁用數據域,以及支持多種方式構建 API。
單元測試框架
單元測試實現各單元和組件的隔離測試。其中,單元可以是應用中的最小可測試代碼部分。下面列出 Node.js 的最好的單元測試框架:
模擬測試(Mocking)
單元測試的規模越小越好,并盡可能輕量級執行。但在一些情況下,測試對象存在對其他對象的依賴。
例如,對于需要與域服務器或 Web Service 通信的對象,無法執行快速、輕量級的測試,這時就需要 Mocking 測試。運行 Mocking 測試不需要任何實際數據庫,或是任何類型的連接,只返回給出預期結果的對象。Mocking 測試只使用一些基本對象,模擬給出實際測試結果,因此可擺脫所有局限更快地運行測試。
推薦閱讀: 下面資料分別介紹了如何使用 Sinon 和 Jasmine 實現 Mocking 測試:
Node.js 軟件庫推薦:
原文鏈接:
https://js.plainenglish.io/node-js-developer-roadmap-for-2021-2ae9c057bff4
*請認真填寫需求信息,我們會在24小時內與您取得聯系。