Expo React Native iOS端HTML转PDF后如何通过expo-share共享文件
问题修复方案
后端逻辑问题修复
原有后端代码同时调用toBuffer和toStream两个方法生成PDF,且两次向同一个请求返回响应,会触发响应重复发送报错,只需保留其中一种返回逻辑即可,推荐使用流方式返回,内存占用更低:
const pdf = require('html-pdf') router.post('/createPdf', (req, res) => { const {html} = req.body pdf.create(html).toStream((err, pdfStream) => { if (err) { console.log(err) return res.sendStatus(500) } res.setHeader('Content-Type', 'application/pdf') res.statusCode = 200 pdfStream.on('end', () => res.end()) pdfStream.pipe(res) }) })
前端逻辑问题修复
你目前前端有两个核心问题:
- axios的
responseType设置为json,无法正确解析二进制PDF流,需要改为blob - 缺失
sharePdf函数的实现,拿到PDF二进制数据后需要先写入本地缓存文件,再调用Expo Sharing接口共享文件
首先安装需要的依赖:
npx expo install expo-file-system expo-sharing
然后修改前端代码:
import * as FileSystem from 'expo-file-system'; import * as Sharing from 'expo-sharing'; const createPdf = () => { const html = insertHtml(orders) // 把生成PDF逻辑放到Alert的Ok回调里,避免用户没确认就生成 Alert.alert('Ordered Success', 'press ok to save a copy', [ { text: 'Ok', onPress: async () => { try { const res = await axios('http://573f-98-14-177-227.ngrok.io/api/createPdf', { method: 'post', data: { html }, // 重点:修改responseType为blob responseType: 'blob', }) await sharePdf(res.data) props.resetOrder() setOrders([]) } catch (error) { console.log('err ', error) } }, }, { text: 'Cancel', style: 'cancel', }, ]) } // 新增sharePdf实现 const sharePdf = async (pdfBlob) => { // 定义本地缓存文件路径 const fileUri = FileSystem.cacheDirectory + 'generated-order.pdf'; // 将blob转换为base64写入本地文件 const reader = new FileReader(); reader.readAsDataURL(pdfBlob); reader.onload = async () => { const base64Data = reader.result.split(',')[1]; await FileSystem.writeAsStringAsync(fileUri, base64Data, { encoding: FileSystem.EncodingType.Base64, }); // 调用共享接口 await Sharing.shareAsync(fileUri, { mimeType: 'application/pdf', dialogTitle: '分享订单PDF', UTI: 'com.adobe.pdf' // iOS专用的文件类型标识 }); } }
内容的提问来源于stack exchange,提问作者shinanl
相关产品推荐
相关产品推荐

