react-pdf 是一个可以在 React 应用中生成、预览、下载 PDF 文件的库。安装npm install @react-pdf/renderer --save创建 pdf创建单页 pdf以创建一个表格视图为例,工具不支持表格组件,需要自己写表格import React from 'react';import { Page, Text, View, Document, StyleSheet, Image } from '@react-pdf/renderer';// 创建样式const styles = StyleSheet.create({ page: { flexDirection: 'row', backgroundColor: '#E4E4E4', padding: 20 }, section: { margin: 10, padding: 10, flexGrow: 1, backgroundColor: 'white', borderRadius: 5 }, title: { fontSize: 18, marginBottom: 10, textAlign: 'center' }, image: { width: '100%', height: 150, marginBottom: 10, borderRadius: 5 }, table: { width: '100%', marginBottom: 10 }, tableRow: { flexDirection: 'row', borderBottom: '1 solid black', padding: 5 }, tableCell: { flex: 1, padding: 5 }});// 创建pdf文档const MyDocument = () => ( <Document> <Page size="A4" style={styles.page}> <View style={styles.section}> <Text style={styles.title}>PDF Example</Text> <Image src="https://www.example.com/logo.png" style={styles.image} /> <Text>Section #1</Text> </View> <View style={styles.section}> <Text style={styles.title}>Table Example</Text> <View style={styles.table}> <View style={styles.tableRow}> <View style={styles.tableCell}> <Text>Name</Text> </View> <View style={styles.tableCell}> <Text>Age</Text> </View> </View> <View style={styles.tableRow}> <View style={styles.tableCell}> <Text>John Doe</Text> </View> <View style={styles.tableCell}> <Text>30</Text> </View> </View> <View style={styles.tableRow}> <View style={styles.tableCell}> <Text>Jane Smith</Text> </View> <View style={styles.tableCell}> <Text>25</Text> </View> </View> </View> </View> </Page> </Document>);export default MyDocument;多页 pdfconst MyPdfDocument = (props) => { return ( <Document> <Page size={{ width: 708, height: 708 / 0.7 }} style={styles.page}> <View> <Image src="https://www.example.com/bg.png" /> </View> </Page> <Page size={{ width: 708, height: 708 / 0.7 }} style={styles.page}> <View> <Image src="https://www.example.com/bg.png" /> </View> </Page> </Document> );};内联样式除了使用 StyleSheet.create 创建样式外,还支持使用多个样式与内联样式使用多个样式对象:const pageStyle = { flexDirection: 'row', backgroundColor: '#E4E4E4',};const sectionStyle = { margin: 10, padding: 10, flexGrow: 1,};const textStyle = { fontSize: 12, color: 'black',};// 使用多个样式对象<View style={[pageStyle, sectionStyle]}> <Text style={textStyle}>Hello, React-PDF!</Text></View>使用内联样式:// 使用内联样式<View style={{ flexDirection: 'row', backgroundColor: '#E4E4E4', margin: 10, padding: 10, flexGrow: 1 }}> <Text style={{ fontSize: 12, color: 'black' }}>Hello, React-PDF!</Text></View>自定义文档尺寸A4: 默认的页面尺寸,类似标准的 A4 纸张尺寸,宽度为 210mm,高度为 297mm。<Page size="A4"> {/* 页面内容 */}</Page>Letter: 类似标准的 Letter 纸张尺寸,宽度为 8.5in(英寸),高度为 11in。<Page size="Letter"> {/* 页面内容 */}</Page>Legal: 类似标准的 Legal 纸张尺寸,宽度为 8.5in,高度为 14in。<Page size="Legal"> {/* 页面内容 */}</Page>Custom: 自定义页面尺寸,可以设置特定的宽度和高度。<Page size={{ width: '210mm', height: '150mm' }}> {/* 页面内容 */}</Page>你还可以指定厘米 cmLandscape: 横向页面,将宽度和高度进行调换,适合横向排列的内容。jsxCopy code<Page size="A4" orientation="landscape"> {/* 页面内容 */}</Page>当你在 size 属性中设置一个数字值而没有指定单位时,默认的单位是“点”(points),这是印刷行业常用的度量单位,1 英寸约等于 72 点。添加字体如需使用中文字体需要自行下载字体文件,并注册import chineseFontBold from '../../assets/苹方粗体字体.ttf';import chineseFont from '../../assets/PingFang SC Regular.ttf';// 注册字体Font.register({ family: 'ChineseFont', src: chineseFontBold });Font.register({ family: 'ChineseFontNormal', src: chineseFont });// 超出宽度自动换行Font.registerHyphenationCallback((word: string) => { // 1. 如果单词只有一个字符,直接返回单个字符。 // 1. 如果单词长度大于 1,将单词拆分为单个字符的数组,并在每个字符之间插入一个空字符串,以表示单词的断开。 if (word.length === 1) { return [word]; } return Array.from(word) .map((char) => [char, '']) .reduce((arr, current) => { arr.push(...current); return arr; }, []);});react-pdf对中文换行处理很不友好,是根据段落中的空格去换行.Font.registerHyphenationCallback 注册了一个自定义的断词回调函数,该函数接受一个单词字符串作为参数,并返回一个数组,其中包含了断开单词后的多个部分,断词后工具可以支持文本自动换行。可用组件Document: 该组件代表PDF文档本身。它必须是树元素结构的根,并且在任何情况下都不应该用作另一个Reaction-pdf组件的子级。此外,它应该只有类型的子项。Page: 表示 PDF 文档中的单个页面,< Document/> 可以包含任意数量的页面,但是确保不会在除 Document 之外的任何组件中呈现页面。View: 类似于 HTML 中的 <div>,用于创建一个容器来包裹其他组件。Image: 用于在 PDF 中插入图像,可以设置图像的路径、宽度、高度等属性。Link: 用于创建一个超链接,可以链接到其他页面或 URL。Note: 用于添加注释或备注,可以在 PDF 中显示一段文本作为注释。Canvas: 用于在 PDF 中绘制图形和图像,可以自定义绘制内容。PDFViewer: 用于在应用中显示 PDF 查看器,允许用户浏览和交互 PDF 内容。Text: 用于添加文本内容,可以设置文本的样式、大小等属性。BlobProvider: 用于提供一个生成 PDF 的容器,通常与 PDFDownloadLink 配合使用。PDFDownloadLink: 用于创建一个下载链接,用户点击后可以下载生成的 PDF 文件。更多详细信息可参考 react-pdf 组件预览 pdfimport React from 'react';import { PDFViewer } from '@react-pdf/renderer';import MyPdfDocument from './MyPdfDocument';const App = () => ( <PDFViewer> <MyPdfDocument /> </PDFViewer>);export default App;注意 : PDFViewer 是 iframe 容器,react的各种provider对其内部组件都是无效的,例如 redux 的Provider,如果要与其内部组件通讯,可以通过props传值方式或纯 js 共享数据,绕过DOM。下载 pdfimport React from 'react';import { PDFDownloadLink } from '@react-pdf/renderer';import MyPdfDocument from './MyPdfDocument';const App = () => ( <div> <PDFDownloadLink document={<MyPdfDocument />} fileName="my-document.pdf"> {({ blob, url, loading, error }) => (loading ? 'Loading ...' : '下载 PDF')} </PDFDownloadLink> </div>);export default App;总结整体来说该工具还是非常好用的,推荐使用。