”即用“ 移动端文件下载

91 阅读1分钟

在React-native上,如何去实现文件内容下载保存代本地呢?

业务背景

在移动端直接调用接口然后返回的数据类型为

'content-type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'

这个时候需要在移动端上直接把数据存储在本地文件中。那么流程是怎么样呢?

  1. 使用 fetch 请求对应的数据
  2. 使用 react-native-fs 将数据写到本地文件中

话不多说,直接上干货(拿来即用)

解决方案

发起 fetch 请求

...
try {
    // 发起请求获取数据
    const response = await fetch(getUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({}),
    });

    if (!response.ok) throw new Error('请求失败');

    // 获取文件类型,这里可以看到接口返回的类型为
    // application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8
    // const contentType = response.headers.get('content-type');
    const contentDisposition = response.headers.get('content-disposition');
    // 获取文件名
    const filename = contentDisposition?.split('filename=')[1] || 'download';

    // 处理文件名
    const newName = decodeURIComponent(filename);

    // 获取二进制数据
    const blob = await response.blob();
    // 将 Blob 转为 Base64
    // 这一步是关键,这样数据才不会发生乱码
    const reader = new FileReader();
    // 异步读取 blob 的内容,并将其转换为 Data URL 格式, 把文件内容编码为 Base64 字符串
    reader.readAsDataURL(blob);
    reader.onloadend = () => {
      // 处理 Base64数据
      const base64Data = reader.result.split(',')[1];
      saveDataToFile(base64Data, newName);
    };
  } catch (error) {
    console.log('error', error);
    throw error;
  }
  ...

将数据写入到本地

import RNFS from 'react-native-fs';

const saveDataToFile = async (base64Data, fileName) => {
  try {
    // 文件保存路径
    const filePath =
      Platform.OS === 'android'
        ? `${RNFS.DownloadDirectoryPath}/${fileName}`
        : `${RNFS.LibraryDirectoryPath}/${fileName}`;

    // 检查文件是否存在
    const exists = await RNFS.exists(filePath);
    if (exists) {
      // 文件已存在,删除旧文件
      await RNFS.unlink(filePath);
    }
    // 写入文件
    await RNFS.writeFile(filePath, base64Data, 'base64');
  } catch (error) {
    console.error('保存文件失败:', error);
    throw error;
  }
};

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。

文章如有错误之处,希望在评论区指正🙏🙏