英文:
AppScript not reading dropdown in Google Docs Table
问题
这是您的Google Apps Script代码的翻译部分:
function combineTablesFromDocuments() {
var folderId = "1KW8OPJr9D9qkJI2C5Zea5WbX6iPAwYOz"; // 包含文档的文件夹ID
var sheetName = "Sheet1"; // 合并表格的名称
var folder = DriveApp.getFolderById(folderId);
var files = folder.getFilesByType(MimeType.GOOGLE_DOCS);
var combinedData = [];
while (files.hasNext()) {
var file = files.next();
var document = DocumentApp.openById(file.getId());
var tables = document.getBody().getTables();
var fileName = file.getName(); // 获取文件名
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
var tableData = tableTo2DArray(table, fileName); // 将文件名传递给tableTo2DArray函数
combinedData = combinedData.concat(tableData);
}
document.saveAndClose();
}
combinedData = combinedData.filter(row => row.length === 4 && row.some(cell => cell !== '')); // 排除不包含四列或仅包含空单元格的行
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var combinedSheet = spreadsheet.getSheetByName(sheetName);
if (!combinedSheet) {
combinedSheet = spreadsheet.insertSheet(sheetName);
} else {
combinedSheet.clear();
}
var headerRow = ["文件名", "日期", "类型", "注释"]; // 添加“文件名”到标题行
combinedData.unshift(headerRow); // 将标题行添加到combinedData数组的开头
var range = combinedSheet.getRange(1, 1, combinedData.length, 4); // 调整范围以包括额外的列
range.setValues(combinedData);
}
function tableTo2DArray(table, fileName) { // 将文件名传递给函数
var tableData = [];
for (var i = 1; i < table.getNumRows(); i++) { // 从索引1开始,以排除标题行
var rowData = [fileName]; // 将文件名添加为每行的第一列
var row = table.getRow(i);
var isEmptyRow = true;
for (var j = 0; j < table.getRow(i).getNumCells(); j++) {
var cell = row.getCell(j);
var cellText = cell.getText();
rowData.push(cellText);
if (cellText !== '') {
isEmptyRow = false;
}
}
if (!isEmptyRow) {
tableData.push(rowData);
}
}
return tableData;
}
请注意,这个代码是用于从Google Drive文件夹中的文档中提取表格内容并合并到电子表格中的脚本。如果您有任何其他问题或需要进一步的帮助,请随时提问。
英文:
I have a google app script that (is supposed to) scan all the documents in a google drive folder and pull the contents of a table in each document into a combined spreadsheet table. My script does the basics of this but it skips cells with drop downs. Is it possible to modify the script so that it captures the dropdown selection? See below for links to example.
Spreadsheet with script and combined table. Folder it scans with example documents.
function combineTablesFromDocuments() {
var folderId = "1KW8OPJr9D9qkJI2C5Zea5WbX6iPAwYOz"; // Folder ID containing the documents
var sheetName = "Sheet1"; // Name of the combined sheet
var folder = DriveApp.getFolderById(folderId);
var files = folder.getFilesByType(MimeType.GOOGLE_DOCS);
var combinedData = [];
while (files.hasNext()) {
var file = files.next();
var document = DocumentApp.openById(file.getId());
var tables = document.getBody().getTables();
var fileName = file.getName(); // Get the file name
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
var tableData = tableTo2DArray(table, fileName); // Pass the file name to the tableTo2DArray function
combinedData = combinedData.concat(tableData);
}
document.saveAndClose();
}
combinedData = combinedData.filter(row => row.length === 4 && row.some(cell => cell !== '')); // Exclude rows that don't have exactly four columns or contain only empty cells
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var combinedSheet = spreadsheet.getSheetByName(sheetName);
if (!combinedSheet) {
combinedSheet = spreadsheet.insertSheet(sheetName);
} else {
combinedSheet.clear();
}
var headerRow = ["File Name", "Date", "Type", "Note"]; // Add "File Name" to the header row
combinedData.unshift(headerRow); // Add the header row to the beginning of the combinedData array
var range = combinedSheet.getRange(1, 1, combinedData.length, 4); // Adjust the range to include the additional column
range.setValues(combinedData);
}
function tableTo2DArray(table, fileName) { // Pass the file name to the function
var tableData = [];
for (var i = 1; i < table.getNumRows(); i++) { // Start from index 1 to exclude header row
var rowData = [fileName]; // Add the file name as the first column of each row
var row = table.getRow(i);
var isEmptyRow = true;
for (var j = 0; j < table.getRow(i).getNumCells(); j++) {
var cell = row.getCell(j);
var cellText = cell.getText();
rowData.push(cellText);
if (cellText !== '') {
isEmptyRow = false;
}
}
if (!isEmptyRow) {
tableData.push(rowData);
}
}
return tableData;
}
答案1
得分: 0
我运行了一些测试,只是将下拉列表添加到Google Docs(不在表格内),然后检索下拉列表中的信息。即使getText()
返回空白,元素中也没有显示,我使用的所有其他方法都得到了相同的结果。我无法找到专门用于检索下拉列表中信息的方法。经过一些搜索,我发现这是Google的问题跟踪器中的一个功能请求。
我也找到了一种解决方法,即将Google Doc转换为DOCX,我找到了一些将文件转换为HTML并使用XmlService.parse()获取数据的选项。您可以在此帖子中看到一些示例。
更新:
首先,您需要添加Google Drive高级服务:
之后,您需要向Apps Script添加显式范围,方法是启用“appsscript.json”清单文件,从项目设置
中执行此操作。
返回编辑器,选择清单,并手动添加范围:
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/spreadsheets"
]
最后,粘贴以下代码并进行新的修改:
function combineTablesFromDocuments() {
// 包含文档的文件夹ID
var folderId = "1KW8OPJr9D9qkJI2C5Zea5WbX6iPAwYOz";
var sheetName = "Sheet1"; // 合并表的名称
var folder = DriveApp.getFolderById(folderId);
var files = folder.getFilesByType(MimeType.GOOGLE_DOCS);
var combinedData = [];
while (files.hasNext()) {
var file = files.next();
// 添加一个名为id的新变量。
// 这个变量将获取需要转换的文件的ID
let id = file.getId()
var url = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=docx&id="
+ id;
// 创建URL抓取的Oauth令牌
var param = {
method: "get",
headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
muteHttpExceptions: true,
};
// 将文件转换为blob
let blob = UrlFetchApp.fetch(url, param).getBlob();
// 将blob返回到临时Google Doc
let tempFileId = Drive.Files
.insert({ title: "temp", mimeType: MimeType.GOOGLE_DOCS }, blob,).id;
// 用临时文件ID替换file.getId()
var document = DocumentApp.openById(tempFileId);
var tables = document.getBody().getTables();
var fileName = file.getName(); // 获取文件名
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
// 将文件名传递给tableTo2DArray函数
var tableData = tableTo2DArray(table, fileName);
combinedData = combinedData.concat(tableData);
}
document.saveAndClose();
// 删除临时文件
Drive.Files.remove(tempFileId)
}
// 排除不包含确切四列或仅包含空单元格的行
combinedData = combinedData.filter(row => row.length === 4 && row.some(cell => cell !== ''));
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var combinedSheet = spreadsheet.getSheetByName(sheetName);
if (!combinedSheet) {
combinedSheet = spreadsheet.insertSheet(sheetName);
} else {
combinedSheet.clear();
}
// 添加“文件名”到标题行
var headerRow = ["File Name", "Date", "Type", "Note"];
// 将标题行添加到combinedData数组的开头
combinedData.unshift(headerRow);
// 调整范围以包括附加列
var range = combinedSheet.getRange(1, 1, combinedData.length, 4);
range.setValues(combinedData);
}
function tableTo2DArray(table, fileName) {
// 将文件名传递给函数
var tableData = [];
// 从索引1开始,以排除标题行
for (var i = 1; i < table.getNumRows(); i++) {
// 将文件名作为每行的第一列添加
var rowData = [fileName];
var row = table.getRow(i);
var isEmptyRow = true;
for (var j = 0; j < table.getRow(i).getNumCells(); j++) {
var cell = row.getCell(j);
var cellText = cell.getText();
rowData.push(cellText);
if (cellText !== '') {
isEmptyRow = false;
}
}
if (!isEmptyRow) {
tableData.push(rowData);
}
}
return tableData;
}
结果如下:
英文:
I ran some tests, by adding just the dropdown list to a Google Docs (outside a table), and retrieving the information on the dropdown list. Even the getText()
return blank, is not showing up in elements either, and all the other methods I use I get the same result. I was not able to find a method specifically for retrieving information in a dropdown list, either. After some search, I found that this is a feature request inside the issue tracker of Google.
I found a workaround too, which is to convert the Google Doc to DOCX, I found some options to convert the file to HTML and user the XmlService.parse() to get the data. You can see some examples in this post.
Update:
First, you will need to add the Google Drive Advance services:
After that, you need to add explicit scopes to the Apps Script, you do this by enabling the “appsscript.json” manifest file from the Project settings
.
Return to the editor, select the manifest, and add the scopes manually:
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/spreadsheets"
]
Lastly, paste the following code with the new modifications:
function combineTablesFromDocuments() {
// Folder ID containing the documents
var folderId = "1KW8OPJr9D9qkJI2C5Zea5WbX6iPAwYOz";
var sheetName = "Sheet1"; // Name of the combined sheet
var folder = DriveApp.getFolderById(folderId);
var files = folder.getFilesByType(MimeType.GOOGLE_DOCS);
var combinedData = [];
while (files.hasNext()) {
var file = files.next();
// Add a new variable called id.
//This one will get the ID of the file which needs to be converted
let id = file.getId()
var url = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=docx&id="
+ id;
// creates the Oauth token for the URL fetch
var param = {
method: "get",
headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
muteHttpExceptions: true,
};
//converts the file to a bloc
let blob = UrlFetchApp.fetch(url, param).getBlob();
// returns the blob to a temp Google Doc
let tempFileId = Drive.Files
.insert({ title: "temp", mimeType: MimeType.GOOGLE_DOCS }, blob,).id;
// I replace the file.getId() with the temp file ID
var document = DocumentApp.openById(tempFileId);
var tables = document.getBody().getTables();
var fileName = file.getName(); // Get the file name
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
// Pass the file name to the tableTo2DArray function
var tableData = tableTo2DArray(table, fileName);
combinedData = combinedData.concat(tableData);
}
document.saveAndClose();
//deletes the temp file
Drive.Files.remove(tempFileId)
}
// Exclude rows that don't have exactly four columns
//or contain only empty cells
combinedData = combinedData.filter(row => row.length === 4 && row.some(cell => cell !== ''));
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var combinedSheet = spreadsheet.getSheetByName(sheetName);
if (!combinedSheet) {
combinedSheet = spreadsheet.insertSheet(sheetName);
} else {
combinedSheet.clear();
}
// Add "File Name" to the header row
var headerRow = ["File Name", "Date", "Type", "Note"];
// Add the header row to the beginning of the combinedData array
combinedData.unshift(headerRow);
// Adjust the range to include the additional column
var range = combinedSheet.getRange(1, 1, combinedData.length, 4);
range.setValues(combinedData);
}
function tableTo2DArray(table, fileName) {
// Pass the file name to the function
var tableData = [];
// Start from index 1 to exclude header row
for (var i = 1; i < table.getNumRows(); i++) {
// Add the file name as the first column of each row
var rowData = [fileName];
var row = table.getRow(i);
var isEmptyRow = true;
for (var j = 0; j < table.getRow(i).getNumCells(); j++) {
var cell = row.getCell(j);
var cellText = cell.getText();
rowData.push(cellText);
if (cellText !== '') {
isEmptyRow = false;
}
}
if (!isEmptyRow) {
tableData.push(rowData);
}
}
return tableData;
}
And the result is:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论