HarmonyOS鸿蒙Next中读取和写入excel,文件必须使用沙箱吗?picker选取的公共目录不行吗?

HarmonyOS鸿蒙Next中读取和写入excel,文件必须使用沙箱吗?picker选取的公共目录不行吗? 我用的是第三方库

@archermind/exceljs

打开文件时一直报错 加载失败: Error: No such file or directory(GetRealPath return path is ,<private>)

private async selectAndLoadExcel() {
    try {
      const documentPicker = new picker.DocumentViewPicker();
      const uris = await documentPicker.select();
      if (!uris || uris.length === 0) return;
      this.originalUri = uris[0];

      // 以只读方式打开文件,读取数据
      const file = fs.openSync(this.originalUri, fs.OpenMode.READ_ONLY);
      const stat = fs.statSync(this.originalUri);
      const arrayBuffer = new ArrayBuffer(stat.size);
      fs.readSync(file.fd, arrayBuffer);
      fs.closeSync(file);

      // 解析 Excel
      this.workbook = new ExcelJS.Workbook();
      await this.workbook.xlsx.load(arrayBuffer);
      const worksheet = this.workbook.worksheets[0];
      const cell = worksheet.getCell('B1');
      this.playerId = this.cellValueToString(cell.value);
    } catch (err) {
      console.error('加载失败:', err);
    }
  }

更多关于HarmonyOS鸿蒙Next中读取和写入excel,文件必须使用沙箱吗?picker选取的公共目录不行吗?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

开发者您好,picker选取公共目录文件,可以获取该文件的临时读取权限,查看您提供的代码,statsync方法使用有误,可查看statsync入参说明(文件或目录的应用沙箱路径path、URI或已打开的文件描述符fd),由于不是应用沙箱路径,因此此处需要使用已打开的文件描述符fd,修改后的代码如下:

private async selectAndLoadExcel() {
    try {
      const documentPicker = new picker.DocumentViewPicker();
      const uris = await documentPicker.select();
      if (!uris || uris.length === 0) return;
      this.originalUri = uris[0];

      // 以只读方式打开文件,读取数据
      const file = fs.openSync(this.originalUri, fs.OpenMode.READ_ONLY);
      const stat = fs.statSync(file.fd); // 修改后的代码
      const arrayBuffer = new ArrayBuffer(stat.size);
      fs.readSync(file.fd, arrayBuffer);
      fs.closeSync(file);

      // 解析 Excel
      this.workbook = new ExcelJS.Workbook();
      await this.workbook.xlsx.load(arrayBuffer);
      const worksheet = this.workbook.worksheets[0];
      const cell = worksheet.getCell('B1');
      this.playerId = this.cellValueToString(cell.value);
    } catch (err) {
      console.error('加载失败:', err);
    }
  }

更多关于HarmonyOS鸿蒙Next中读取和写入excel,文件必须使用沙箱吗?picker选取的公共目录不行吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


太感谢您了,这个确实是我太粗心了,犯了一个超低级错误。

是的,在HarmonyOS Next中,读写Excel文件必须使用应用沙箱路径。picker选取的公共目录文件需先拷贝到沙箱内才能操作。系统限制应用直接访问公共目录文件,这是安全机制要求。

关于您的问题,直接说明:

是的,必须使用沙箱路径picker 选取的公共目录 URI 不能直接用于 fs.openSync 等文件操作 API。

错误原因:

  1. picker 返回的 URI 是 content://file:// 格式的媒体库/公共目录 URI,不是沙箱内的绝对路径。
  2. @archermind/exceljs 库底层依赖 fs 模块的同步或流式文件读取,这些 API 只接受沙箱路径(/data/storage/el2/base/haps/...sandbox: 前缀路径)。
  3. 您尝试直接对 picker URI 调用 fs.openSync,系统无法解析该路径,因此报错 No such file or directory 且返回 <private>

正确的操作流程是:

  1. 使用 picker 获取文件 URI。
  2. 将文件从公共目录拷贝到应用沙箱目录(例如沙箱的临时目录 getContext().cacheDirgetContext().filesDir)。
  3. 对沙箱内的文件副本使用 fs.openSync 读取,再传给 exceljs 解析。

无法直接通过 picker URI 在沙箱外读写 Excel 文件。您的代码需增加 fs.copyFile 步骤。

回到顶部