React.js中如何将含超链接的对象数组导出为PDF报告?
可行解决方案
方案1:结合jspdf + html2canvas + 手动添加链接
直接用jspdf转HTML时链接会丢失,因为html2canvas会把DOM转成位图,无法保留可点击属性。可以先转canvas生成PDF基础内容,再用jspdf的addLink方法手动给对应位置添加可点击链接。
步骤:
- 安装依赖
npm install jspdf html2canvas
- 组件实现示例
import React, { useRef } from 'react'; import jsPDF from 'jspdf'; import html2canvas from 'html2canvas'; const DataPdfExport = () => { const dataRef = useRef(null); const data = [{ profile1: { url: "facebook.com", text: "facebook" }, name: 'Name', profile2: { url: "google.com", text: "google" }, age: 23, country: 'ABc' }]; const exportPdf = async () => { const doc = new jsPDF('p', 'mm', 'a4'); const canvas = await html2canvas(dataRef.current); const imgData = canvas.toDataURL('image/png'); // 将canvas图片导入PDF const imgWidth = 210; const pageHeight = 297; const imgHeight = canvas.height * imgWidth / canvas.width; let heightLeft = imgHeight; let position = 0; doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; while (heightLeft >= 0) { position = heightLeft - imgHeight; doc.addPage(); doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; } // 手动添加链接:需根据实际DOM布局调整坐标 // 可通过元素getBoundingClientRect()获取位置,再转成PDF的mm单位(1px≈0.264583mm) doc.addLink(20, 30, 50, 10, { url: data[0].profile1.url }); doc.addLink(20, 50, 50, 10, { url: data[0].profile2.url }); doc.save('report.pdf'); }; return ( <div> <div ref={dataRef} style={{ padding: '20px', width: '210mm' }}> <p>Profile 1: <a href={data[0].profile1.url}>{data[0].profile1.text}</a></p> <p>Name: {data[0].name}</p> <p>Profile 2: <a href={data[0].profile2.url}>{data[0].profile2.text}</a></p> <p>Age: {data[0].age}</p> <p>Country: {data[0].country}</p> </div> <button onClick={exportPdf}>导出PDF</button> </div> ); }; export default DataPdfExport;
如果用jsautotable,可在表格渲染完成的回调里获取单元格坐标,再调用addLink给对应单元格添加链接。
方案2:用react-pdf正确配置可点击链接
react-pdf不直接解析HTML字符串,需要用它自带的<Link>组件。之前失败大概率是直接传入了HTML格式的链接,未转换成react-pdf支持的组件结构。
步骤:
- 安装依赖
npm install @react-pdf/renderer
- 组件实现示例
import React from 'react'; import { Document, Page, Text, View, Link, StyleSheet, PDFDownloadLink } from '@react-pdf/renderer'; const styles = StyleSheet.create({ page: { padding: 20 }, section: { marginBottom: 10 }, link: { color: 'blue', textDecoration: 'underline' } }); const PdfDocument = ({ data }) => ( <Document> <Page size="A4" style={styles.page}> <View style={styles.section}> <Text>Profile 1: <Link style={styles.link} src={data[0].profile1.url}>{data[0].profile1.text}</Link></Text> </View> <View style={styles.section}> <Text>Name: {data[0].name}</Text> </View> <View style={styles.section}> <Text>Profile 2: <Link style={styles.link} src={data[0].profile2.url}>{data[0].profile2.text}</Link></Text> </View> <View style={styles.section}> <Text>Age: {data[0].age}</Text> </View> <View style={styles.section}> <Text>Country: {data[0].country}</Text> </View> </Page> </Document> ); const DataPdfExport = () => { const data = [{ profile1: { url: "facebook.com", text: "facebook" }, name: 'Name', profile2: { url: "google.com", text: "google" }, age: 23, country: 'ABc' }]; return ( <div> <PDFDownloadLink document={<PdfDocument data={data} />} fileName="report.pdf"> {({ loading }) => loading ? '生成PDF中...' : '导出PDF'} </PDFDownloadLink> </div> ); }; export default DataPdfExport;
注意:
需要把原数据中的HTML链接拆成url和text字段,适配react-pdf的<Link>组件;样式需用react-pdf的StyleSheet定义,不能直接使用普通CSS类。
内容的提问来源于stack exchange,提问作者Lokesh Rayannagari
相关产品推荐
相关产品推荐

