首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >uniapp 实现 APP 文件导出与预览功能记录

uniapp 实现 APP 文件导出与预览功能记录

作者头像
代码简单说
发布2026-06-16 16:25:58
发布2026-06-16 16:25:58
190
举报
文章被收录于专栏:代码简单说代码简单说

uniapp 实现 APP 文件导出与预览功能记录

最近在 APP 中需要实现 文件导出功能,研究了一阵子,主要是文件保存到用户目录,并支持后续文件预览。为了避免自己以后再踩坑,这里快速做一个完整的记录。本文包含 manifest 权限配置、文件保存逻辑、文件预览打开 等核心步骤,适合有类似需求的同学参考。

在这里插入图片描述
在这里插入图片描述

文件读写授权

uniapp 中,如果要在 IOS 和 Android 下将文件保存到用户本地目录,首先需要在 manifest.json 中配置文件读写权限。如果不配置,文件会默认保存到 Android 的包名路径或 IOS 的容器路径,用户无法方便地找到。

示例配置如下:

代码语言:javascript
复制
"android": {
  "permissions": [
    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
    "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>"
   ]
},
"apple": {
  "plistcmds": [
    "Set :NSFileProviderDomainUsageDescription 需要访问文件以保存用户数据",
    "Set :UIFileSharingEnabled true",
    "Set :LSSupportsOpeningDocumentsInPlace true"
  ]
}
  • Android:需要明确指定以 file://storage/emulated/0/ 为开头的路径,才能保存到真正的本地目录。
  • IOS:可以直接写入 _doc 目录。

文件下载、保存并打开

在实际开发中,最容易踩坑的就是 文件重复保存 问题。为了避免这种情况,建议先用 resolveLocalFileSystemURL 判断文件是否已存在:

  1. 文件存在 → 直接执行打开操作;
  2. 文件不存在 → 使用 plus.downloader.createDownload 下载到指定目录,再转为平台路径,然后再打开。

下面贴一下完整的工具方法:

代码语言:javascript
复制
/**
 * 保存并打开文件
 * @param url 文件网络地址
 */
async function saveFile(url: string) {
  const fileName = url.split("/").pop()?.split("?")[0];
  console.log(url);

  // #ifdef APP-PLUS
  let realAbs = "";
  const platform = uni.getSystemInfoSync().platform;

  if (platform === "ios") {
    realAbs = "_doc";
  }

  if (platform === "android") {
    let granted = await permision.requestAndroidPermission(
      "android.permission.WRITE_EXTERNAL_STORAGE"
    );
    if (granted === GrantedStatusEnum.GRANTED) {
      realAbs = "file://storage/emulated/0/Download";
    } else {
      // 没有授权则保存到临时目录
      realAbs = "_downloads";
      notify.showNotify({
        message: `未能授权文件权限,文件将临时保存`,
        type: "danger",
      });
    }
  }

  const relPath = `${realAbs}/${fileName}`;

  // 判断文件是否已存在
  plus.io.resolveLocalFileSystemURL(
    relPath,
    async () => {
      console.log("[saveFile] 文件已存在,直接打开");
      if (platform === "android") {
        await uni.showToast({
          title: `文件已保存至: /Download/${fileName}`,
          icon: "none",
        });
      }
      openDocument(relPath);
    },
    () => {
      console.log("[saveFile] 文件不存在,开始下载");
      const task = plus.downloader.createDownload(
        url,
        { filename: relPath },
        async (d, status) => {
          if (status === 200) {
            if (platform === "android") {
              await uni.showToast({
                title: `文件已保存至: /Download/${fileName}`,
                icon: "none",
              });
            }
            const realAbs = plus.io.convertLocalFileSystemURL(d.filename);
            openDocument(realAbs);
          } else {
            notify.showNotify({
              message: `文件导出失败, 请稍后重试`,
              type: "danger",
            });
          }
        }
      );
      task.start();
    }
  );
  // #endif

  // #ifdef H5
  location.href = url;
  // #endif
}

function openDocument(absPath: string) {
  plus.runtime.openFile(absPath, {}, (res) => {
    if (res.code === -1) {
      notify.showNotify({
        message: "无法打开文件,请检查是否安装对应应用",
        type: "danger",
      });
    }
  });
}

使用体验

  • Android 下,建议将文件保存到 /Download 目录,用户可以直观地在系统下载文件夹找到导出的文件。
  • IOS 下,目前测试时保存路径仍有些问题,指定 _downloads 并未生效,猜测需要额外权限请求。暂时采取写入 _doc 的方案,虽然需要用户在预览后手动保存,但能保证功能基本可用。

结束语

这次研究主要解决了 APP 文件导出与预览 的核心问题,过程中最关键的是权限和文件路径的处理。IOS 的部分还有待继续优化,等后续摸清楚具体的保存规则后会再更新。

如果你在开发中也遇到类似问题,可以先参考本文的实现思路,至少能保证大部分场景下功能可用。后续如果有更优解,我也会继续更新笔记。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • uniapp 实现 APP 文件导出与预览功能记录
    • 文件读写授权
    • 文件下载、保存并打开
    • 使用体验
    • 结束语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档