"TypeError: Cannot read property 'getBlob' of undefined" when trying to get two different images and insert them into a document

"TypeError: Cannot read property 'getBlob' of undefined" when trying to get two different images and insert them into a document

我有一个 Google Apps 脚本,可以自动从 Google Sheet 中提取数据并将其插入到预先指定的模板中。使用 unique tagNumbers/identifiers.

找到数据

正在提取的数据包括 3 个签名。在遇到上述错误之前,我只能提取这些签名之一:TypeError: Cannot read property 'getBlob' of undefined.

此代码用于两个不同的函数,使用所有相同的变量和名称。我曾尝试更改变量名称,但这导致了相同的 TypeError

可以找到电子表格 here

剧本是here

正在填写的文档模板为here

这是代码。

function electInstallSignature(row, body){
  var signature = row[17];
  var sign = signature.substring(signature.indexOf("/") + 1);
  var sigFolder = DriveApp.getFolderById("16C0DR-R5rJ4f5_2T1f-ZZIxoXQPKvh5C");
  var files = sigFolder.getFilesByName(sign);
  var n = 0;
  var file;
  while(files.hasNext()){
    file = files.next();
    n++;
  } if(n>1){
    SpreadsheetApp.getUi().alert('there is more than one file with this name' + sign);
  }
  var sigElectInstaller = "%SIGNELECTINSTALL%";
  var targetRange = body.findText(sigElectInstaller); // Finding the range we need to focus on
  var paragraph = targetRange.getElement().getParent().asParagraph(); // Getting the Paragraph of the target
  paragraph.insertInlineImage(1, file.getBlob());// As there are only one element in this case you want to  insert at index 1 so it will appear after the text // Notice the .getBlob()
  paragraph.replaceText(sigElectInstaller, ""); // Remove the placeholder
}

function commEngineerSignature(row, body){
  var signature = row[35];
  var sign = signature.substring(signature.indexOf("/") + 1);
  var sigFolder = DriveApp.getFolderById("16C0DR-R5rJ4f5_2T1f-ZZIxoXQPKvh5C");
  var files = sigFolder.getFilesByName(sign);
  var n = 0;
  var file;
  while(files.hasNext()){
    file = files.next();
    n++;
  } if(n>1){
    SpreadsheetApp.getUi().alert('there is more than one file with this name' + sign);
  }
  var sigCommEngineer = "%SFCE%";
  var targetRange = body.findText(sigCommEngineer); // Finding the range we need to focus on
  var paragraph = targetRange.getElement().getParent().asParagraph(); // Getting the Paragraph of the target
  paragraph.insertInlineImage(1, file.getBlob());// As there are only one element in this case you want to  insert at index 1 so it will appear after the text // Notice the .getBlob()
  paragraph.replaceText(sigCommEngineer, ""); // Remove the placeholder
}

如您所见,代码在两个函数中完全相同,但仅适用于 electInstallSignature(row, body) 函数。

您可以在下面找到声明 rowbody 参数的位置。

function chooseRowMethodI(templateId, rowNumber){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var dataRange = sheet.getDataRange();
  var values = dataRange.getValues();
  var data = sheet.getRange(2, 2, 10, 41).getValues();//starting with row 2 and column 1 as our upper-left most column, get values from cells from 1 row down, and 15 columns along - hence (2,1,1,15)
  var docTitle = sheet.getRange(2, 2, 10, 1).getValues();//this is grabbing the data in field B2
  var docTitleTagNumber = sheet.getRange(2, 5, 11, 1).getValues();
  var today = new Date();
  var dd = today.getDate();
  var mm = today.getMonth() + 1;
  var yyyy = today.getFullYear();
  today = dd + '/' + mm + '/' + yyyy;

  for(var i = 0; i < values.length; i++){
    for(var j = 0; j < values[i].length; j++){
      if(values[i][j] == response){
        Logger.log(i);
        var row = data[rowNumber];
        var docId = DriveApp.getFileById(templateId).makeCopy().getId();  
        var doc = DocumentApp.openById(docId);
        var body = doc.getActiveSection();
        //**************************  All Instruments data in here**********************
        instrumentDetails(body, row);
        electInstallSignature(row, body);
        commEngineerSignature(row, body);

        doc.saveAndClose();
        var file = DriveApp.getFileById(doc.getId());
        var newFolder = DriveApp.getFolderById("1Jylk3uO_WU0ClLQdm9y-mwRfHxlh2Ovn");
        newFolder.addFile(file); 
        var newDocTitle = docTitle[i - 1][0];
        var newDocTagNumber = docTitleTagNumber[i - 1][0];
        doc.setName(newDocTitle + " " + newDocTagNumber + " " + today);
      }
    }
  } 
}

应该是 required,我已经包含了所有内容都来自 运行 的函数(请注意任何 ui 和用户输入代码都被标记出来以避免必须每次代码为 运行).

时导航回电子表格
var response = "FT101";

function chooseRow(){
//  var ui = SpreadsheetApp.getUi(); // Same variations.
//  var result = ui.prompt('Please enter the Tag number of the row you wish to print.', ui.ButtonSet.OK_CANCEL);
//  
//  // Process the user's response.
//  var button = result.getSelectedButton();
//  response = result.getResponseText();
//  if (button == ui.Button.OK) {
//    // User clicked "OK".
//    ui.alert('Your tag number is' + response + '.');
//  } else if (button == ui.Button.CANCEL) {
//    // User clicked X in the title bar.
//    ui.alert('You closed the dialog.');
//    return 'the end';
//  }

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var dataRange = sheet.getDataRange();
  var values = dataRange.getValues();
  var category = sheet.getRange(2, 3, 11, 1).getValues();//Needs to be verified to ensure correct cell is chosen by script
  var tags = sheet.getRange(2, 5, 11, 1).getValues();//Needs to be verified to ensure correct cell is chosen by script

  for(var i = 0; i < tags.length; i++){
    if(tags[i][0] == response && category[i][0] == "Instrument"){
      var templateId = "1N3o951ECS5CAVGE6UgqBiCPC7H7LiJbL7Cd59G1xTnA";
      chooseRowMethodI(templateId, i);
      return "";
    } else if(tags[i][0] == response && category[i][0] == "Motor" || tags[i][0] == response && category[i][0] == "Valve"){
      var templateId = "1cSPD23qFd-34-IIr5eJ5a5OgHp9YR6xav9T28Y4Msec";
      chooseRowMethodMV(templateId, i);
      return "";
    }
  }
}

此错误 TypeError: Cannot read property 'getBlob' of undefined 表示您尝试从中 getBlobobject 没有任何 blob 数据。

第一个函数和第二个函数的唯一区别是第一行:row[17] 而不是 row[35] 这意味着以下内容:

  var signature = row[17];
  var sign = signature.substring(signature.indexOf("/") + 1);
  var sigFolder = DriveApp.getFolderById("16C0DR-R5rJ4f5_2T1f-ZZIxoXQPKvh5C");
  var files = sigFolder.getFilesByName(sign);
  var n = 0;
  var file;
  while(files.hasNext()){
    file = files.next();
    n++;
  } if(n>1){
    SpreadsheetApp.getUi().alert('there is more than one file with this name' + sign);
  }

因此,您可能永远不会访问 while 循环:

while(files.hasNext())

因为 var files = sigFolder.getFilesByName(sign); 从来没有下一个,因此,由于 file 没有初始化,所以它是 undefined.


总而言之,您遇到的错误是:

fileundefined

这意味着您从未在此变量上分配任何内容,这只会在您从未访问过 while 时发生,而这只会在 files 从未有过 next 时发生。

发生这种情况是因为那里根本没有任何文件,这意味着 sigFolder 上没有任何名为 sign 的文件。或者 row[17] 不包含有关您要访问的文件名的任何实质性信息。

所以,检查这个。

此外,请考虑以下有关迭代器的文档,例如您在 files 上处理的迭代器:

当您执行 files.next() 时,您正在访问迭代器的第一个元素:

File iterator

关于 JavaScript 迭代器的一般文档:

Iterators and generators on Javascript