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 数据分段导出到多个文件中,避免单个文件过大导致的性能问题。这种方法特别适用于处理大量数据,同时确保应用的性能和用户体验。

相关推荐
2501_916007475 小时前
HTTPS 抓包的流程,代理抓包、设备数据线直连抓包、TCP 数据分析
网络协议·tcp/ip·ios·小程序·https·uni-app·iphone
游戏开发爱好者86 小时前
React Native iOS 代码如何加密,JS 打包 和 IPA 混淆
android·javascript·react native·ios·小程序·uni-app·iphone
2501_915918417 小时前
iOS mobileprovision 描述文件管理,新建、下载和内容查看
android·ios·小程序·https·uni-app·iphone·webview
00后程序员张8 小时前
iOS 应用程序使用历史记录和耗能记录怎么查?
android·ios·小程序·https·uni-app·iphone·webview
学亮编程手记8 小时前
Mars-Admin 基于Spring Boot 3 + Vue 3 + UniApp的企业级管理系统
vue.js·spring boot·uni-app
万物得其道者成12 小时前
uni-app CLI:APP 多环境打包(测试/正式)最简配置 + `import.meta.env` 为 `undefined` 的解决
uni-app
毕设源码-邱学长12 小时前
【开题答辩全过程】以 基于 uni-app Node.js 的音乐系统设计与实现为例,包含答辩的问题和答案
uni-app
qq_3168377512 小时前
华为obs 私有桶 音频 使用uniapp 安卓端播放-99的问题
uni-app·音视频
凉辰1 天前
uniapp实现生成海报功能 (开箱即用)
javascript·vue.js·小程序·uni-app
笨笨狗吞噬者1 天前
【uniapp】小程序支持分包引用分包 node_modules 依赖产物打包到分包中
前端·微信小程序·uni-app