React Native中使用react-native-html-to-pdf生成动态表格PDF的问题
解决React Native中react-native-html-to-pdf无法渲染动态JavaScript内容的问题
我完全懂你的困扰——用react-native-html-to-pdf生成PDF时,HTML里写的JavaScript代码根本没执行,原本要动态生成的表格行完全出不来,只显示静态的表头和空行。这其实是这个库的底层限制:它依赖的原生HTML转PDF工具(或受限的WebView环境)不会执行HTML中的JavaScript代码,所以onload="addRow()"这种前端逻辑根本跑不起来。
下面给你两种可行的解决思路,优先推荐第一种,简单又靠谱:
方案一:在React Native端提前生成完整HTML字符串
既然HTML里的JS没法执行,那我们就把动态数据的处理逻辑移到React Native的JavaScript代码里,直接拼接出包含所有表格行的完整HTML,再传给react-native-html-to-pdf。
修改后的代码示例:
import React, { Component } from 'react'; import { View, Text, TouchableHighlight} from 'react-native'; import RNHTMLtoPDF from 'react-native-html-to-pdf'; export default class CreatePDFExample extends Component{ async createPDF() { // 模拟你的动态业务数据(可以从接口/本地缓存获取) const tableData = [ { srNo: "1", date: "2024-05-01", particular: "办公采购", type: "支出", currency: "CNY", amount: "890", remark: "文具耗材" }, { srNo: "2", date: "2024-05-03", particular: "项目回款", type: "收入", currency: "CNY", amount: "15000", remark: "A项目第一期" }, { srNo: "3", date: "2024-05-05", particular: "差旅费报销", type: "支出", currency: "CNY", amount: "1200", remark: "北京出差" }, ]; // 动态生成表格行的HTML片段 const tableRows = tableData.map(item => ` <tr style="border: 2px solid #000"> <td>${item.srNo}</td> <td>${item.date}</td> <td>${item.particular}</td> <td>${item.type}</td> <td>${item.currency}</td> <td>${item.amount}</td> <td>${item.remark}</td> </tr> `).join(''); let options = { html: `<!DOCTYPE html> <html> <head> <title>Report</title> <style> .mainContainer { width: 100%; border: 2px solid #000; border-bottom-width: 0px; } .headerContainer { text-align: center; border-bottom: 2px solid #000; } .middleContainer { margin-left: 5%; margin-top: 5%; margin-bottom: 1%; } .tableContent{ width: 100%; border-collapse: collapse; border-top: 0px solid #000; } .tableContent td{ text-align: center; } .bottomline { width: 100%; border-color: #000; border-style: solid; bottom-width: 1px; border-top-width: 0px; } hr{ border: 1px solid #000; margin-left: 10%; margin-right: 10%; } .sign td{ border: 2px solid #000; padding-top: 5%; padding-bottom: 5%; } </style> </head> <body> <div class="mainContainer"> <div class="headerContainer"> <h3>MY SHEET</h3> </div> <div class="middleContainer"> <table> <tr> <td><b>Name:-</b></td> <td></td> </tr> <tr> <td><b>Destination:-</b></td> <td></td> </tr> <tr> <td><b>Date:-</b></td> <td></td> </tr> </table> </div> <div> <table id="tble" class="tableContent" border="1"> <tr style="border: 2px solid #000"> <th>Sr.No</th> <th>Date</th> <th>Particulars</th> <th>Type</th> <th>Currency</th> <th>Amount</th> <th>Remarks</th> </tr> ${tableRows} <!-- 插入动态生成的表格行 --> <tr style="border: 2px solid #000"> <td></td> <td colspan="2"><b>TOTAL</b></td> <td style="text-align: right"><b></b></td> <td style="text-align: right"><b></b></td> <td style="text-align: right"><b></b></td> <td style="text-align: right"><b></b></td> </tr> </table> </div> </div> </body> </html>`, fileName: 'test', directory: 'docs' }; let file = await RNHTMLtoPDF.convert(options); console.log(file.filePath); } render() { return( <View> <TouchableHighlight onPress={this.createPDF.bind(this)}> <Text>Create PDF</Text> </TouchableHighlight> </View> ); } }
这个方案的核心优势:
- 把动态数据的渲染逻辑移到了React Native侧,完全避开HTML内JS执行的限制
- 生成的是完整静态的HTML字符串,传给库后能直接正确渲染所有内容
- 改动量小,只需要替换原来的HTML生成方式,其余样式和结构都能复用
方案二:换用支持JS执行的PDF生成方案
如果你一定要保留HTML内的JavaScript逻辑,可以考虑以下替代方案:
- 使用
react-native-webview先渲染完整的HTML(让JS执行完毕),再调用WebView的截图API,将截图转成PDF(缺点是生成的PDF是图片格式,文字无法选中复制) - 使用
react-native-pdf-lib这类底层库,直接通过代码构建PDF内容,不依赖HTML转PDF的方式
不过方案一无疑是最适合你当前场景的,省心又高效,不需要额外引入新库或改变现有开发习惯。
内容的提问来源于stack exchange,提问作者Sanakhatun Shaikh
相关产品推荐
相关产品推荐

