1

我有一个将模板文件的内容复制到文档末尾的 Apps 脚本。它有一个小烦恼:编号列表从一个副本继续到下一个副本。

我有许多不同的模板,用户可以将它们附加到文档的末尾。每个模板都存储在自己的 Document 中。

    function addSub(template_id){
      var mainBody = DocumentApp.getActiveDocument().getBody();
      var tempBody = DocumentApp.openById(template_id).getBody();
      for(var i = 0;i<tempBody .getNumChildren();i++){
        var element = tempBody .getChild(i);
        if(element.getType() == DocumentApp.ElementType.TABLE)
          mainBody.appendTable(element.copy());
        else if(element.getType() == DocumentApp.ElementType.PARAGRAPH)
          mainBody.appendParagraph(element.copy());
        else if(element.getType() == DocumentApp.ElementType.LIST_ITEM)
          mainBody.appendListItem(element.copy());
        else if(element.getType() == DocumentApp.ElementType.PAGE_BREAK)
          mainBody.appendPageBreak(element.copy());
      }
    }

它可能看起来像这样:(我希望为模板的每个新副本重置列表)

带有此模板名称的表

一些原始文本

  1. 列表项1
  2. 列表项2

带有此模板名称的表

一些原始文本

  1. 列表项1
  2. 列表项2
4

3 回答 3

2

您现在是否 ListItems 有一个 ID,它是一个 STRING,您可以通过 myListItem.getListId() 访问它。

您的所有 ListItem 似乎都具有相同的 ID。如果是这种情况,编号必须如您所述。

为什么它们具有相同的 ListID?我不知道。似乎body.appendListem 方法总是选择相同的listId。

我还没有测试它,但是如果它们不同,您可以尝试将新附加的 ListItem 的 listID 设置为原始文档的 listID。

是的,我知道,.copy() 方法应该包含此信息,但 body.appendListItem 方法可能不在乎。

因此,您可以尝试先保存 listItem 的分离副本。然后将其附加到新主体。然后将新添加的 listItem 的 id 设置为分离副本的 id。这很愚蠢,我知道,但它可能会有所帮助。还没试过。

而且我对listItems 的经验很少,到目前为止我看到的是,如果您附加或插入listItems,文档正文中似乎只有一个ListId。

这可能是问题的原因。

希望这可以帮助。

于 2016-05-16T20:01:58.873 回答
1

在 Richard Gantz 解决它之后,它被以下代码纠正:

var listItemDictionary = {};//top

...

else if(element.getType() == DocumentApp.ElementType.LIST_ITEM){
  var listCopy = element.copy().asListItem()
  var lcID = listCopy.getListId();
  if (listItemDictionary[lcID] == null){
    var tempLI = mainBody.appendListItem("temp")
    listItemDictionary[lcID] = tempLI;
  }
  Logger.log(lcID)
  mainBody.insertListItem(childIndex+j, listCopy.setListId(listItemDictionary[lcID]));
}

...

if(listItemDictionary){//bottom
  mainBody.appendParagraph("");
  for(var key in listItemDictionary){
    listItemDictionary[key].clear().removeFromParent()
  }
}
于 2016-05-17T14:23:55.470 回答
0

根据 Niklas Ternvall/Richard Gantz 的回答,对于每个模板不超过一个列表的情况,我找到了一个更简单的解决方案。

function addSub(template_id) {
  var mainBody = DocumentApp.getActiveDocument().getBody();
  var tempBody = DocumentApp.openById(template_id).getBody();
  var listID = null;                        
  for(var i = 0;i<tempBody.getNumChildren();i++){
    var element = tempBody.getChild(i).copy();  
    var type = element.getType();                
    if(type == DocumentApp.ElementType.TABLE)
      mainBody.appendTable(element);
    else if(type == DocumentApp.ElementType.PARAGRAPH)
      mainBody.appendParagraph(element);
    else if(type == DocumentApp.ElementType.LIST_ITEM){
      if(listID==null)                                  // First list item
        listID = mainBody.appendListItem('temp');       // Define new listID
      mainBody.appendListItem(element).setListId(listID); // Apply to copy 
    }
    else if(type == DocumentApp.ElementType.PAGE_BREAK)
      mainBody.appendPageBreak(element);
  }
  mainBody.removeChild(listID);               // Delete temporary list item
}

每次调用该函数时,listID=null都会指示模板中是否存在任何列表项。当您到达第一个列表项时,附加文本“temp”会强制生成一个新列表,从而生成一个新的 listID,您可以将其应用于模板中的列表项。完成模板浏览后,mainBody.removeChild(listID)从列表顶部删除“临时”。

当在一个文档中使用一个模板 100 次时,这个解决方案对我有用,本质上是作为邮件合并。我对 Apps 脚本还很陌生,因此如果有任何反馈对单列表模板不起作用,我将不胜感激。

于 2016-07-24T20:25:43.137 回答