使用应用程序脚本在 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 当前内容。