You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何选取Excel文件并通过API上传?

解决React Native中content:// URI无法上传Excel文件的问题

Android返回的content://类型URI是系统内容提供者的统一标识符,并非真实文件路径,无法直接被多数上传API识别。以下是两种可行的解决方案:

方案1:将content URI转换为真实文件路径(使用react-native-fs)

  • 先安装依赖包:
npm install react-native-fs --save
# 或使用yarn
yarn add react-native-fs
  • 编写URI转换函数,获取可用于上传的文件路径或Base64内容:
import RNFS from 'react-native-fs';
import { Platform } from 'react-native';

async function getValidFileResource(contentUri) {
  try {
    if (Platform.OS === 'android') {
      // 直接读取文件为Base64(适合小文件,无需路径转换)
      const base64Content = await RNFS.readFile(contentUri, 'base64');
      // 或尝试获取真实文件路径(部分场景适用)
      const statResult = await RNFS.stat(contentUri);
      return statResult.path || base64Content;
    }
    // iOS下直接返回原URI即可
    return contentUri;
  } catch (error) {
    console.error('URI转换失败:', error);
    return null;
  }
}
  • 结合文件选择与上传逻辑:
import DocumentPicker from 'react-native-document-picker';

async function pickAndUploadExcel() {
  try {
    // 选取Excel文件
    const pickResult = await DocumentPicker.pick({
      type: [DocumentPicker.types.excel],
    });
    // 转换URI为可用资源
    const fileResource = await getValidFileResource(pickResult.uri);
    if (!fileResource) return;

    // 构建FormData用于上传
    const formData = new FormData();
    formData.append('excel_file', {
      uri: Platform.OS === 'android' ? `file://${fileResource}` : fileResource,
      name: pickResult.name,
      type: pickResult.type,
    });

    // 调用上传API
    const uploadResponse = await fetch('你的上传API地址', {
      method: 'POST',
      body: formData,
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
    const responseData = await uploadResponse.json();
    console.log('上传成功:', responseData);
  } catch (err) {
    if (DocumentPicker.isCancel(err)) {
      console.log('用户取消文件选择');
    } else {
      console.error('文件选择或上传失败:', err);
    }
  }
}

方案2:直接获取文件Blob(react-native-document-picker v6+版本支持)

如果使用的是v6及以上版本的react-native-document-picker,可以直接通过getFile()方法获取Blob对象,跳过URI转换步骤:

import DocumentPicker from 'react-native-document-picker';

async function pickAndUploadExcel() {
  try {
    const pickResult = await DocumentPicker.pick({
      type: [DocumentPicker.types.excel],
    });
    // 获取文件Blob
    const fileBlob = await pickResult.getFile();

    const formData = new FormData();
    formData.append('excel_file', fileBlob, pickResult.name);

    // 上传逻辑
    const uploadResponse = await fetch('你的上传API地址', {
      method: 'POST',
      body: formData,
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
    const responseData = await uploadResponse.json();
    console.log('上传成功:', responseData);
  } catch (err) {
    if (DocumentPicker.isCancel(err)) {
      console.log('用户取消文件选择');
    } else {
      console.error('操作失败:', err);
    }
  }
}

注意事项

  • Android权限配置:在AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 10-12 可选MANAGE_EXTERNAL_STORAGE权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Android 13+ 需要单独请求媒体权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_DOCUMENTS" />
  • Android 13+需动态申请权限:
import { PermissionsAndroid } from 'react-native';

async function requestFilePermission() {
  if (Platform.OS === 'android') {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.READ_MEDIA_DOCUMENTS,
      {
        title: '文件读取权限申请',
        message: '需要读取设备中的Excel文件以完成上传',
        buttonPositive: '允许',
        buttonNegative: '取消',
      },
    );
    return granted === PermissionsAndroid.RESULTS.GRANTED;
  }
  return true;
}

内容的提问来源于stack exchange,提问作者Abdul Rehman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 15:45:10