javascript - 将 excel 文件转换为 Google 电子表格并自动替换现有的电子表格文件
问题描述
提供的代码将文件从 Excel 转换为 Google 表格。此处的代码,但它不会覆盖/替换目标文件夹中当前现有的电子表格文件。是否可以完全转换包括子文件夹内的所有内容并替换任何现有的同名 Google 电子表格文件?
function convertCollection1()
{
var user = Session.getActiveUser(); // Used for ownership testing.1aJcbdGhwliTs_CZ-3ZUvQmGRDzBM7fv9
var origin = DriveApp.getFolderById("1dPsDfoqMQLCokZK4RN0C0VRzaRATr9AN");
var dest = DriveApp.getFolderById("1M6lDfc_xEkR4w61pUOG4P5AXmSGF1hGy");
// Index the filenames of owned Google Sheets files as object keys (which are hashed).
// This avoids needing to search and do multiple string comparisons.
// It takes around 100-200 ms per iteration to advance the iterator, check if the file
// should be cached, and insert the key-value pair. Depending on the magnitude of
// the task, this may need to be done separately, and loaded from a storage device instead.
// Note that there are quota limits on queries per second - 1000 per 100 sec:
// If the sequence is too large and the loop too fast, Utilities.sleep() usage will be needed.
var gsi = dest.getFilesByType(MimeType.GOOGLE_SHEETS), gsNames = {};
while (gsi.hasNext())
{
var file = gsi.next();
if(file.getOwner().getEmail() == user.getEmail())
gsNames[file.getName()] = true;
Logger.log(JSON.stringify(gsNames))
}
// Find and convert any unconverted .xls, .xlsx files in the given directories.
var exceltypes = [MimeType.MICROSOFT_EXCEL, MimeType.MICROSOFT_EXCEL_LEGACY];
for(var mt = 0; mt < exceltypes.length; ++mt)
{
var efi = origin.getFilesByType(exceltypes[mt]);
while (efi.hasNext())
{
var file = efi.next();
// Perform conversions only for owned files that don't have owned gs equivalents.
// If an excel file does not have gs file with the same name, gsNames[ ... ] will be undefined, and !undefined -> true
// If an excel file does have a gs file with the same name, gsNames[ ... ] will be true, and !true -> false
if(file.getOwner().getEmail() == user.getEmail() && !gsNames[file.getName().replace(/\.[^/.]+$/, "")])
{
Drive.Files.insert (
{title: file.getName(), parents: [{"id": dest.getId()}]},
file.getBlob(),
{convert: true}
);
// Do not convert any more spreadsheets with this same name.
gsNames[file.getName()] = true;
}
}
}
Logger.log(JSON.stringify(gsNames))
}
解决方案
- 具有多个子文件夹的文件夹中有 Excel 文件(文件扩展名为 .xlsx 或 .xls)。
- 没有子文件夹的文件夹中有电子表格文件(文件名没有 .xlsx 或 .xls 的扩展名)。
- 您想用从 Excel 文件转换的电子表格覆盖现有的电子表格文件。
- 电子表格和 Excel 文件的数量相同。
从您的问题和评论中,我可以像上面那样理解。
起初,我测试了通过批处理请求更新文件。结果,当使用文件blob进行更新时,似乎无法通过批处理请求来实现文件的更新。关于这一点,如果我找到了解决这种情况的方法,我想更新我的答案。
因此,在这个示例脚本中,我针对上述情况提出了使用 Advanced Google Services 的 Drive API 的方法。
使用此脚本时,请在高级 Google 服务和 API 控制台启用 Drive API。你可以在这里看到这个。
流动:
该脚本的流程如下。
- 检索源和目标文件夹中的文件。
- 当源文件夹中的文件名存在于目标文件夹中时,这些文件将覆盖现有的电子表格文件。
- 当源文件夹中的文件名在目标文件夹中不存在时,这些文件将作为新文件转换为电子表格。
示例脚本:
在运行脚本之前,请先设置sourceFolderId
和destinationFolderId
。
function myFunction() {
var sourceFolderId = "###"; // Folder ID including source files.
var destinationFolderId = "###"; // Folder ID that the converted files are put.
var getFileIds = function (folder, fileList, q) {
var files = folder.searchFiles(q);
while (files.hasNext()) {
var f = files.next();
fileList.push({id: f.getId(), fileName: f.getName().split(".")[0].trim()});
}
var folders = folder.getFolders();
while (folders.hasNext()) getFileIds(folders.next(), fileList, q);
return fileList;
};
var sourceFiles = getFileIds(DriveApp.getFolderById(sourceFolderId), [], "mimeType='" + MimeType.MICROSOFT_EXCEL + "' or mimeType='" + MimeType.MICROSOFT_EXCEL_LEGACY + "'");
var destinationFiles = getFileIds(DriveApp.getFolderById(destinationFolderId), [], "mimeType='" + MimeType.GOOGLE_SHEETS + "'");
var createFiles = sourceFiles.filter(function(e) {return destinationFiles.every(function(f) {return f.fileName !== e.fileName});});
var updateFiles = sourceFiles.reduce(function(ar, e) {
var dst = destinationFiles.filter(function(f) {return f.fileName === e.fileName});
if (dst.length > 0) {
e.to = dst[0].id;
ar.push(e);
}
return ar;
}, []);
if (createFiles.length > 0) createFiles.forEach(function(e) {Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, parents: [{id: destinationFolderId}], title: e.fileName}, DriveApp.getFileById(e.id))});
if (updateFiles.length > 0) updateFiles.forEach(function(e) {Drive.Files.update({}, e.to, DriveApp.getFileById(e.id))});
}
笔记:
- 当您有许多文件要转换并且脚本的执行时间结束时,请划分文件并运行脚本。
参考:
推荐阅读
- php - 如何更好地编写此脚本?在 PHP 中从数组中搜索和提取值
- sql - 合并实体的相似数据
- python - Tensorflow中张量的逐行处理
- html - 如何防止文本重叠导航栏?
- r - R 问题 - 尝试使用非常量分隔符单独拆分数据
- r - ggplot2 geom_jitterdodge 点和叠加闪避箱线图:我想保留点的颜色,但强制箱线图为黑色
- java - 错误:无法下载 kotlin-gradle-plugin.jar (org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50):没有可离线使用的缓存版本
- python - Python CRUD 实例函数崩溃 pyqt5 GUI
- git - 防止git bash自动改变路径
- javascript - 尝试创建一个 for 循环,将其运行的总和迭代地累加到一个总变量中