使用应用程序脚本在 google 文档 table 中查找占位符文本元素的索引
Finding the index of a placeholder text element in a google doc table using app script
如标题所示,我正在尝试在 google 文档 table 中查找占位符文本元素的索引,以便我可以将其替换为存储在不同文档中的文本。
我可以将 pre-formatted 文本添加到文档中 - 而不是 table 中所需的位置 - 使用我在 Whosebug 上找到的其他示例。
但是我不清楚如何在模板文档中的多个 table 之一中找到占位符元素的索引。
我需要占位符文本的索引才能使用 insertParagraph 函数。
要添加更多细节:我可以使用以下代码找到占位符文本并插入图像。
function replaceTextToImage(body, searchText, image, width) {
var next = body.findText(searchText);
if (!next) return;
var r = next.getElement();
r.asText().setText("");
var img = r.getParent().asParagraph().insertInlineImage(0, image);
if (width && typeof width == "number") {
var w = img.getWidth();
var h = img.getHeight();
img.setWidth(width);
img.setHeight(width * h / w);
}
return next;
};
但是,我需要保留要导入的文档的格式。因此,我打开带有格式化文本的文档,然后循环遍历不同的元素类型,如果元素类型匹配,则有条件地插入 text/image。这就是为什么我需要占位符文本的索引。请参阅以下功能:
function replaceTextWithDoc(body, searchText, id) {
let doc = DocumentApp.openById(id)
var numElements = body.getNumChildren();
var index = numElements;
for (var i = 0; i < numElements; i++) {
var child = body.getChild(i);
if (child.asText().getText() == searchText){
index = i;
body.removeChild(child);
break;
}
}
var totalElements = doc.getNumChildren();
for( var j = 0; j < totalElements; ++j ) {
var element = doc.getChild(j).copy();
var type = element.getType();
if( type == DocumentApp.ElementType.PARAGRAPH )
body.insertParagraph(index, element);
else if( type == DocumentApp.ElementType.TABLE )
body.insertTable(index, element);
else if( type == DocumentApp.ElementType.LIST_ITEM )
body.insertParagraph(index, element);
else
throw new Error("According to the doc this type couldn't appear in the body: "+type);
}
}
这是 table 中占位符文本 ( {iText} ) 的示例:https://docs.google.com/document/d/1mZWpQqk4gYAF6UCRALrT8S99-01RYNfwni_kqDzOg7E/edit?usp=sharing
这是我需要将占位符文本替换为 - 保持 all/any 格式的文本和图像示例。 https://docs.google.com/document/d/1wuX0g5W2GL0YJ7admiv3TNEepb_zVwQleKwazCiAMBU/edit?usp=sharing
问题:
如果我没理解错的话,您想将一个文档的内容(由文本和内联图像组成)复制到包含特定占位符文本的特定 table 个单元格。
解决方案:
在这种情况下,我建议如下:
- 遍历目标文档中的所有 tables,使用 Body.getTables().
- 对于每个 table,遍历其所有单元格。
- 对于每个单元格,检查其文本是否包含占位符。
- 如果包含占位符,通过TableCell.clear()清除当前单元格内容。
- 遍历所有源文档元素(例如,参见 this answer)。
- 对于每个元素,检查其类型 (Element.getType())。
- 如果元素是段落,通过 TableCell.appendParagraph 将段落附加到单元格。
- 如果元素是图片,通过TableCell.appendImage附加它。
代码示例:
const PLACEHOLDER = "{iText}";
function myFunction() {
const doc = DocumentApp.openById(TARGET_ID);
const sourceDoc = DocumentApp.openById(SOURCE_ID);
const body = doc.getBody();
const tables = body.getTables();
tables.forEach(table => {
const numRows = table.getNumRows();
for (let i = 0; i < numRows; i++) {
const row = table.getRow(i);
const numCells = row.getNumCells();
for (let j = 0; j < numCells; j++) {
const cell = row.getCell(j);
const cellText = cell.editAsText();
const text = cellText.getText();
if (text.includes(PLACEHOLDER)) {
cell.clear();
appendSourceContent(sourceDoc, cell);
}
}
}
});
}
function appendSourceContent(doc, cell) {
const numChildren = doc.getNumChildren();
for (let j = 0; j < numChildren; j++) {
const element = doc.getChild(j).copy();
const type = element.getType();
if (type == DocumentApp.ElementType.PARAGRAPH) {
cell.appendParagraph(element);
} else if (type == DocumentApp.ElementType.INLINE_IMAGE) {
cell.appendImage(element);
}
}
}
注:
- 如果源内容可以
ElementTypes
不同于段落和内联图像,请添加额外的 else if
块。
- 我假设您想在 table 单元格中保留 none 当前内容。
如标题所示,我正在尝试在 google 文档 table 中查找占位符文本元素的索引,以便我可以将其替换为存储在不同文档中的文本。
我可以将 pre-formatted 文本添加到文档中 - 而不是 table 中所需的位置 - 使用我在 Whosebug 上找到的其他示例。
但是我不清楚如何在模板文档中的多个 table 之一中找到占位符元素的索引。
我需要占位符文本的索引才能使用 insertParagraph 函数。
要添加更多细节:我可以使用以下代码找到占位符文本并插入图像。
function replaceTextToImage(body, searchText, image, width) {
var next = body.findText(searchText);
if (!next) return;
var r = next.getElement();
r.asText().setText("");
var img = r.getParent().asParagraph().insertInlineImage(0, image);
if (width && typeof width == "number") {
var w = img.getWidth();
var h = img.getHeight();
img.setWidth(width);
img.setHeight(width * h / w);
}
return next;
};
但是,我需要保留要导入的文档的格式。因此,我打开带有格式化文本的文档,然后循环遍历不同的元素类型,如果元素类型匹配,则有条件地插入 text/image。这就是为什么我需要占位符文本的索引。请参阅以下功能:
function replaceTextWithDoc(body, searchText, id) {
let doc = DocumentApp.openById(id)
var numElements = body.getNumChildren();
var index = numElements;
for (var i = 0; i < numElements; i++) {
var child = body.getChild(i);
if (child.asText().getText() == searchText){
index = i;
body.removeChild(child);
break;
}
}
var totalElements = doc.getNumChildren();
for( var j = 0; j < totalElements; ++j ) {
var element = doc.getChild(j).copy();
var type = element.getType();
if( type == DocumentApp.ElementType.PARAGRAPH )
body.insertParagraph(index, element);
else if( type == DocumentApp.ElementType.TABLE )
body.insertTable(index, element);
else if( type == DocumentApp.ElementType.LIST_ITEM )
body.insertParagraph(index, element);
else
throw new Error("According to the doc this type couldn't appear in the body: "+type);
}
}
这是 table 中占位符文本 ( {iText} ) 的示例:https://docs.google.com/document/d/1mZWpQqk4gYAF6UCRALrT8S99-01RYNfwni_kqDzOg7E/edit?usp=sharing
这是我需要将占位符文本替换为 - 保持 all/any 格式的文本和图像示例。 https://docs.google.com/document/d/1wuX0g5W2GL0YJ7admiv3TNEepb_zVwQleKwazCiAMBU/edit?usp=sharing
问题:
如果我没理解错的话,您想将一个文档的内容(由文本和内联图像组成)复制到包含特定占位符文本的特定 table 个单元格。
解决方案:
在这种情况下,我建议如下:
- 遍历目标文档中的所有 tables,使用 Body.getTables().
- 对于每个 table,遍历其所有单元格。
- 对于每个单元格,检查其文本是否包含占位符。
- 如果包含占位符,通过TableCell.clear()清除当前单元格内容。
- 遍历所有源文档元素(例如,参见 this answer)。
- 对于每个元素,检查其类型 (Element.getType())。
- 如果元素是段落,通过 TableCell.appendParagraph 将段落附加到单元格。
- 如果元素是图片,通过TableCell.appendImage附加它。
代码示例:
const PLACEHOLDER = "{iText}";
function myFunction() {
const doc = DocumentApp.openById(TARGET_ID);
const sourceDoc = DocumentApp.openById(SOURCE_ID);
const body = doc.getBody();
const tables = body.getTables();
tables.forEach(table => {
const numRows = table.getNumRows();
for (let i = 0; i < numRows; i++) {
const row = table.getRow(i);
const numCells = row.getNumCells();
for (let j = 0; j < numCells; j++) {
const cell = row.getCell(j);
const cellText = cell.editAsText();
const text = cellText.getText();
if (text.includes(PLACEHOLDER)) {
cell.clear();
appendSourceContent(sourceDoc, cell);
}
}
}
});
}
function appendSourceContent(doc, cell) {
const numChildren = doc.getNumChildren();
for (let j = 0; j < numChildren; j++) {
const element = doc.getChild(j).copy();
const type = element.getType();
if (type == DocumentApp.ElementType.PARAGRAPH) {
cell.appendParagraph(element);
} else if (type == DocumentApp.ElementType.INLINE_IMAGE) {
cell.appendImage(element);
}
}
}
注:
- 如果源内容可以
ElementTypes
不同于段落和内联图像,请添加额外的else if
块。 - 我假设您想在 table 单元格中保留 none 当前内容。