React Native中Android/iOS端从SAS URL批量下载PDF方案咨询
React Native 批量下载PDF方案(支持SAS URL/Buffer、Android/iOS)
准备工作
- 安装依赖:
npm install rn-fetch-blob --save(react-native-fetch-blob已停止维护,推荐使用其维护分支rn-fetch-blob),RN0.60+版本会自动完成链接,低版本需手动执行链接操作 - 配置权限:
- Android:在
AndroidManifest.xml中添加权限声明<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 13+ 需新增以下权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> - iOS:在
Info.plist中添加权限描述<key>NSDocumentFolderUsageDescription</key> <string>需要访问文档目录存储PDF文件</string> <key>UIFileSharingEnabled</key> <true/> <!-- 开启后用户可在系统文件APP中查看下载的PDF -->
- Android:在
批量下载SAS URL来源的PDF
SAS URL自带访问权限,可直接发起请求下载,以下是封装好的批量处理代码:
import RNFetchBlob from 'rn-fetch-blob'; import { Platform } from 'react-native'; // 获取平台对应的存储目录 const getStorageDir = () => { return Platform.OS === 'android' ? RNFetchBlob.fs.dirs.DownloadDir // Android公共下载目录,用户可见 : RNFetchBlob.fs.dirs.DocumentDir; // iOS文档目录 }; // 单个SAS URL PDF下载逻辑 const downloadSASPDF = async (sasUrl, fileName) => { const savePath = `${getStorageDir()}/${fileName}.pdf`; // 检查文件是否已存在,避免重复下载 const isExists = await RNFetchBlob.fs.exists(savePath); if (isExists) { console.log(`文件${fileName}已存在,跳过下载`); return { success: true, filePath: savePath }; } try { const response = await RNFetchBlob.config({ path: savePath }) .fetch('GET', sasUrl); if (response.info().status === 200) { console.log(`${fileName}下载完成`); return { success: true, filePath: savePath }; } else { throw new Error(`下载失败,状态码:${response.info().status}`); } } catch (err) { console.error(`${fileName}下载出错:`, err); return { success: false, error: err.message }; } }; // 批量下载SAS URL PDF const batchDownloadSASPDFs = async (pdfTasks) => { // pdfTasks格式示例:[{ sasUrl: 'xxx', fileName: '合同1' }, { sasUrl: 'xxx', fileName: '合同2' }] const results = []; // 串行下载,避免并发请求过多被限制,也可改用Promise.all并行(需控制并发数) for (const task of pdfTasks) { const result = await downloadSASPDF(task.sasUrl, task.fileName); results.push({ ...task, ...result }); } return results; };
从Buffer保存PDF
如果获取到的是文件Buffer(如接口返回的ArrayBuffer),可直接写入文件:
// 单个Buffer转PDF保存 const savePDFFromBuffer = async (buffer, fileName) => { const savePath = `${getStorageDir()}/${fileName}.pdf`; try { // 将ArrayBuffer转为base64格式写入 const base64Str = Buffer.from(buffer).toString('base64'); await RNFetchBlob.fs.writeFile(savePath, base64Str, 'base64'); console.log(`${fileName}从Buffer保存完成`); return { success: true, filePath: savePath }; } catch (err) { console.error(`${fileName}保存出错:`, err); return { success: false, error: err.message }; } }; // 批量从Buffer保存PDF const batchSavePDFsFromBuffer = async (bufferTasks) => { // bufferTasks格式示例:[{ buffer: xxx, fileName: '报告1' }, { buffer: xxx, fileName: '报告2' }] const results = []; for (const task of bufferTasks) { const result = await savePDFFromBuffer(task.buffer, task.fileName); results.push({ ...task, ...result }); } return results; };
额外提示
- 并发控制:如果采用并行下载,建议用
Promise.allSettled替代Promise.all,避免单个任务失败导致全部中断,同时可限制并发数(如一次最多下载3个) - 重试逻辑:可在下载失败时添加1-2次重试机制,提升成功率
- 文件覆盖:如果需要强制覆盖已存在的文件,可在下载前先执行
RNFetchBlob.fs.unlink(savePath)删除旧文件
内容的提问来源于stack exchange,提问作者mayank verma
相关产品推荐
相关产品推荐

