uni-app App 端分段导出 JSON 数据为文件

在开发过程中,我们经常需要将大量数据导出为 JSON 文件,尤其是在处理长列表或大数据集时。然而,直接将所有数据写入一个文件可能会导致性能问题,尤其是在移动设备上。为了优化性能并提高用户体验,我们可以将数据分段导出到多个文件中。

实现思路

  1. 分段处理数据:将长 JSON 数据分段,每段包含固定数量的数据。

  2. 使用 plus.io 写入文件 :利用 uni-app 的 plus.io API,将每段数据写入单独的文件。

  3. 提示用户导出成功:在导出完成后,提示用户文件保存路径。

代码实现

1. 定义导出方法

在组件中定义一个方法 handleExport,用于分段导出数据。

javascript 复制代码
const handleExport = (annoList) => {
  console.log("开始分段导出数据");
  isLoadingPage.value = true;
  loadingPageText.value = "导出中...";


  const chunkSize = 10; // 每组10个数据
  const totalChunks = Math.ceil(annoList.length / chunkSize); // 总组数

  // 使用 plus.io 写入文件
  plus.io.requestFileSystem(plus.io.PUBLIC_DOWNLOADS, (fs) => {
    fs.root.getDirectory("文件_exports", { create: true }, (dirEntry) => {
      // 创建一个目录用于存储所有 JSON 文件
      let currentChunk = 0;

      const writeChunk = () => {
        if (currentChunk >= totalChunks) {
          isLoadingPage.value = false;
          uni.showToast({
            title: `导出成功,路径:${dirEntry.fullPath}`,
            icon: "none",
          });
          return;
        }

        const start = currentChunk * chunkSize;
        const end = start + chunkSize;
        const chunkData = annoList.slice(start, end); // 获取当前分段数据
        const jsonString = JSON.stringify(chunkData, null, 2); // 格式化为 JSON 字符串
        const fileName = `data_chunk_${currentChunk + 1}.json`; // 文件名:data_chunk_1.json, data_chunk_2.json, ...

        dirEntry.getFile(fileName, { create: true }, (fileEntry) => {
          fileEntry.createWriter((writer) => {
            writer.onwrite = () => {
              console.log(`文件 ${fileName} 导出成功`);
              currentChunk++;
              writeChunk(); // 写入下一个分段
            };
            writer.write(jsonString); // 写入当前分段数据
          });
        });
      };

      writeChunk(); // 开始写入
    });
  });
};
2. 调用导出方法

调用 handleExport 方法,例如在按钮点击事件中触发。

3. 清空文件

定义一个清空文件夹的方法。

javascript 复制代码
const clearDirectory = async (dirName) => {
  try {
    // 获取文件系统
    plus.io.requestFileSystem(
      plus.io.PUBLIC_DOWNLOADS,
      (fs) => {
        // 获取目标文件夹
        fs.root.getDirectory(
          dirName,
          { create: false },
          (dirEntry) => {
            console.log(`目录 ${dirName} 已获取成功`);

            // 创建目录阅读器
            const reader = dirEntry.createReader();

            // 读取目录中的所有条目
            reader.readEntries(
              (entries) => {
                // 递归删除所有条目
                const deleteEntry = (entry) => {
                  if (entry.isFile) {
                    entry.remove(
                      () => {
                        console.log(`文件 ${entry.name} 已删除`);
                      },
                      (error) => {
                        console.error(`删除文件 ${entry.name} 时出错:`, error);
                      }
                    );
                  } else if (entry.isDirectory) {
                    entry.removeRecursively(
                      () => {
                        console.log(`目录 ${entry.name} 已删除`);
                      },
                      (error) => {
                        console.error(`删除目录 ${entry.name} 时出错:`, error);
                      }
                    );
                  }
                };

                // 遍历并删除所有条目
                entries.forEach(deleteEntry);

                // 检查是否所有条目都已删除
                const checkDirectory = () => {
                  reader.readEntries((remainingEntries) => {
                    if (remainingEntries.length === 0) {
                      console.log(`目录 ${dirName} 已清空`);
                    } else {
                      remainingEntries.forEach(deleteEntry);
                      checkDirectory(); // 递归检查
                    }
                  });
                };

                checkDirectory(); // 开始检查
              },
              (error) => {
                console.error(`读取目录 ${dirName} 时出错:`, error);
              }
            );
          },
          (error) => {
            console.error(`获取目录 ${dirName} 时出错:`, error);
          }
        );
      },
      (error) => {
        console.error(`请求文件系统时出错:`, error);
      }
    );
  } catch (error) {
    console.error(`清空目录时出错:`, error);
  }
};
4. 调用清空方法

调用 handleExport 方法,例如在按钮点击事件中触发。

javascript 复制代码
 clearDirectory("文件_exports");

注意事项

  1. 文件权限:确保应用已申请文件读写权限,否则可能会导致文件写入失败。

  2. 文件路径 :文件将保存到设备的公共下载目录下的 文件_exports 文件夹中,用户可以通过文件管理器访问。

  3. 性能优化:分段写入文件可以避免因数据量过大导致的性能问题,同时提高用户体验。

总结

通过上述方法,可以将长 JSON 数据分段导出到多个文件中,避免单个文件过大导致的性能问题。这种方法特别适用于处理大量数据,同时确保应用的性能和用户体验。

相关推荐
一只程序熊7 小时前
Uniapp 字体加载问题(文件本地存储)
uni-app
星月昭铭9 小时前
uni-app打包h5并部署到nginx,路由模式history
nginx·uni-app
xiyueta17 小时前
基于UniApp + Vue3开发的智能汉字转拼音工具
uni-app
洪洪呀1 天前
uni-app & vue2 记住密码功能
前端·javascript·uni-app
新兵蛋子CodeLiu1 天前
uni-app多端资源文件下载实现方案
vue.js·uni-app
小钟H呀1 天前
【UniApp跳转外部链接】实现方案
uni-app
unioncron2 天前
uniapp上传文件问题以及返回上一页出现退出app的问题记录
android·前端·uni-app
狼性书生2 天前
uniapp 实现的步进指示器组件
前端·uni-app·vue·组件
小旋风012342 天前
uniapp实现 uview1 u-button的水波纹效果
uni-app