为使用 google 应用程序脚本和网络应用程序表单上传的所有文件创建一个文件夹
Create one folder for all files uploaded with google apps script and web app form
我有一个带有 GAS 的网络应用程序。此 Web 应用程序具有三个输入(输入 1、输入 2、上传文件输入),两个用于元数据,一个用于上传文件。上传输入是多上传文件输入。当我提交表单时,代码必须为我上传的所有文件生成一个文件夹,并将数据注册在 google sheet 中。例如,我上传文件 1 和文件 2,其中包含文件夹名称的名称或输入 1 的条目。但是,当我转到 google 驱动器时,代码会生成两个同名文件夹,换句话说,例如,两个文件夹,第一个包含文件 1,文件夹名称为“文件夹 1”,第二个文件 2 的文件夹名称为“文件夹 1”。我如何才能为所有文件生成一个文件夹?我的代码有什么问题?你能帮助我吗?
问候!
这是我的代码:
<html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
crossorigin="anonymous"
/>
<title>TITLE</title>
</head>
<body>
<div class="container">
<h4>Ingrese datos</h4>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="numsip"
type="text"
placeholder="Set Name for folder"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="rut"
type="number"
placeholder="Set idnumber"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="files"
type="file"
placeholder="Seleccione Archivos"
multiple
/>
</div>
</div>
<button id="contactar" class="btn btn-primary" onclick="enviardatos()">
Generar carpeta
</button>
</div>
<script
src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
crossorigin="anonymous"
></script>
</body>
<script>
function enviardatos() {
var sip = document.getElementById("numsip");
var rut = document.getElementById("rut");
var array = { numsip: sip.value, rut: rut.value };
const f = document.getElementById("files");
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {
fileName: f.files[i].name,
mimeType: data[0].match(/:(\w.+);/)[1],
data: data[1],
};
google.script.run
.withSuccessHandler((id) => {
console.log(id);
})
.addNewRow(array, obj);
};
fr.readAsDataURL(file);
});
alert("Se ha generado carpeta");
}
</script>
</html>
</html>
这是 google 应用程序脚本的服务器端函数:
function addNewRow(array, obj) {
var timestamp = new Date();
var parentFolderId = 'URLPARENTFOLDER';
var parentFolder = DriveApp.getFolderById(parentFolderId);
var user = Session.getActiveUser().getEmail();
var foldercreated = parentFolder.createFolder('SIP ' + array.numsip + '/' + array.rut);
var idfolder = foldercreated.getId();
var url = 'URLSHEET';
var values = SpreadsheetApp.openByUrl(url);
var ss = values.getSheetByName('DATA');
ss.appendRow([array.numsip, array.rut, timestamp, user, idfolder]);
var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
return foldercreated.createFile(blob).getId();
}
*我省略了“doGet”函数...
我相信你的目标如下。
- 您想将上传的文件放到指定的文件夹中。
- 当
"SIP "+array.numsip+"/"+array.rut
的文件夹名称存在于 parentFolder
中时,您不想创建具有相同文件夹名称的文件夹。您想将文件放入现有文件夹。
修改点:
- 在这种情况下,我想建议修改 Google Apps Script 端的
addNewRow
和 Javascript 端的 enviardatos()
的功能。
- 在您当前的脚本中,新文件夹由
var foldercreated = parentFolder.createFolder("SIP "+array.numsip+"/"+array.rut)
每 运行 创建一次。所以这部分需要修改。
- 检查是否存在同名文件夹。
- 而且,您的 Google Apps 脚本端,我认为未使用函数底部的
var parentFolder=DriveApp.getFolderById(parentFolderId);
。
- 但是,您的脚本中还有更重要的一点。
[...f.files].forEach((file, i) => {,,,})
中的脚本是运行的异步处理。这样,即使修改 Google Apps Script 端的脚本,也会创建重复的文件夹名称。所以需要也修改Javascript端的脚本
当以上几点反映到你的脚本中,就会变成如下。请修改addNewRow
函数如下
修改后的脚本:
Google Apps 脚本端:
请设置URLPARENTFOLDER
和URLSHEET
。
function addNewRow(array,obj) {
var timestamp = new Date();
var parentFolderId = "URLPARENTFOLDER";
var parentFolder = DriveApp.getFolderById(parentFolderId);
var user = Session.getActiveUser().getEmail();
var folderName = "SIP "+array.numsip+"/"+array.rut;
var foldercreated = parentFolder.getFoldersByName(folderName);
foldercreated = foldercreated.hasNext() ? foldercreated.next() : parentFolder.createFolder(folderName);
var idfolder= foldercreated.getId()
var url = "URLSHEET";
var values = SpreadsheetApp.openByUrl(url);
var ss= values.getSheetByName("DATA");
ss.appendRow([array.numsip,array.rut,timestamp,user,idfolder]);
return obj.map(({fileName, mimeType, data}) => {
var blob = Utilities.newBlob(Utilities.base64Decode(data), mimeType, fileName);
return foldercreated.createFile(blob).getId();
});
}
Javascript 边:
请修改Javascript端的enviardatos()
如下。
从:
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
google.script.run.withSuccessHandler((id) => {console.log(id);}).addNewRow(array, obj);
}
fr.readAsDataURL(file);
});
到:
Promise.all([...f.files].map((file, i) => {
const fr = new FileReader();
return new Promise((r, rj) => {
fr.onload = (e) => {
const data = e.target.result.split(",");
r({fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]});
}
fr.onerror = (e) => rj(e);
fr.readAsDataURL(file);
});
}))
.then(obj => google.script.run.withSuccessHandler(console.log).addNewRow(array, obj))
.catch(err => console.log(err));
参考文献:
我有一个带有 GAS 的网络应用程序。此 Web 应用程序具有三个输入(输入 1、输入 2、上传文件输入),两个用于元数据,一个用于上传文件。上传输入是多上传文件输入。当我提交表单时,代码必须为我上传的所有文件生成一个文件夹,并将数据注册在 google sheet 中。例如,我上传文件 1 和文件 2,其中包含文件夹名称的名称或输入 1 的条目。但是,当我转到 google 驱动器时,代码会生成两个同名文件夹,换句话说,例如,两个文件夹,第一个包含文件 1,文件夹名称为“文件夹 1”,第二个文件 2 的文件夹名称为“文件夹 1”。我如何才能为所有文件生成一个文件夹?我的代码有什么问题?你能帮助我吗? 问候! 这是我的代码:
<html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
crossorigin="anonymous"
/>
<title>TITLE</title>
</head>
<body>
<div class="container">
<h4>Ingrese datos</h4>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="numsip"
type="text"
placeholder="Set Name for folder"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="rut"
type="number"
placeholder="Set idnumber"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="files"
type="file"
placeholder="Seleccione Archivos"
multiple
/>
</div>
</div>
<button id="contactar" class="btn btn-primary" onclick="enviardatos()">
Generar carpeta
</button>
</div>
<script
src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
crossorigin="anonymous"
></script>
</body>
<script>
function enviardatos() {
var sip = document.getElementById("numsip");
var rut = document.getElementById("rut");
var array = { numsip: sip.value, rut: rut.value };
const f = document.getElementById("files");
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {
fileName: f.files[i].name,
mimeType: data[0].match(/:(\w.+);/)[1],
data: data[1],
};
google.script.run
.withSuccessHandler((id) => {
console.log(id);
})
.addNewRow(array, obj);
};
fr.readAsDataURL(file);
});
alert("Se ha generado carpeta");
}
</script>
</html>
</html>
这是 google 应用程序脚本的服务器端函数:
function addNewRow(array, obj) {
var timestamp = new Date();
var parentFolderId = 'URLPARENTFOLDER';
var parentFolder = DriveApp.getFolderById(parentFolderId);
var user = Session.getActiveUser().getEmail();
var foldercreated = parentFolder.createFolder('SIP ' + array.numsip + '/' + array.rut);
var idfolder = foldercreated.getId();
var url = 'URLSHEET';
var values = SpreadsheetApp.openByUrl(url);
var ss = values.getSheetByName('DATA');
ss.appendRow([array.numsip, array.rut, timestamp, user, idfolder]);
var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
return foldercreated.createFile(blob).getId();
}
*我省略了“doGet”函数...
我相信你的目标如下。
- 您想将上传的文件放到指定的文件夹中。
- 当
"SIP "+array.numsip+"/"+array.rut
的文件夹名称存在于parentFolder
中时,您不想创建具有相同文件夹名称的文件夹。您想将文件放入现有文件夹。
修改点:
- 在这种情况下,我想建议修改 Google Apps Script 端的
addNewRow
和 Javascript 端的enviardatos()
的功能。 - 在您当前的脚本中,新文件夹由
var foldercreated = parentFolder.createFolder("SIP "+array.numsip+"/"+array.rut)
每 运行 创建一次。所以这部分需要修改。- 检查是否存在同名文件夹。
- 而且,您的 Google Apps 脚本端,我认为未使用函数底部的
var parentFolder=DriveApp.getFolderById(parentFolderId);
。 - 但是,您的脚本中还有更重要的一点。
[...f.files].forEach((file, i) => {,,,})
中的脚本是运行的异步处理。这样,即使修改 Google Apps Script 端的脚本,也会创建重复的文件夹名称。所以需要也修改Javascript端的脚本
当以上几点反映到你的脚本中,就会变成如下。请修改addNewRow
函数如下
修改后的脚本:
Google Apps 脚本端:
请设置URLPARENTFOLDER
和URLSHEET
。
function addNewRow(array,obj) {
var timestamp = new Date();
var parentFolderId = "URLPARENTFOLDER";
var parentFolder = DriveApp.getFolderById(parentFolderId);
var user = Session.getActiveUser().getEmail();
var folderName = "SIP "+array.numsip+"/"+array.rut;
var foldercreated = parentFolder.getFoldersByName(folderName);
foldercreated = foldercreated.hasNext() ? foldercreated.next() : parentFolder.createFolder(folderName);
var idfolder= foldercreated.getId()
var url = "URLSHEET";
var values = SpreadsheetApp.openByUrl(url);
var ss= values.getSheetByName("DATA");
ss.appendRow([array.numsip,array.rut,timestamp,user,idfolder]);
return obj.map(({fileName, mimeType, data}) => {
var blob = Utilities.newBlob(Utilities.base64Decode(data), mimeType, fileName);
return foldercreated.createFile(blob).getId();
});
}
Javascript 边:
请修改Javascript端的enviardatos()
如下。
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
google.script.run.withSuccessHandler((id) => {console.log(id);}).addNewRow(array, obj);
}
fr.readAsDataURL(file);
});
到:
Promise.all([...f.files].map((file, i) => {
const fr = new FileReader();
return new Promise((r, rj) => {
fr.onload = (e) => {
const data = e.target.result.split(",");
r({fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]});
}
fr.onerror = (e) => rj(e);
fr.readAsDataURL(file);
});
}))
.then(obj => google.script.run.withSuccessHandler(console.log).addNewRow(array, obj))
.catch(err => console.log(err));