如何在 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 元素的屏幕截图并将其转换为画布对象,然后可以通过使用其他库(如 jsPDF)将其转换为 PDF。
在 React 中将 HTML 转换为 PDF 的前提条件
对 React 及其生态系统的熟悉
在深入了解 HTML 到 PDF 转换之前,拥有扎实的 React 基础是至关重要的。 这包括对 JSX、状态管理、组件生命周期和钩子的了解。
对 HTML、CSS 和 JavaScript 的理解
在使用 React-pdf 库时,强大的 HTML、CSS 和 JavaScript 基础至关重要。 这包括对 HTML 元素和属性、CSS 样式和选择器的了解,以及 JavaScript 基础知识,如变量、函数和循环。
开始一个 React 应用程序
在我们继续将HTML 转换为 React 中的 PDF之前,让我们快速浏览一下如何使用流行的create-react-app CLI 工具创建一个新的 React 应用程序。 这将是我们 PDF 生成示例的基础。
步骤 1 安装 Node.js
确保您在计算机上安装了 Node.js。您可以从官方 Node.js 网站下载最新版本的 Node.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-pdf 库
React-pdf 是专为 React 应用程序设计的流行库,提供与 React 生态系统的无缝集成。 它的一些关键功能包括支持内联和外部 CSS、多页 PDF 生成、先进的样式和与服务器端渲染(SSR)的兼容性。
使用 React-pdf 创建 PDF 文件
在本节中,我们将重点介绍在 React 应用程序中使用React-pdf创建 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;现在,您可以使用 PDFDownloadLink 组件来自 React-pdf,来下载生成的 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:设置文本对齐方式(例如,'left'、'right'、'center' 或 'justify')。margin:设置元素周围的边距。padding:设置元素内部的填充。border:设置元素周围的边框。backgroundColor:设置元素的背景颜色。
React 开发者的替代 PDF 库
IronPDF for Node.js 是在 React 中将 HTML 转换为 PDF 的一个绝佳替代方案。 由 Iron Software 开发,它是一个强大的库,允许开发人员直接从他们的 Node.js 应用程序生成和处理 PDF 文档。 其突出功能之一是在生成 PDF 时处理 HTML 内容中的 JavaScript 执行能力,从而实现动态和交互式 PDF 创建。
支持包括 Windows、MacOS、Linux、Docker 和像 Azure 和 AWS 这样的云平台,IronPDF 确保跨平台兼容性。 其用户友好的 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 字符串、URLs 或 图像 转换为 PDFs。
- 渲染 PDFs:一旦您使用 IronPDF 生成了 PDFs,您可以使用合适的组件或库在 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 库并尝试一下。








