Skip to content

ChengYiLin/Generate-PDF-from-React-SSR

Repository files navigation

Generate PDF from React SSR

Introduction

當我們在電商購買商品,無論是哪一種物流配送方式,
商家都需要填一張託運單黏貼在寄件物上,這樣在運送過程中才知道它要送去哪裡,
通常在商家的後台都會有功能可以批次列印這些託運單 (如下方使用黑貓的示意圖),
上面會有固定的樣板,且在欄位上都會帶入對應的寄件人、寄件地址等相關資訊,
那麼有沒有想過這是怎麼做到的呢?

託運單範例

我們公司這邊過去是使用 RDLC 這套工具來產生這些託運單,
但就我這邊接受到的其他工程師反饋,似乎在排版上會遇到一些困難,
在開發及維護上都會是一個成本,因此決定要汰換這個做法。
在 Server 端,有找到一個套件來產生 PDF (ironpdf),
但這需要 Frontend 來協助刻 Html 樣板,另外很重要的一點,這還需要錢買授權~

剛好最近在研究 React Server Side Render,
於是想說有沒有使用 React 來產生 PDF 的可能性呢?
於是產生下圖這個初步的構想及流程 :

  1. User 在頁面按下按鈕發送 Request 到我們的 API Server
  2. API Server 會撈取相關的寄件資訊,再透過 API 的方式送到 SSR Server
  3. 將 Request 的寄件資料傳送到 React Component 中,並透過 SSR 方式產生對應的 Html 結構
  4. 使用 NodeJS 的免費套件,將 html 轉換為 PDF
  5. 直接將產生的 PDF 回傳給 API Server,再交給 API Server 傳遞給 User

React SSR

Skills Stack

Package Description
React Frontend framework, Build the Html5 template
Tailwind CSS CSS framework, Styling the React Component
Express Server Side Render Server, Do the React SSR
ejs Server Side Engine Template, Help to generate Html template
puppeteer Headless Chrome Node.js API, Help to generate PDF file from Html

Implementation Detail

Step1. Build the Fullstack Template : React + Express

這一整個產生 PDF 的服務是運作在 Node.js 之上的,
這邊選用 Express 來進行實作,並且使用 ejs 作為 Template Engine,
在前端的部分則是使用 React,並搭配 react-dom 這個 package 來完成 SSR,
分別在 Server Side 使用 renderToString 及 Client Side 使用 hydrateRoot
相關的實作細節在 Reference 中的 這篇文章 都寫得很詳盡 ,就不多著墨了

Step2. Styling the React Component

經由上方的實作,應該可以完成很基本的 React SSR 流程,
接下來就是要為 React 建立樣式了,這邊選用 Tailwind CSS 來開發,
實作上用最簡單的方式,因為我們使用 ejs 作為 Server Template Engine,
因此直接在 Layout 的 template 引用 Tailwind CDN 快速導入,在官方文件也有相關敘述 (Link)

Step3. Generate PDF file from React

這邊使用 puppeteer 這個 Node.js 的爬蟲工具來產生 PDF,
在它的 example 中就有提到它能產生 PDF 及 Screenshot,
實作方式也相當簡單,我這邊有包成一個 Function 來處理產 PDF 這個流程,

原先是 Server 透過 ReactDOMServer.renderToString 來產生 Html5 String,
並把它放到 ejs Template 中渲染,直接 Response 一個 Html 回給瀏覽器,
而產生 PDF 這件事就是在 Response 之前運行上面產 PDF 的 function,
再將 PDF 的結果 Response 給 需求端

Step4. React Get the Server Side Request Data

因為整體服務的資料來源是放在另一個 API Server,
會經由 API 的方式,透過 Request 送到 SSR Server 中,
因此我們的 React Component 要能夠接收到來自 Server Side 的資料,
這邊就透過 Server Side 的 React.createElement 第二個參數,
經由 Props 傳入 Component 中進行畫面渲染

Reference

React SSR

Html To PDF

Styling

About

Implement React Server Side Render with NodeJS Express

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published