React Native用expo-print时如何将useState状态传入待打印HTML
React Native 中向 expo-print 传入动态状态数据的实现方案
直接拼接动态HTML的标准实现
expo-print 在Android端接收HTML参数打印的逻辑和iOS端完全一致,不需要做特殊适配,核心是用ES6模板字符串构造打印用的HTML,直接把useState管理的状态通过插值语法嵌入到HTML结构里即可,具体写法参考:
import { useState } from 'react'; import { Button, View } from 'react-native'; import * as Print from 'expo-print'; export default function PrintPage() { // 示例:useState管理的待打印业务数据 const [receiptData, setReceiptData] = useState({ receiptNo: '202405001', customer: '李明', payAmount: 89, goods: [ { title: '原味奶茶', qty: 1, price: 19 }, { title: '鸡米花套餐', qty: 2, price: 35 } ] }); const triggerPrint = async () => { // 用反引号包裹HTML模板,通过${}嵌入状态变量 const printHtml = ` <html> <head> <meta charset="utf-8"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { padding: 24px; font-size: 14px; line-height: 1.5; } .header { text-align: center; font-size: 18px; font-weight: 600; margin-bottom: 20px; } .info-line { display: flex; justify-content: space-between; margin: 6px 0; } .goods-table { width: 100%; border-collapse: collapse; margin: 16px 0; } .goods-table th, .goods-table td { border-bottom: 1px solid #eee; padding: 8px 4px; text-align: left; } .total { font-weight: 600; font-size: 16px; margin-top: 12px; } </style> </head> <body> <div class="header">消费小票</div> <div class="info-line"><span>小票编号</span><span>${receiptData.receiptNo}</span></div> <div class="info-line"><span>客户姓名</span><span>${receiptData.customer}</span></div> <table class="goods-table"> <thead> <tr><th>商品名称</th><th>数量</th><th>单价</th><th>小计</th></tr> </thead> <tbody> ${receiptData.goods.map(item => ` <tr> <td>${item.title}</td> <td>${item.qty}</td> <td>¥${item.price}</td> <td>¥${item.qty * item.price}</td> </tr> `).join('')} </tbody> </table> <div class="info-line total"><span>实付金额</span><span>¥${receiptData.payAmount}</span></div> </body> </html> `; // 传入构造完成的HTML调用打印 await Print.printAsync({ html: printHtml }); }; return ( <View style={{padding: 20}}> <Button title="发起打印" onPress={triggerPrint} /> </View> ); }
常见踩坑注意点
- 不要用单引号/双引号定义HTML字符串,必须用反引号(
`)包裹,才能支持${}插值语法读取最新的状态值。 - 嵌入数组、对象这类复杂状态时,不要直接插值,要先把结构遍历转换成HTML字符串再拼接:比如列表数据用
map生成对应标签字符串后,必须加.join(''),否则打印内容会出现多余的数组逗号分隔符。 - Android端打印中文乱码时,必须在HTML的
<head>标签内加入<meta charset="utf-8">声明编码。 - 如果打印内容始终是旧值,检查HTML构造逻辑是否写在了打印事件函数外部,导致闭包捕获了旧的状态值。
替代方案
如果不想手动拼接HTML字符串,可以选择以下方案:
- 先通过
expo-print的printToFileAsync方法生成带数据的PDF文件,再配合expo-sharing调用系统能力完成打印、分享,兼容性比直接调打印更稳定。 - 替换为
react-native-print库,支持直接传入React Native组件节点渲染生成打印内容,不需要手动编写HTML,注意Android端需要额外配置打印相关权限。
内容的提问来源于stack exchange,提问作者Patryk
相关产品推荐
相关产品推荐

