uni-app App 端分段导出 JSON 数据为文件
在开发过程中,我们经常需要将大量数据导出为 JSON 文件,尤其是在处理长列表或大数据集时。然而,直接将所有数据写入一个文件可能会导致性能问题,尤其是在移动设备上。为了优化性能并提高用户体验,我们可以将数据分段导出到多个文件中。
实现思路
-
分段处理数据:将长 JSON 数据分段,每段包含固定数量的数据。
-
使用
plus.io
写入文件:利用 uni-app 的plus.io
API,将每段数据写入单独的文件。 -
提示用户导出成功:在导出完成后,提示用户文件保存路径。
代码实现
1. 定义导出方法
在组件中定义一个方法 handleExport
,用于分段导出数据。
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. 清空文件
定义一个清空文件夹的方法。
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
方法,例如在按钮点击事件中触发。
clearDirectory("文件_exports");
注意事项
-
文件权限:确保应用已申请文件读写权限,否则可能会导致文件写入失败。
-
文件路径:文件将保存到设备的公共下载目录下的
文件_exports
文件夹中,用户可以通过文件管理器访问。 -
性能优化:分段写入文件可以避免因数据量过大导致的性能问题,同时提高用户体验。
总结
通过上述方法,可以将长 JSON 数据分段导出到多个文件中,避免单个文件过大导致的性能问题。这种方法特别适用于处理大量数据,同时确保应用的性能和用户体验。