Объединение документов Google Docs

Можно ли объединить 100 документов Google Docs в один? Я пробовал копировать-вставлять, но это кажется слишком длинным и невозможно скопировать комментарии.


person Igor    schedule 23.07.2014    source источник


Ответы (5)


Это можно сделать с помощью скрипта Google Apps. См. этот пример. Наиболее важные части (в примере предполагается, что в папке нет ничего, кроме Google Docs):

function combine() {
  var folder = DriveApp.getRootFolder();
  if (folder == null) { Logger.log("Failed to get root folder"); return; }
  var combinedTitle = "Combined Document Example";
  var combo = DocumentApp.create(combinedTitle);
  var comboBody = combo.getBody();
  var hdr = combo.addHeader();
  hdr.setText(combinedTitle)

  var list = folder.getFiles();
  while (list.hasNext()) {
    var doc = list.next();
    var src = DocumentApp.openById(doc.getId());
    var srcBody = src.getBody();
    var elems = srcBody.getNumChildren();
    for (var i = 0; i < elems; i++ ) {
      elem = srcBody.getChild(i).copy();
      // fire the right method based on elem's type
      switch (elem.getType()) {
        case DocumentApp.ElementType.PARAGRAPH:
          comboBody.appendParagraph(elem);
          break;
        case // something
      }
    }
  }
} 

Обратите внимание, что вы не копируете содержимое исходного документа одним куском; вам нужно пройтись по ним как по отдельным элементам и запустить правильный метод append*, чтобы добавить их в объединенный/целевой файл.

person noltie    schedule 04.06.2016
comment
привет, спасибо - вы знаете, где мне нужно запустить этот код, чтобы объединить документы? - person BKSpurgeon; 11.04.2017

Я расширил ответ @noltie, чтобы поддерживать рекурсивное слияние документов в структуре папок, начиная с произвольной папки (не обязательно корневой папки документов Google), и защищаться от сбоев сценария при слишком большом количестве несохраненных изменений.

function getDocsRec(rootFolder) {
  var docs = [];

  function iter(folder) {
    var childFolders = folder.getFolders();
    while (childFolders.hasNext()) {
      iter(childFolders.next());
    }

    var childFiles = folder.getFiles();
    while (childFiles.hasNext()) {
      var item = childFiles.next();
      var docName = item.getName();
      var docId   = item.getId();
      var doc     = {name: docName, id: docId};
      docs.push(doc);
    }
  }

  iter(rootFolder);
  return docs;
}

function combineDocs() {
  // This function assumes only Google Docs files are in the root folder
  // Get the id from the URL of the folder.
  var folder = DriveApp.getFolderById("<root folder id>");
  if (folder == null) { Logger.log("Failed to get root folder"); return; }

  var combinedTitle = "Combined Document Example";
  var combo = DocumentApp.create(combinedTitle);
  var comboBody = combo.getBody();

  // merely get the files recursively, does not get them in alphabetical order.
  var docArr = getDocsRec(folder);

  // Log all the docs we got back. Click "Edit -> Logs" to see.
  docArr.forEach(function(item) {
    Logger.log(item.name)
  });

  // this sort will fail if you have files with identical names
  // docArr.sort(function(a, b) { return a.name < b.name ? -1 : 1; });

  // Now load the docs into the combo doc.
  // We can't load a doc in one big lump though;
  // we have to do it by looping through its elements and copying them
  for (var j = 0; j < docArr.length; j++) {

    // There is a limit somewhere between 50-100 unsaved changed where the script
    // wont continue until a batch is commited.
    if (j % 50 == 0) {
      combo.saveAndClose();
      combo = DocumentApp.openById(combo.getId());
      comboBody = combo.getBody();
    }

    var entryId = docArr[j].id;
    var entry = DocumentApp.openById(entryId);
    var entryBody = entry.getBody();
    var elems = entryBody.getNumChildren();
    for (var i = 0; i < elems; i++) {
      var elem = entryBody.getChild(i).copy();
      switch (elem.getType()) {
        case DocumentApp.ElementType.HORIZONTAL_RULE:
          comboBody.appendHorizontalRule();
          break;
        case DocumentApp.ElementType.INLINE_IMAGE:
          comboBody.appendImage(elem);
          break;
        case DocumentApp.ElementType.LIST_ITEM:
          comboBody.appendListItem(elem);
          break;
        case DocumentApp.ElementType.PAGE_BREAK:
          comboBody.appendPageBreak(elem);
          break;
        case DocumentApp.ElementType.PARAGRAPH:
          comboBody.appendParagraph(elem);
          break;
        case DocumentApp.ElementType.TABLE:
          comboBody.appendTable(elem);
          break;
        default:
          var style = {};
          style[DocumentApp.Attribute.BOLD] = true;
          comboBody.appendParagraph("Element type '" + elem.getType() + "' could not be merged.").setAttributes(style);
      }
    }
   // page break at the end of each entry.
   comboBody.appendPageBreak();
  }
}

Вы можете создать и запустить скрипт с приведенным выше кодом на странице https://script.google.com/home

person Red Mercury    schedule 25.12.2018

Оба вышеперечисленных терпят неудачу для меня со сценарием, возвращающим красную лепешку:

Служба недоступна: закрыть документы

(документы в папке найдены, как и идентификаторы документов, и объединенный документ создан, но пустой)

Исправлено - в списке был документ, который не принадлежал мне или был создан путем конвертации. Удалил это и понеслось.

person Metric Rat    schedule 06.05.2019

Документы Google пока не поддерживают слияние. Вы можете выбрать все 100 документов, загрузить их и попытаться объединить в автономном режиме.

person Rajven    schedule 23.07.2014

Загрузите все файлы в формате Docx, затем используйте Microsoft Word или Open Office для объединения документов с помощью функции «главный документ». (Word также называет это «контуром».)

person CheddarCheese    schedule 09.10.2015