Нумерованные списки продолжаются, когда Apps Script добавляет содержимое шаблона в документ

У меня есть Apps Script, который копирует содержимое файла шаблона в конец документа. Это работает с одним незначительным раздражением: нумерованный список продолжается с одной копии на другую.

У меня есть много разных шаблонов, которые пользователи могут добавлять в конец документа. Каждый шаблон хранится в своем собственном документе.

    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

3 ответа

Решение

После того, как Ричард Ганц решил это, он был исправлен следующим кодом:

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()
  }
}

Теперь вы знаете, что ListItems имеют идентификатор, который является STRING, и вы можете получить к нему доступ через myListItem.getListId().

Кажется, что все ваши ListItems имеют одинаковый идентификатор. Если это так, нумерация должна быть такой, как вы описали.

Почему у них одинаковый ListID? Я не знаю. Кажется, что метод body.appendListem всегда выбирает один и тот же listId.

Я еще не тестировал его, но вы можете попробовать установить listID вновь добавленного ListItem в исходный документ, если они отличаются.

Да, я знаю, метод.copy() должен содержать эту информацию, но метод body.appendListItem может не заботиться.

Таким образом, вы можете попытаться сначала сохранить отдельную копию listItem. Затем добавьте его в новое тело. А затем установите идентификатор вновь добавленного listItem на идентификатор отсоединенной копии. Это глупо, я знаю, но это может помочь. Еще не пробовал.

И у меня мало опыта с listItems, но то, что я до сих пор видел, это то, что в теле документа, по-видимому, только один ListId, если вы добавляете или вставляете listItems.

Это может быть причиной проблемы.

Надеюсь это поможет.

Основываясь на ответе Никласа Тернвалла / Ричарда Ганца, я нашел более простое решение для каждого шаблона, имеющего не более одного списка.

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) удаляет 'temp' из верхней части вашего списка.

Это решение работало для меня при использовании одного шаблона 100 раз в одном документе, по сути, в качестве слияния. Я довольно новичок в скрипте приложений, поэтому буду признателен за любые отзывы, если есть причина, по которой это не сработает для шаблона с одним списком.

Другие вопросы по тегам