Google App Script "Exception: FILENAME.csv exceeds the maxmium file size" 的变通解决方案?
Workaround solutions to Google App Script "Exception: FILENAME.csv exceeds the maxmium file size"?
我正在构建一个 Google App Maker 应用程序,它将用户上传的 Excel CSV 电子表格文件作为输入。我想过多种可能的解决方案来从这个文件中读取数据,但我每次都遇到这个错误:"Exception: FILENAME.csv exceeds the maximum file size"。我尝试通过 parseCSV() 将数据提取到 Google Cloud SQL,通过 .getBlob().getDataAsString() 作为一个字符串读入并用“\n”拆分,然后写入所有数据到 Google 文档并尝试从那里读取它。但是,所有这些方法都导致了相同的错误。
是否有解决此最大文件大小问题的解决方案?
我想过将文件拆分成更小的 CSV 文件,但我不确定该怎么做。
您想将大型 CSV 文件转换为拆分电子表格。如果我的理解是正确的,这个解决方法怎么样?
这种情况的问题和解决方法:
这么大的CSV文件转换为电子表格时,由于单元格总数和文件大小,无法直接转换为电子表格。而且当尝试拆分大文件时,它也无法拆分,因为可以在 GAS 上使用的 blob 小于 50 MB(52,428,800 字节)。
- 为了拆分这么大的文件,它在驱动器 API 中使用了 "Partial download" of files.get。
在我的环境中,当一个大小为 100 MB 的 CSV 文件用于此示例脚本时,当文件被拆分为 10 MB 时,大约需要 65 秒才能将一个块转换为电子表格。在这种情况下,当CSV文件完全转换时,将被认为超过执行GAS的限制时间(6分钟)。
- 为了避免这种情况,需要实现从大型 CSV 文件到多个电子表格的可恢复转换。
准备:
为了使用此示例脚本,请在高级 Google 服务和 API 控制台启用驱动器 API。
在高级 Google 服务中启用驱动器 API v2
- 在脚本编辑器上
- 资源 -> 高级 Google 服务
- 打开驱动器 API v2
Enable Drive API at API console
- 在脚本编辑器上
- 资源 -> 云平台项目
- 查看API控制台
- 在开始时,单击启用 APIs 并获取密钥等凭据。
- 在左侧,单击“库”。
- 在搜索 API 和服务时,输入 "Drive"。然后单击驱动器 API。
- 单击“启用”按钮。
- 如果API已经启用,请不要关闭。
示例脚本:
function createSplitSpreadsheet(obj) {
var accessToken = ScriptApp.getOAuthToken();
var baseUrl = "https://www.googleapis.com/drive/v3/files/";
// Retrieve file size.
var url1 = baseUrl + obj.fileId + "?fields=size";
var params1 = {
method: "get",
headers: {Authorization: "Bearer " + accessToken},
};
var fileSize = Number(JSON.parse(UrlFetchApp.fetch(url1, {headers: {Authorization: "Bearer " + accessToken}}).getContentText()).size);
// Calculate number of output files.
if (obj.files == null) {
obj.number = 1;
obj.start = 0;
}
var start = obj.start;
var end = start + obj.chunk;
var useFileSize = fileSize - start;
f = Math.floor(useFileSize / obj.chunk);
f = useFileSize % obj.chunk > 0 ? f + 1 : f;
if (f < obj.files || obj.files == null) {
obj.files = f;
}
// Split large file by chunk size (bytes).
var url2 = baseUrl + obj.fileId + "?alt=media";
var i;
for (i = 0; i < obj.files; i++) {
var params = {
method: "get",
headers: {
Authorization: "Bearer " + accessToken,
Range: "bytes=" + start + "-" + end,
},
};
var res = UrlFetchApp.fetch(url2, params).getContentText();
var e = res.lastIndexOf("\n");
start += e + 1;
end = start + obj.chunk;
Drive.Files.insert(
{mimeType: MimeType.GOOGLE_SHEETS, title: obj.fileName + (i + obj.number)},
Utilities.newBlob(res.substr(0, e), MimeType.CSV)
);
}
// Return next start value if there is a next chunk for the resume.
if (start < fileSize) {
return {nextStart: start, nextNumber: i + obj.number};
} else {
return null;
}
}
// Please run this function.
function main() {
var obj = {
fileId: "#####", // File ID of the large CSV file.
chunk: 10485760, // 10MB Please modify this for your situation.
files: 3, // Please input the number of files you want to convert.
start: 0,
fileName: "sample",
number: 1, // Counter of output files. Please input this as a next number.
};
var nextStart = createSplitSpreadsheet(obj);
Logger.log(nextStart);
}
用法:
使用时请根据自己的情况修改main()
中的obj
,运行main()
。示例案例如下
假设如下。
- 您想将大小为 100 MB 的 CSV 文件转换为 10 个电子表格。
- 一个块的大小是 10 MB。
- CSV 文件每 3 处理一次。
本例中,每个obj
如下。请在每个 运行.
输入每个 obj
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: 0, fileName: "sample", number: 1}
{"nextStart": ### nextStart2 ###, "nextNumber": 4}
从 createSplitSpreadsheet()
返回。
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart2 ###, fileName: "sample", number: 4}
{"nextStart": ### nextStart3 ###, "nextNumber": 7}
从 createSplitSpreadsheet()
返回。
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart3 ###, fileName: "sample", number: 7}
{"nextStart": ### nextStart4 ###, "nextNumber": 10}
从 createSplitSpreadsheet()
返回。
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart4 ###, fileName: "sample", number: 10}
null
从 createSplitSpreadsheet()
返回。
通过此流程,从大小为 100 MB 的 CSV 文件创建了 10 个电子表格。
如果null
用于obj
中的files
,则自动计算files
。但在这种情况下,执行GAS的限制时间可能已经结束。请注意这一点。
参考资料:
如果这不是你想要的,我很抱歉。
我正在构建一个 Google App Maker 应用程序,它将用户上传的 Excel CSV 电子表格文件作为输入。我想过多种可能的解决方案来从这个文件中读取数据,但我每次都遇到这个错误:"Exception: FILENAME.csv exceeds the maximum file size"。我尝试通过 parseCSV() 将数据提取到 Google Cloud SQL,通过 .getBlob().getDataAsString() 作为一个字符串读入并用“\n”拆分,然后写入所有数据到 Google 文档并尝试从那里读取它。但是,所有这些方法都导致了相同的错误。
是否有解决此最大文件大小问题的解决方案?
我想过将文件拆分成更小的 CSV 文件,但我不确定该怎么做。
您想将大型 CSV 文件转换为拆分电子表格。如果我的理解是正确的,这个解决方法怎么样?
这种情况的问题和解决方法:
这么大的CSV文件转换为电子表格时,由于单元格总数和文件大小,无法直接转换为电子表格。而且当尝试拆分大文件时,它也无法拆分,因为可以在 GAS 上使用的 blob 小于 50 MB(52,428,800 字节)。
- 为了拆分这么大的文件,它在驱动器 API 中使用了 "Partial download" of files.get。
在我的环境中,当一个大小为 100 MB 的 CSV 文件用于此示例脚本时,当文件被拆分为 10 MB 时,大约需要 65 秒才能将一个块转换为电子表格。在这种情况下,当CSV文件完全转换时,将被认为超过执行GAS的限制时间(6分钟)。
- 为了避免这种情况,需要实现从大型 CSV 文件到多个电子表格的可恢复转换。
准备:
为了使用此示例脚本,请在高级 Google 服务和 API 控制台启用驱动器 API。
在高级 Google 服务中启用驱动器 API v2
- 在脚本编辑器上
- 资源 -> 高级 Google 服务
- 打开驱动器 API v2
Enable Drive API at API console
- 在脚本编辑器上
- 资源 -> 云平台项目
- 查看API控制台
- 在开始时,单击启用 APIs 并获取密钥等凭据。
- 在左侧,单击“库”。
- 在搜索 API 和服务时,输入 "Drive"。然后单击驱动器 API。
- 单击“启用”按钮。
- 如果API已经启用,请不要关闭。
示例脚本:
function createSplitSpreadsheet(obj) {
var accessToken = ScriptApp.getOAuthToken();
var baseUrl = "https://www.googleapis.com/drive/v3/files/";
// Retrieve file size.
var url1 = baseUrl + obj.fileId + "?fields=size";
var params1 = {
method: "get",
headers: {Authorization: "Bearer " + accessToken},
};
var fileSize = Number(JSON.parse(UrlFetchApp.fetch(url1, {headers: {Authorization: "Bearer " + accessToken}}).getContentText()).size);
// Calculate number of output files.
if (obj.files == null) {
obj.number = 1;
obj.start = 0;
}
var start = obj.start;
var end = start + obj.chunk;
var useFileSize = fileSize - start;
f = Math.floor(useFileSize / obj.chunk);
f = useFileSize % obj.chunk > 0 ? f + 1 : f;
if (f < obj.files || obj.files == null) {
obj.files = f;
}
// Split large file by chunk size (bytes).
var url2 = baseUrl + obj.fileId + "?alt=media";
var i;
for (i = 0; i < obj.files; i++) {
var params = {
method: "get",
headers: {
Authorization: "Bearer " + accessToken,
Range: "bytes=" + start + "-" + end,
},
};
var res = UrlFetchApp.fetch(url2, params).getContentText();
var e = res.lastIndexOf("\n");
start += e + 1;
end = start + obj.chunk;
Drive.Files.insert(
{mimeType: MimeType.GOOGLE_SHEETS, title: obj.fileName + (i + obj.number)},
Utilities.newBlob(res.substr(0, e), MimeType.CSV)
);
}
// Return next start value if there is a next chunk for the resume.
if (start < fileSize) {
return {nextStart: start, nextNumber: i + obj.number};
} else {
return null;
}
}
// Please run this function.
function main() {
var obj = {
fileId: "#####", // File ID of the large CSV file.
chunk: 10485760, // 10MB Please modify this for your situation.
files: 3, // Please input the number of files you want to convert.
start: 0,
fileName: "sample",
number: 1, // Counter of output files. Please input this as a next number.
};
var nextStart = createSplitSpreadsheet(obj);
Logger.log(nextStart);
}
用法:
使用时请根据自己的情况修改main()
中的obj
,运行main()
。示例案例如下
假设如下。
- 您想将大小为 100 MB 的 CSV 文件转换为 10 个电子表格。
- 一个块的大小是 10 MB。
- CSV 文件每 3 处理一次。
本例中,每个obj
如下。请在每个 运行.
obj
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: 0, fileName: "sample", number: 1}
{"nextStart": ### nextStart2 ###, "nextNumber": 4}
从createSplitSpreadsheet()
返回。
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart2 ###, fileName: "sample", number: 4}
{"nextStart": ### nextStart3 ###, "nextNumber": 7}
从createSplitSpreadsheet()
返回。
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart3 ###, fileName: "sample", number: 7}
{"nextStart": ### nextStart4 ###, "nextNumber": 10}
从createSplitSpreadsheet()
返回。
var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart4 ###, fileName: "sample", number: 10}
null
从createSplitSpreadsheet()
返回。
通过此流程,从大小为 100 MB 的 CSV 文件创建了 10 个电子表格。
如果null
用于obj
中的files
,则自动计算files
。但在这种情况下,执行GAS的限制时间可能已经结束。请注意这一点。
参考资料:
如果这不是你想要的,我很抱歉。