跳過到頁腳內容
PDF工具

如何在 React 中將 HTML 轉換成 PDF(開發者教程)

在 React 中將 HTML 轉換為 PDF

在 React 中將 HTML 轉換為 PDF 已成為許多 Web 應用程式的必備功能。 無論您是建立發票系統、報表產生器,還是僅僅需要以通用格式共享訊息,PDF 生成都至關重要。 在本文中,我們將探討如何使用流行的程式庫將 HTML 轉換為 PDF,從而在 React 應用程式中建立和設定 PDF 文件樣式。

常用的 PDF 生成庫

在深入探討如何將 HTML 轉換為 PDF 之前,讓我們先來討論一些可以在 React 應用程式中用於產生 PDF 的常用程式庫:

  1. React-pdf:一個強大的程式庫,用於在 React 應用程式中建立 PDF 文件。 它支援多種樣式選項,可以輕鬆建立複雜的多頁 PDF 檔案。
  2. jsPDF:一個廣泛使用的JavaScript庫,用於即時產生 PDF 檔案。 它提供了多種功能,包括文字樣式設定、圖像嵌入等等。
  3. 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-app
npm install -g create-react-app
SHELL

步驟 3 建立一個新的 React 應用程式

現在您已經安裝了create-react-app ,可以使用以下命令建立一個新的 React 應用程式:

create-react-app my-pdf-app
create-react-app my-pdf-app
SHELL

此命令將在名為my-pdf-app 的資料夾中產生一個新的 React 應用程式。 進入新建立的目錄:

cd my-pdf-app
cd my-pdf-app
SHELL

步驟 4:啟動開發伺服器

若要啟動開發伺服器並查看您的新 React 應用程式的運行情況,請執行以下命令:

npm start
npm start
SHELL

步驟 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/renderer
npm install --save @react-pdf/renderer
SHELL

安裝完成後,您可以建立一個新的 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;
JAVASCRIPT

現在,您可以使用來自 React-pdfPDFDownloadLink 元件來下載產生的 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;
JAVASCRIPT

現在在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 結合使用:

  1. 安裝IronPDF:您可以使用 npm 或 yarn 在您的 React 專案中安裝IronPDF 。
npm install @ironsoftware/ironpdf
npm install @ironsoftware/ironpdf
SHELL
  1. 與 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;
JAVASCRIPT
  1. 處理 PDF 產生:在您的 React 元件中使用 IronPDF 的功能來處理 PDF 的產生、操作和保存。 您可以使用 IronPDF 的方法將HTML 字串URL圖像轉換為 PDF。
  2. 渲染 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;
JAVASCRIPT

透過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# .NETJavaPython從IronPDF for Node.js下載IronPDF庫,然後試試看。

Darrius Serrant
全棧軟件工程師 (WebOps)

Darrius Serrant 擁有邁阿密大學計算機科學學士學位,目前任職於 Iron Software 的全栈 WebOps 市場營銷工程師。從小就迷上編碼,他認為計算既神秘又可接近,是創意和解決問題的完美媒介。

在 Iron Software,Darrius 喜歡創造新事物,並簡化複雜概念以便於理解。作為我們的駐場開發者之一,他也自願教學生,分享他的專業知識給下一代。

對 Darrius 來說,工作令人滿意因為它被重視且有實際影響。

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me