Параграфы со встроенными изображениями разбивают скрипт приложения, объединяя данные листа в документ - PullRequest
1 голос
/ 14 января 2020

У меня есть Google App Script, который объединяет значения данных из строк на листе с шаблоном до c. В шаблоне у c абзацев есть встроенные изображения. Когда я удаляю изображения, скрипт работает отлично. Когда я добавляю изображения обратно, я получаю следующую ошибку: Service unavailable: Documents (line 34, file "Code")

Любые идеи о том, что мне нужно сделать? К вашему сведению: строка 34 отмечена с комментарием ниже ...

function buildGivingStatements() {
  var tempDocID = "1-SAQYP41wwnah6tF15nvT8fSx1rjCHN57T7lECFTCCw";
  var finDocID = "1TnR63Yq9oiUwxxJ5MTHbm-OX3pqvH6iW7bBLcFC2v1w";
  var sheetID = "19Sl61Rp37bPWc_fsCqpu59DFsDdwZF4zxdjHlplA-fI";

  var tempDoc = DocumentApp.openById(tempDocID);
  var finDoc = DocumentApp.openById(finDocID);
  var sheet = SpreadsheetApp.openById(sheetID).getSheetByName("Annual Report");

  var tDATE = Utilities.formatDate(new Date(), "America/Chicago", "EEEE, MMMM dd, yyyy");
  var tYEAR = Utilities.formatDate(new Date(), "America/Chicago", "yyyy");

  var data = sheet.getRange(6,1,1,2).getDisplayValues();
  //var data = sheet.getRange(6,1,sheet.getLastRow()-1,4).getValues();

  var tempPs = tempDoc.getBody().getParagraphs();

  finDoc.getBody().clear();

  data.forEach(function(r){
    replaceTempVars(r[0], r[1], tDATE, tYEAR, finDoc, tempPs);
  });

}



function replaceTempVars(NAME, AMOUNT, tDATE, tYEAR, finDoc, tempPs) {
  tempPs.forEach(function(p){
    var elType = p.getType();
    Logger.log(elType);

    if(elType == "PARAGRAPH") {
      finDoc.getBody().appendParagraph( //LINE 34
        p
          .copy()
          .replaceText("{{NAME}}", NAME)
          .replaceText("{{AMOUNT}}", AMOUNT)
          .replaceText("{{DATE}}", tDATE)
          .replaceText("{{YEAR}}", tYEAR)
      );
    }else if(elType == "LIST_ITEM") {
      finDoc.getBody().appendListItem(
        p
          .copy()
      ).setGlyphType(DocumentApp.GlyphType.BULLET);
    }
  });

  finDoc.getBody().appendPageBreak();
}

1 Ответ

1 голос
/ 16 января 2020
  • Вы хотите объединить шаблон документа с существующим документом Google, заменив тексты.
  • В вашей текущей проблеме ошибка Service unavailable возникает в сценарии finDoc.getBody().appendParagraph().
    • Когда изображение в верхней части документа удаляется, скрипт работает.
  • Вы хотите добиться этого с помощью скрипта Google Apps.

Если мое понимание верно, как насчет этого ответа? Пожалуйста, подумайте об этом как об одном из нескольких возможных ответов.

Точки изменения:

  • Из вашего общего документа Google, я мог бы знать, что ваш шаблон документа использует позиционированное изображение. Я думаю, что причина ошибки Service unavailable связана с позиционированием изображения. Когда копируется абзац с позиционированным изображением, возникает такая ошибка.
    • Чтобы избежать этой проблемы, я хотел бы предложить изменить ваш скрипт, разделив позиционированное изображение и абзац.
    • Для этого я использовал getNumChildren() вместо getParagraphs(). Потому что я думал, что необходимо использовать метод insert вместо метода append. Поскольку при использовании метода append в верхнем абзаце создается пустой абзац.

Измененный сценарий:

Перед запуском сценария включите API Документов Google в расширенных службах Google.

function buildGivingStatements() {
  var tempDocID = "1-SAQYP41wwnah6tF15nvT8fSx1rjCHN57T7lECFTCCw";
  var finDocID = "1TnR63Yq9oiUwxxJ5MTHbm-OX3pqvH6iW7bBLcFC2v1w";
  var sheetID = "19Sl61Rp37bPWc_fsCqpu59DFsDdwZF4zxdjHlplA-fI";

  var tempDoc = DocumentApp.openById(tempDocID);
  var finDoc = DocumentApp.openById(finDocID);
  var sheet = SpreadsheetApp.openById(sheetID).getSheetByName("Annual Report");
  var tDATE = Utilities.formatDate(new Date(), "America/Chicago", "EEEE, MMMM dd, yyyy");
  var tYEAR = Utilities.formatDate(new Date(), "America/Chicago", "yyyy");
  var data = sheet.getRange(6,1,1,2).getDisplayValues();

  // I modified below script.
  var finBody = finDoc.getBody();
  finBody.clear();
  var tempBody = tempDoc.getBody();
  var tempNumChildren = tempBody.getNumChildren();
  var pos = 0;
  data.forEach(function(r){
    replaceTempVars(r[0], r[1], tDATE, tYEAR, finBody, tempBody, tempNumChildren, pos);
  });

  // If you want to delete the last empty page, please use the following script. In this case, please enable Docs API at Advanced Google services.
  finDoc.saveAndClose();
  var c = Docs.Documents.get(finDocID, {fields: "body.content"}).body.content.pop();
  Docs.Documents.batchUpdate({requests: [{deleteContentRange: {range: {startIndex: c.startIndex - 1, endIndex: c.endIndex - 1}}}]}, finDocID);
}

function replaceTempVars(NAME, AMOUNT, tDATE, tYEAR, finBody, tempBody, tempNumChildren, pos) {
  for (var i = 0; i < tempNumChildren; i++) {
    var element = tempBody.getChild(i).copy();
    var type = element.getType();
    if (type == DocumentApp.ElementType.PARAGRAPH) {
      var copyPara = element.asParagraph();
      var pImgs = copyPara.getPositionedImages();
      if (pImgs.length > 0) {
        var img = pImgs[0];
        var obj = {id: img.getId(), blob: img.getBlob(), leftOffset: img.getLeftOffset(), topOffset: img.getTopOffset(), width: img.getWidth(), height: img.getHeight(), layout: img.getLayout()};
        copyPara.removePositionedImage(obj.id);
        var texts = copyPara.replaceText("{{NAME}}", NAME).replaceText("{{AMOUNT}}", AMOUNT).replaceText("{{DATE}}", tDATE).replaceText("{{YEAR}}", tYEAR);
        var paragraph = finBody.insertParagraph(pos + i, texts);
        paragraph.addPositionedImage(obj.blob).setWidth(obj.width).setHeight(obj.height).setLayout(obj.layout).setLeftOffset(obj.leftOffset).setTopOffset(obj.topOffset);
      } else {
        var texts = element.asParagraph().replaceText("{{NAME}}", NAME).replaceText("{{AMOUNT}}", AMOUNT).replaceText("{{DATE}}", tDATE).replaceText("{{YEAR}}", tYEAR);
        finBody.insertParagraph(pos + i, texts);
      }
    } else if (type == DocumentApp.ElementType.LIST_ITEM) {
      var glyphType = element.asListItem().getGlyphType();
      finBody.insertListItem(pos + i, element).setGlyphType(glyphType);
    } else if (type == DocumentApp.ElementType.INLINE_IMAGE) {
      finBody.insertImage(pos + i, element);
    }
  }
  pos += tempNumChildren;
}

Примечание:

  • В этом измененном сценарии был подготовлен тестовый шаблон вашего документа. Если вы хотите использовать другой шаблон, может возникнуть ошибка. Поэтому, пожалуйста, будьте осторожны.
  • О документе Google из finDocID, используйте документ, который имеет те же поля страницы документа, что и шаблон документа. Если используется Документ Google по умолчанию, результат может быть не таким, как вы ожидаете. Пожалуйста, будьте осторожны.

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...