如何在 React 中將 HTML 轉換成 PDF(開發者教程)
在 React 中將 HTML 轉換為 PDF
在 React 中將 HTML 轉換為 PDF 已成為許多 Web 應用程式的必備功能。 無論您是建立發票系統、報表產生器,還是僅僅需要以通用格式共享訊息,PDF 生成都至關重要。 在本文中,我們將探討如何使用流行的程式庫將 HTML 轉換為 PDF,從而在 React 應用程式中建立和設定 PDF 文件樣式。
如何在 React 中將 HTML 轉換為 PDF
- 建立並配置 React 項目
- 下載庫,使用 npm 在 React 中將 HTML 轉換為 PDF。
- 從 React-pdf/renderer 匯入必要的模組
- 使用導入的模組配置 HTML 頁面
- 使用 React-pdf 的**PDFDownloadLink**模組將 HTML 轉換為 PDF
常用的 PDF 生成庫
在深入探討如何將 HTML 轉換為 PDF 之前,讓我們先來討論一些可以在 React 應用程式中用於產生 PDF 的常用程式庫:
- React-pdf:一個強大的程式庫,用於在 React 應用程式中建立 PDF 文件。 它支援多種樣式選項,可以輕鬆建立複雜的多頁 PDF 檔案。
- jsPDF:一個廣泛使用的JavaScript庫,用於即時產生 PDF 檔案。 它提供了多種功能,包括文字樣式設定、圖像嵌入等等。
- html2canvas:此程式庫可讓您擷取 HTML 元素的螢幕截圖並將其轉換為 canvas 對象,然後可以使用 jsPDF 等其他程式庫將其轉換為 PDF。
React 中將 HTML 轉換為 PDF 的前提條件
熟悉 React 及其生態系統
在深入研究 HTML 轉 PDF 之前,對 React 有紮實的了解至關重要。 這包括對 JSX、狀態管理、元件生命週期和鉤子函數的了解。
了解 HTML、CSS 和JavaScript
要使用 React-pdf 函式庫,紮實的 HTML、CSS 和JavaScript基礎至關重要。 這包括對 HTML 元素和屬性、CSS 樣式和選擇器以及JavaScript基礎知識(如變數、函數和循環)的了解。
React 應用程式入門
在開始使用 React 將 HTML 轉換為 PDF之前,讓我們快速了解如何使用流行的 create-react-app CLI 工具建立一個新的 React 應用程式。 這將作為我們產生 PDF 範例的基礎。
步驟 1:安裝Node.js
請確保您的電腦上已安裝Node.js您可以從Node.jsNode.js網站下載最新版本。
步驟 2 安裝 create-react-app
create-react-app 是一個廣泛使用的 CLI 工具,用於產生 React 應用程式。 使用以下命令全域安裝:
npm install -g create-react-appnpm install -g create-react-app步驟 3 建立一個新的 React 應用程式
現在您已經安裝了create-react-app ,可以使用以下命令建立一個新的 React 應用程式:
create-react-app my-pdf-appcreate-react-app my-pdf-app此命令將在名為my-pdf-app 的資料夾中產生一個新的 React 應用程式。 進入新建立的目錄:
cd my-pdf-appcd my-pdf-app步驟 4:啟動開發伺服器
若要啟動開發伺服器並查看您的新 React 應用程式的運行情況,請執行以下命令:
npm startnpm start步驟 5:實作 PDF 生成
現在您已經設定好了 React 應用程序,您可以按照本文前面幾節中概述的步驟,使用React-pdf等流行庫來實現HTML 到 PDF 的 React轉換。
介紹 React-pdf 函式庫
React-pdf 是一個專為 React 應用程式設計的熱門程式庫,可與 React 生態系統無縫整合。 它的一些主要功能包括支援內聯和外部 CSS、多頁 PDF 生成、高級樣式設定以及與伺服器端渲染 (SSR) 的兼容性。
使用 React-pdf 建立 PDF 文件
在本節中,我們將重點介紹如何使用React-pdf在 React 應用程式中建立 PDF 檔案。 首先,您需要安裝React-pdf套件:
npm install --save @react-pdf/renderernpm install --save @react-pdf/renderer安裝完成後,您可以建立一個新的 React 元件來定義 PDF 文件的結構:
import React from 'react';
import {
Document,
Page,
Text,
View,
StyleSheet
} from '@react-pdf/renderer';
// Sample invoice data
const invoiceData = {
sender: {
name: "John Doe",
address: "123 Main Street",
city: "New York",
state: "NY",
zip: "10001",
},
recipient: {
name: "Jane Smith",
address: "456 Elm Street",
city: "San Francisco",
state: "CA",
zip: "94107",
},
items: [
{ description: "Item 1", quantity: 2, unitPrice: 10 },
{ description: "Item 2", quantity: 3, unitPrice: 15 },
{ description: "Item 3", quantity: 1, unitPrice: 20 },
],
invoiceNumber: "INV-123456",
date: "April 26, 2023",
};
// Define styles for PDF document
const styles = StyleSheet.create({
page: {
backgroundColor: "#FFF",
padding: 30,
},
header: {
fontSize: 24,
textAlign: "center",
marginBottom: 30,
},
sender: {
marginBottom: 20,
},
recipient: {
marginBottom: 30,
},
addressLine: {
fontSize: 12,
marginBottom: 2,
},
itemsTable: {
display: "table",
width: "100%",
borderStyle: "solid",
borderWidth: 1,
borderRightWidth: 0,
borderBottomWidth: 0,
},
tableRow: {
margin: "auto",
flexDirection: "row",
},
tableColHeader: {
width: "25%",
borderStyle: "solid",
borderWidth: 1,
borderLeftWidth: 0,
borderTopWidth: 0,
backgroundColor: "#F0F0F0",
},
tableCol: {
width: "25%",
borderStyle: "solid",
borderWidth: 1,
borderLeftWidth: 0,
borderTopWidth: 0,
},
tableCell: {
fontSize: 12,
textAlign: "center",
padding: 5,
},
total: {
marginTop: 20,
textAlign: "right",
},
totalLabel: {
fontSize: 14,
fontWeight: "bold",
},
totalValue: {
fontSize: 14,
},
});
const InvoiceDocument = () => {
// Calculate total amount
const totalAmount = invoiceData.items.reduce(
(total, item) => total + item.quantity * item.unitPrice,
0
);
return (
<Document>
<Page style={styles.page}>
<Text style={styles.header}>Invoice</Text>
<View style={styles.sender}>
<Text>{invoiceData.sender.name}</Text>
<Text>{invoiceData.sender.address}</Text>
<Text>
{invoiceData.sender.city}, {invoiceData.sender.state} {invoiceData.sender.zip}
</Text>
</View>
<View style={styles.recipient}>
<Text>{invoiceData.recipient.name}</Text>
<Text>{invoiceData.recipient.address}</Text>
<Text>
{invoiceData.recipient.city}, {invoiceData.recipient.state} {invoiceData.recipient.zip}
</Text>
</View>
<View style={styles.itemsTable}>
<View style={styles.tableRow}>
<Text style={[styles.tableColHeader, styles.tableCell]}>Description</Text>
<Text style={[styles.tableColHeader, styles.tableCell]}>Quantity</Text>
<Text style={[styles.tableColHeader, styles.tableCell]}>Unit Price</Text>
<Text style={[styles.tableColHeader, styles.tableCell]}>Amount</Text>
</View>
{invoiceData.items.map((item, index) => (
<View key={index} style={styles.tableRow}>
<Text style={[styles.tableCol, styles.tableCell]}>{item.description}</Text>
<Text style={[styles.tableCol, styles.tableCell]}>{item.quantity}</Text>
<Text style={[styles.tableCol, styles.tableCell]}>{item.unitPrice.toFixed(2)}</Text>
<Text style={[styles.tableCol, styles.tableCell]}>
{(item.quantity * item.unitPrice).toFixed(2)}
</Text>
</View>
))}
</View>
<View style={styles.total}>
<Text style={styles.totalLabel}>Total: ${totalAmount.toFixed(2)}</Text>
</View>
</Page>
</Document>
);
};
export default InvoiceDocument;import React from 'react';
import {
Document,
Page,
Text,
View,
StyleSheet
} from '@react-pdf/renderer';
// Sample invoice data
const invoiceData = {
sender: {
name: "John Doe",
address: "123 Main Street",
city: "New York",
state: "NY",
zip: "10001",
},
recipient: {
name: "Jane Smith",
address: "456 Elm Street",
city: "San Francisco",
state: "CA",
zip: "94107",
},
items: [
{ description: "Item 1", quantity: 2, unitPrice: 10 },
{ description: "Item 2", quantity: 3, unitPrice: 15 },
{ description: "Item 3", quantity: 1, unitPrice: 20 },
],
invoiceNumber: "INV-123456",
date: "April 26, 2023",
};
// Define styles for PDF document
const styles = StyleSheet.create({
page: {
backgroundColor: "#FFF",
padding: 30,
},
header: {
fontSize: 24,
textAlign: "center",
marginBottom: 30,
},
sender: {
marginBottom: 20,
},
recipient: {
marginBottom: 30,
},
addressLine: {
fontSize: 12,
marginBottom: 2,
},
itemsTable: {
display: "table",
width: "100%",
borderStyle: "solid",
borderWidth: 1,
borderRightWidth: 0,
borderBottomWidth: 0,
},
tableRow: {
margin: "auto",
flexDirection: "row",
},
tableColHeader: {
width: "25%",
borderStyle: "solid",
borderWidth: 1,
borderLeftWidth: 0,
borderTopWidth: 0,
backgroundColor: "#F0F0F0",
},
tableCol: {
width: "25%",
borderStyle: "solid",
borderWidth: 1,
borderLeftWidth: 0,
borderTopWidth: 0,
},
tableCell: {
fontSize: 12,
textAlign: "center",
padding: 5,
},
total: {
marginTop: 20,
textAlign: "right",
},
totalLabel: {
fontSize: 14,
fontWeight: "bold",
},
totalValue: {
fontSize: 14,
},
});
const InvoiceDocument = () => {
// Calculate total amount
const totalAmount = invoiceData.items.reduce(
(total, item) => total + item.quantity * item.unitPrice,
0
);
return (
<Document>
<Page style={styles.page}>
<Text style={styles.header}>Invoice</Text>
<View style={styles.sender}>
<Text>{invoiceData.sender.name}</Text>
<Text>{invoiceData.sender.address}</Text>
<Text>
{invoiceData.sender.city}, {invoiceData.sender.state} {invoiceData.sender.zip}
</Text>
</View>
<View style={styles.recipient}>
<Text>{invoiceData.recipient.name}</Text>
<Text>{invoiceData.recipient.address}</Text>
<Text>
{invoiceData.recipient.city}, {invoiceData.recipient.state} {invoiceData.recipient.zip}
</Text>
</View>
<View style={styles.itemsTable}>
<View style={styles.tableRow}>
<Text style={[styles.tableColHeader, styles.tableCell]}>Description</Text>
<Text style={[styles.tableColHeader, styles.tableCell]}>Quantity</Text>
<Text style={[styles.tableColHeader, styles.tableCell]}>Unit Price</Text>
<Text style={[styles.tableColHeader, styles.tableCell]}>Amount</Text>
</View>
{invoiceData.items.map((item, index) => (
<View key={index} style={styles.tableRow}>
<Text style={[styles.tableCol, styles.tableCell]}>{item.description}</Text>
<Text style={[styles.tableCol, styles.tableCell]}>{item.quantity}</Text>
<Text style={[styles.tableCol, styles.tableCell]}>{item.unitPrice.toFixed(2)}</Text>
<Text style={[styles.tableCol, styles.tableCell]}>
{(item.quantity * item.unitPrice).toFixed(2)}
</Text>
</View>
))}
</View>
<View style={styles.total}>
<Text style={styles.totalLabel}>Total: ${totalAmount.toFixed(2)}</Text>
</View>
</Page>
</Document>
);
};
export default InvoiceDocument;現在,您可以使用來自 React-pdf 的 PDFDownloadLink 元件來下載產生的 PDF 檔案:
import React from 'react';
import { PDFDownloadLink } from '@react-pdf/renderer';
import InvoiceDocument from './InvoiceDocument';
import './App.css';
const App = () => (
<div className="app-container">
<PDFDownloadLink
document={<InvoiceDocument />}
fileName="invoice.pdf"
className="download-button"
>
{({ loading }) =>
loading ? 'Loading document...' : 'Download Invoice'
}
</PDFDownloadLink>
</div>
);
export default App;import React from 'react';
import { PDFDownloadLink } from '@react-pdf/renderer';
import InvoiceDocument from './InvoiceDocument';
import './App.css';
const App = () => (
<div className="app-container">
<PDFDownloadLink
document={<InvoiceDocument />}
fileName="invoice.pdf"
className="download-button"
>
{({ loading }) =>
loading ? 'Loading document...' : 'Download Invoice'
}
</PDFDownloadLink>
</div>
);
export default App;現在在App.css中加入一些 CSS 樣式以建立自訂 UI:
.app-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #d1e8ff;
}
.download-button {
display: inline-block;
background-color: #5a8fd5;
color: #fff;
font-size: 18px;
font-weight: bold;
padding: 12px 24px;
border-radius: 4px;
text-decoration: none;
cursor: pointer;
transition: background-color 0.3s ease;
}
.download-button:hover {
background-color: #3a68b7;
}在瀏覽器中開啟localhost:3000 。 點選下載按鈕後,PDF 檔案就會被下載。
設定 PDF 文件的樣式
React-pdf庫支援多種樣式選項,類似於 CSS。 以下是一些常用的樣式屬性,可用於自訂 PDF 檔案的外觀:
color:設定文字顏色。fontSize:設定文字的字體大小。fontFamily:設定文字的字型系列。textAlign:設定文字對齊方式(例如,"左對齊"、"右對齊"、"居中對齊"或"兩端對齊")。margin:設定元素周圍的邊距。padding:設定元素內部的內邊距。border:設定元素的邊框。backgroundColor:設定元素的背景顏色。
面向 React 開發者的備選 PDF 函式庫
IronPDF for Node.js是一個優秀的替代方案,可用於在 React 中將 HTML 轉換為 PDF。 該庫由Iron Software開發,功能強大,允許開發人員直接從其Node.js應用程式生成和操作 PDF 文件。 其突出特點之一是能夠在生成 PDF 時處理 HTML 內容中的JavaScript執行,從而實現動態和互動式 PDF 創建。
IronPDF支援包括 Windows、MacOS、Linux、Docker 以及 Azure 和 AWS 等雲端平台在內的各種平台,確保跨平台相容性。 它易於使用的 API 使開發人員能夠快速將 PDF 生成和處理整合到他們的Node.js專案中。
React 是一個用於建立使用者介面的JavaScript庫,由於IronPDF是為Node.js建立的,因此您可以透過利用其Node.js API 將IronPDF整合到您的 React 應用程式中。
以下概述如何將IronPDF與 React 結合使用:
- 安裝IronPDF:您可以使用 npm 或 yarn 在您的 React 專案中安裝IronPDF 。
npm install @ironsoftware/ironpdfnpm install @ironsoftware/ironpdf- 與 React 元件整合:您可以建立利用IronPDF生成和操作 PDF 的 React 元件。 例如,您可以建立一個元件,該元件接受 HTML 內容作為輸入,並使用 IronPDF 的 API 將其轉換為 PDF。
import React from 'react';
import { PdfDocument } from '@ironsoftware/ironpdf';
const HTMLToPDFComponent = () => {
const convertHTMLToPDF = async (htmlContent) => {
try {
const pdf = await PdfDocument.fromHtml(htmlContent);
await pdf.saveAs('generated_pdf.pdf');
alert('PDF generated successfully!');
} catch (error) {
console.error('Error generating PDF:', error);
}
};
return (
<div>
{/* Input HTML content */}
<textarea onChange={(e) => convertHTMLToPDF(e.target.value)} />
</div>
);
};
export default HTMLToPDFComponent;import React from 'react';
import { PdfDocument } from '@ironsoftware/ironpdf';
const HTMLToPDFComponent = () => {
const convertHTMLToPDF = async (htmlContent) => {
try {
const pdf = await PdfDocument.fromHtml(htmlContent);
await pdf.saveAs('generated_pdf.pdf');
alert('PDF generated successfully!');
} catch (error) {
console.error('Error generating PDF:', error);
}
};
return (
<div>
{/* Input HTML content */}
<textarea onChange={(e) => convertHTMLToPDF(e.target.value)} />
</div>
);
};
export default HTMLToPDFComponent;- 處理 PDF 產生:在您的 React 元件中使用 IronPDF 的功能來處理 PDF 的產生、操作和保存。 您可以使用 IronPDF 的方法將HTML 字串、 URL或圖像轉換為 PDF。
- 渲染 PDF:使用IronPDF產生 PDF 後,您可以使用適當的元件或函式庫在 React 應用程式中渲染它們以顯示 PDF 文件。
import React from 'react';
const PDFViewerComponent = () => {
return (
<div>
{/* Render PDF using appropriate component or library */}
<iframe src="generated_pdf.pdf" width="100%" height="600px" title="PDF Viewer" />
</div>
);
};
export default PDFViewerComponent;import React from 'react';
const PDFViewerComponent = () => {
return (
<div>
{/* Render PDF using appropriate component or library */}
<iframe src="generated_pdf.pdf" width="100%" height="600px" title="PDF Viewer" />
</div>
);
};
export default PDFViewerComponent;透過IronPDF,開發人員可以有效地從各種來源生成專業級 PDF 文檔,對其進行自訂以滿足其特定要求,並將 PDF 生成功能無縫整合到其.NET應用程式中。 IronPDF也支援 CSS、 JavaScript和自訂字體等進階功能,確保產生的 PDF 檔案符合應用程式的設計和要求。
結論
本文介紹了使用React-pdf程式庫在 React 中將 HTML 轉換為 PDF的過程。 我們討論了常用的PDF 生成庫、如何使用React-pdf建立和設定PDF 文件樣式,以及產生更複雜 PDF 文件的其他選項。
透過遵循本指南,您現在應該對如何在 React 應用程式中產生 PDF 文件有了紮實的了解,從而能夠產生高品質的 PDF 文件,並滿足各種使用情境的需求。
IronPDF提供免費試用版,您可以先測試該庫,確定它是否滿足您的需求,然後再決定是否購買。 試用期結束後, IronPDF購買許可證的價格從 $799 起,其中包括優先支援和更新。 此外, IronPDF也支援其他語言,如C# .NET 、 Java和Python 。 從IronPDF for Node.js下載IronPDF庫,然後試試看。







