如何使用 Google Apps 脚本获取列表项的值
How to get value of List Items using Google Apps Script
我有 google 个包含列表项的文档。现在我想获取这些列表项的值。例如,文档包含:
- 新文本
- 旧文本
如何获取列表项 (1,2)?
我使用了以下代码,但它只提供了一个列表项对象数组,而不是这些列表项的值。
function docFunction() {
var doc = DocumentApp.getActiveDocument();
var docBody = doc.getBody();
var docText = docBody.getListItems();
Logger.log(docText);
}
无法检索您需要的值。
此外,ListItem
指的是列表本身中的项目,而不是 Glyph
。
最接近获得所需信息的方法是使用 getGlyphType
,它将 return 您正在使用的字形类型,在本例中为 NUMBER
.
参考
我相信你的目标如下。
您想通过搜索文本从列表项中检索字形。
例如有如下列表时,
1. Text New
2. Text Old
通过搜索 Text New
和 Text Old
,您想检索 1.
和 2.
的字形。
问题和解决方法:
遗憾的是,在目前阶段,似乎无法直接检索字形。这已经在评论和现有答案中提到了。
幸运的是,可以通过 Google 文档服务检索字形类型。并且,可以检索字形格式 Google 文档 API。我认为当使用这些时,可能会提出一个解决方法。所以,这只是我的尝试。我不确定这种方法是否适用于所有情况。所以请注意这一点。
示例脚本:
此脚本使用文档 API。所以 please enable Docs API at Advanced Google services.
function myFunction() {
// Please set the searching texts in the list.
// const searchText = ["One One One", "Two Two Two", "ii ii ii ii ii", "C", "Factory Floor"];
// In this case, all list itmes are retrieved.
const searchText = DocumentApp.getActiveDocument().getBody().getListItems().map(e => e.getText().trim());
// This is an object for the numbers with the GlyphType. When you want to use more numbers and GlyphTypes, please add them.
const numObj = {
"NUMBER": ["1", "2", "3", "4", "5", "6"],
"LATIN_LOWER": ["a", "b", "c", "d", "e", "f"],
"LATIN_UPPER": ["A", "B", "C", "D", "E", "F"],
"ROMAN_LOWER": ["i", "ii", "iii", "iv", "v", "vi"],
"ROMAN_UPPER": ["I", "II", "III", "IV", "V", "VI"],
"GLYPH_TYPE_UNSPECIFIED": ["", "", "", "", "", ""],
"noGlyphType": ["", "", "", "", "", ""],
};
// 1. Retrieve list object using Docs API.
const doc = DocumentApp.getActiveDocument();
const listObj = Docs.Documents.get(doc.getId(), { fields: "lists" }).lists;
// 2. Retrieve list items using Document service and create an object for searching the texts.
const listItems = doc.getBody().getListItems();
const obj = listItems.reduce((o, e) => {
const listId = e.getListId();
const glyphType = e.getGlyphType() || "GLYPH_TYPE_UNSPECIFIED";
const nestingLevel = e.getNestingLevel().toString();
const text = e.getText();
if (o[listId]) {
if (o[listId][nestingLevel]) {
if (o[listId][nestingLevel][glyphType]) {
o[listId][nestingLevel][glyphType].text.push(text);
} else {
o[listId][nestingLevel] = { [glyphType]: { text: [text], glyphFormat: listObj[listId].listProperties.nestingLevels[nestingLevel].glyphFormat, nestingLevel } };
}
} else {
o[listId][nestingLevel] = { [glyphType]: { text: [text], glyphFormat: listObj[listId].listProperties.nestingLevels[nestingLevel].glyphFormat, nestingLevel } };
}
} else {
o[listId] = { [nestingLevel]: { [glyphType]: { text: [text], glyphFormat: listObj[listId].listProperties.nestingLevels[nestingLevel].glyphFormat, nestingLevel } } };
}
return o;
}, {});
// 3. Search text and output an object for retrieving glyphs.
const getRes = (obj, search, res = [], parents = []) => {
Object.entries(obj).forEach(([k, v]) => {
if (Array.isArray(v)) {
v = v.map(vv => vv.trim());
const temp = search.filter(s => v.includes(s));
if (temp.length > 0) {
const parent = parents[parents.length - 1];
res.push(temp.map(e => ({ search: e, k: parent.k == "null" ? "noGlyphType" : parent.k, idx: v.indexOf(e), glyphFormat: parent.v.glyphFormat, nestingLevel: parent.v.nestingLevel })));
}
} else if (typeof v == "object") {
parents.push({ k, v });
getRes(v, search, res, parents);
}
});
return search.map(s => res.flat().filter(t => t.search == s)[0]);
}
const res = getRes(obj, searchText).map(e => {
const count = [...e.glyphFormat].reduce((c, e) => e == "%" ? c + 1 : c, 0);
return e ? e.glyphFormat.replace(/%([0-9]+)/g, (_, p, o) => count > 1 ? numObj[e.k][o == 0 ? Number(p) : e.idx] : numObj[e.k][e.idx]) : "Text was not found."
});
console.log(res);
}
测试:
当上述脚本为运行时,检索所有列表项并返回字形。并且,例如,当使用下图中显示的示例文档并将 const searchText = ["One One One", "Two Two Two", "ii ii ii ii ii", "C", "Factory Floor"];
用作搜索文本时,
得到如下结果。
[ '1.', '2.', 'ii.', '(A)', '1.3' ]
不幸的是,我找不到识别I1.
和I2.
的I
的方法。这样,Factory Floor
的字形就变成了 1.3
.
注:
现阶段,在我提议的脚本中,我找不到识别I1.
和I2.
的I
的方法。当我找到方法时,我想更新我的示例脚本。
这只是我的尝试。我不确定这种方法是否适用于所有情况。所以请注意这一点。
当您要检索所有列表项的字形时,请按如下方式修改上述脚本。
来自
const searchText = ["One One One", "Two Two Two", "ii ii ii ii ii", "C", "Factory Floor"];
到
const searchText = DocumentApp.getActiveDocument().getBody().getListItems().map(e => e.getText().trim());
很遗憾,目前阶段,好像check box type的glyph type无法检索到
参考文献:
我有 google 个包含列表项的文档。现在我想获取这些列表项的值。例如,文档包含:
- 新文本
- 旧文本
如何获取列表项 (1,2)?
我使用了以下代码,但它只提供了一个列表项对象数组,而不是这些列表项的值。
function docFunction() {
var doc = DocumentApp.getActiveDocument();
var docBody = doc.getBody();
var docText = docBody.getListItems();
Logger.log(docText);
}
无法检索您需要的值。
此外,ListItem
指的是列表本身中的项目,而不是 Glyph
。
最接近获得所需信息的方法是使用 getGlyphType
,它将 return 您正在使用的字形类型,在本例中为 NUMBER
.
参考
我相信你的目标如下。
您想通过搜索文本从列表项中检索字形。
例如有如下列表时,
1. Text New 2. Text Old
通过搜索
Text New
和Text Old
,您想检索1.
和2.
的字形。
问题和解决方法:
遗憾的是,在目前阶段,似乎无法直接检索字形。这已经在评论和现有答案中提到了。
幸运的是,可以通过 Google 文档服务检索字形类型。并且,可以检索字形格式 Google 文档 API。我认为当使用这些时,可能会提出一个解决方法。所以,这只是我的尝试。我不确定这种方法是否适用于所有情况。所以请注意这一点。
示例脚本:
此脚本使用文档 API。所以 please enable Docs API at Advanced Google services.
function myFunction() {
// Please set the searching texts in the list.
// const searchText = ["One One One", "Two Two Two", "ii ii ii ii ii", "C", "Factory Floor"];
// In this case, all list itmes are retrieved.
const searchText = DocumentApp.getActiveDocument().getBody().getListItems().map(e => e.getText().trim());
// This is an object for the numbers with the GlyphType. When you want to use more numbers and GlyphTypes, please add them.
const numObj = {
"NUMBER": ["1", "2", "3", "4", "5", "6"],
"LATIN_LOWER": ["a", "b", "c", "d", "e", "f"],
"LATIN_UPPER": ["A", "B", "C", "D", "E", "F"],
"ROMAN_LOWER": ["i", "ii", "iii", "iv", "v", "vi"],
"ROMAN_UPPER": ["I", "II", "III", "IV", "V", "VI"],
"GLYPH_TYPE_UNSPECIFIED": ["", "", "", "", "", ""],
"noGlyphType": ["", "", "", "", "", ""],
};
// 1. Retrieve list object using Docs API.
const doc = DocumentApp.getActiveDocument();
const listObj = Docs.Documents.get(doc.getId(), { fields: "lists" }).lists;
// 2. Retrieve list items using Document service and create an object for searching the texts.
const listItems = doc.getBody().getListItems();
const obj = listItems.reduce((o, e) => {
const listId = e.getListId();
const glyphType = e.getGlyphType() || "GLYPH_TYPE_UNSPECIFIED";
const nestingLevel = e.getNestingLevel().toString();
const text = e.getText();
if (o[listId]) {
if (o[listId][nestingLevel]) {
if (o[listId][nestingLevel][glyphType]) {
o[listId][nestingLevel][glyphType].text.push(text);
} else {
o[listId][nestingLevel] = { [glyphType]: { text: [text], glyphFormat: listObj[listId].listProperties.nestingLevels[nestingLevel].glyphFormat, nestingLevel } };
}
} else {
o[listId][nestingLevel] = { [glyphType]: { text: [text], glyphFormat: listObj[listId].listProperties.nestingLevels[nestingLevel].glyphFormat, nestingLevel } };
}
} else {
o[listId] = { [nestingLevel]: { [glyphType]: { text: [text], glyphFormat: listObj[listId].listProperties.nestingLevels[nestingLevel].glyphFormat, nestingLevel } } };
}
return o;
}, {});
// 3. Search text and output an object for retrieving glyphs.
const getRes = (obj, search, res = [], parents = []) => {
Object.entries(obj).forEach(([k, v]) => {
if (Array.isArray(v)) {
v = v.map(vv => vv.trim());
const temp = search.filter(s => v.includes(s));
if (temp.length > 0) {
const parent = parents[parents.length - 1];
res.push(temp.map(e => ({ search: e, k: parent.k == "null" ? "noGlyphType" : parent.k, idx: v.indexOf(e), glyphFormat: parent.v.glyphFormat, nestingLevel: parent.v.nestingLevel })));
}
} else if (typeof v == "object") {
parents.push({ k, v });
getRes(v, search, res, parents);
}
});
return search.map(s => res.flat().filter(t => t.search == s)[0]);
}
const res = getRes(obj, searchText).map(e => {
const count = [...e.glyphFormat].reduce((c, e) => e == "%" ? c + 1 : c, 0);
return e ? e.glyphFormat.replace(/%([0-9]+)/g, (_, p, o) => count > 1 ? numObj[e.k][o == 0 ? Number(p) : e.idx] : numObj[e.k][e.idx]) : "Text was not found."
});
console.log(res);
}
测试:
当上述脚本为运行时,检索所有列表项并返回字形。并且,例如,当使用下图中显示的示例文档并将 const searchText = ["One One One", "Two Two Two", "ii ii ii ii ii", "C", "Factory Floor"];
用作搜索文本时,
得到如下结果。
[ '1.', '2.', 'ii.', '(A)', '1.3' ]
不幸的是,我找不到识别I1.
和I2.
的I
的方法。这样,Factory Floor
的字形就变成了 1.3
.
注:
现阶段,在我提议的脚本中,我找不到识别
I1.
和I2.
的I
的方法。当我找到方法时,我想更新我的示例脚本。这只是我的尝试。我不确定这种方法是否适用于所有情况。所以请注意这一点。
当您要检索所有列表项的字形时,请按如下方式修改上述脚本。
来自
const searchText = ["One One One", "Two Two Two", "ii ii ii ii ii", "C", "Factory Floor"];
到
const searchText = DocumentApp.getActiveDocument().getBody().getListItems().map(e => e.getText().trim());
很遗憾,目前阶段,好像check box type的glyph type无法检索到