如何在React Native Expo中转换PDF原始数据并实现下载预览
Expo中处理API返回PDF并预览的正确方案
问题根源
你之前的错误在于直接将PDF文本/Blob丢入Buffer转Base64,忽略了PDF的二进制特性——尤其是开头的非ASCII标识字符,容易导致编码错乱,生成空文件或损坏文件。
正确处理流程
1. 确保API请求的响应类型正确
请求API时,务必设置responseType为'blob'或'arraybuffer',避免默认的文本解析损坏二进制数据:
// 示例:fetch请求设置responseType const response = await fetch('你的PDF接口地址', { method: 'GET', headers: { /* 你的请求头 */ }, responseType: 'blob' // 关键:获取二进制Blob数据 }); const pdfBlob = await response.blob();
2. 用Expo File System保存文件
Expo官方的expo-file-system是处理文件读写的首选,无需 eject,兼容iOS/Android:
import * as FileSystem from 'expo-file-system'; const Buffer = require('buffer').Buffer; // 保存PDF到本地 const savePDF = async (pdfData) => { let base64Str; // 处理Blob类型数据 if (pdfData instanceof Blob) { base64Str = await new Promise(resolve => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result.split(',')[1]); reader.readAsDataURL(pdfData); }); } // 处理文本格式的PDF源码(你当前拿到的类型) else if (typeof pdfData === 'string') { const encoder = new TextEncoder(); const uint8Array = encoder.encode(pdfData); base64Str = Buffer.from(uint8Array).toString('base64'); } // 定义本地保存路径 const savePath = `${FileSystem.documentDirectory}preview.pdf`; // 写入文件 await FileSystem.writeAsStringAsync(savePath, base64Str, { encoding: FileSystem.EncodingType.Base64 }); return savePath; };
3. 预览PDF文件
有两种预览方式:
方式一:调用系统默认应用打开
直接用Expo File System的openAsync方法,唤起系统PDF阅读器:
const previewPDF = async (pdfPath) => { await FileSystem.openAsync(pdfPath); };
方式二:APP内嵌入预览(用expo-pdf-viewer)
安装依赖:
npx expo install expo-pdf-viewer
使用组件预览:
import { PDFViewer } from 'expo-pdf-viewer'; import { useState, useEffect } from 'react'; import * as FileSystem from 'expo-file-system'; export default function PDFPreviewScreen({ pdfData }) { const [pdfPath, setPdfPath] = useState(null); useEffect(() => { const loadPDF = async () => { const path = await savePDF(pdfData); setPdfPath(path); }; loadPDF(); }, [pdfData]); if (!pdfPath) return <Text>加载中...</Text>; return ( <PDFViewer style={{ flex: 1 }} source={{ uri: pdfPath }} /> ); }
关键注意事项
- 不要手动将PDF二进制数据转成普通字符串再编码,直接处理Blob/ArrayBuffer或用
TextEncoder转Uint8Array后再转Base64。 - 保存路径必须用
FileSystem.documentDirectory,这是Expo授权的可读写目录,避免权限报错。 - 如果API返回的是完整PDF文本(如你提供的%PDF-1.4开头内容),确保文本没有被API请求截断,否则会生成损坏的PDF。
内容的提问来源于stack exchange,提问作者Bloom Flora
相关产品推荐
相关产品推荐

