如何使用 Google Apps 脚本强制图像出现在预先指定的文本行中?

How can I force an image to appear in a pre-specified line of text using Google Apps Script?

我正在编写一个脚本,自动从 google sheet 中提取信息并将其应用于 google 文档中制作的模板。该模板包括多个签名部分。签名作为图像存储在子文件夹中,图像文件名由 appsheet.com 自动生成。

我目前能够提取图像并将其附加到文档的最后,但我无法强制图像出现在文档的正确位置。

我可以强制脚本在正确的位置显示图像名称,但不是图像。我怀疑这与文本换行有关,而且由于我不熟悉 Google Apps 脚本,我找不到其他方法来解决这个问题。

您可以找到包含所有必要数据的价差sheet。here

我写的脚本是here.

文档模板是here

这是我认为问题所在的代码块。

        var signature = row[17];
        var sign = signature.substring(signature.indexOf("/") + 1);
        var sigFolder = DriveApp.getFolderById("1IWix3MTEWnGn9lmb91XmCakz7kV3DoCV");

        var files = sigFolder.getFilesByName(sign);
        var n = 0;
        var file;
        while(files.hasNext()){
          file = files.next();
          n++;
        } if(n>1){
          SpreadsheetApp.getUi().alers('there is more than one file with this name' + sign);
        }
        var sigElectInstaller = "%SIGNELECTINSTALL%";
        //var sigElectInstaller = body.appendImage(file);
        //var sig = body.appendImage(file);
        //body.appendImage(file);
        //body.replaceText(sig, row[17]);
        //body.replaceText(file, row[17]);
        body.replaceText(sigElectInstaller, file);

下一个块是整个函数。

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[i - 1];
        var row = data[rowNumber];
        var docId = DriveApp.getFileById(templateId).makeCopy().getId();  
        var doc = DocumentApp.openById(docId);
        var body = doc.getActiveSection();
        //***** Script begins inserting data into document ******
        body.replaceText("%SITE%",row[0]);
        ...


        //************************  This is the section in question. Here the image is found and the attempt to insert it into the document is made ************************
        var signature = row[17];
        var sign = signature.substring(signature.indexOf("/") + 1);
        var sigFolder = DriveApp.getFolderById("1IWix3MTEWnGn9lmb91XmCakz7kV3DoCV");

        var files = sigFolder.getFilesByName(sign);
        var n = 0;
        var file;
        while(files.hasNext()){
          file = files.next();
          n++;
        } if(n>1){
          SpreadsheetApp.getUi().alers('there is more than one file with this name' + sign);
        }
        var sigElectInstaller = "%SIGNELECTINSTALL%";
        //var sigElectInstaller = body.appendImage(file);
        //var sig = body.appendImage(file);
        //body.appendImage(file);
        //body.replaceText(sig, row[17]);
        //body.replaceText(file, row[17]);
        body.replaceText(sigElectInstaller, file);
        //*********************** End of the section in question **********************

        body.replaceText("%INSTALLATIONTESTDATE%", row[18]);
        ...
        body.replaceText("%SFCDATE%", row[37]);

        doc.saveAndClose();

        var file = DriveApp.getFileById(doc.getId());
        var newFolder = DriveApp.getFolderById("1_PKmVK3EoTeMd4UStH_zUCqLw3-An5Zv");
        newFolder.addFile(file); 

        var newDocTitle = docTitle[i - 1][0];
        var newDocTagNumber = docTitleTagNumber[i - 1][0];

        doc.setName(newDocTitle + " " + newDocTagNumber + " " + today);
      }
    }
  } 
}

最后一个块是运行脚本的块。 (请注意 ui 部分被标记为易于使用,以避免必须导航回传播 sheet 并手动输入已知标签号。)

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 = "1MaCMLoqj1cnA-GjQT3EZdoGfCsybRZ2JcL5Yi-J1p8U";
      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 "";
    }
  }
}

在您发布的第一段代码中,对所涉及的 类 存在一些误解,您从驱动器中为方法 replaceText() 提供了 File 资源API 但它只接受字符串作为输入。

要在该文本后添加图像,我会获取文本所在的段落元素,然后将图像附加到 insertInlineImage()。所以基本上你的代码应该从这个改变:

    var signature = row[17];
    var sign = signature.substring(signature.indexOf("/") + 1);
    var sigFolder = DriveApp.getFolderById("1IWix3MTEWnGn9lmb91XmCakz7kV3DoCV");

    var files = sigFolder.getFilesByName(sign);
    var n = 0;
    var file;
    while(files.hasNext()){
      file = files.next();
      n++;
    } if(n>1){
      SpreadsheetApp.getUi().alers('there is more than one file with this name' + sign);
    }
    var sigElectInstaller = "%SIGNELECTINSTALL%";
    //var sigElectInstaller = body.appendImage(file);
    //var sig = body.appendImage(file);
    //body.appendImage(file);
    //body.replaceText(sig, row[17]);
    //body.replaceText(file, row[17]);
    body.replaceText(sigElectInstaller, file);

类似这样的事情:

    var signature = row[17];
    var sign = signature.substring(signature.indexOf("/") + 1);
    var sigFolder = DriveApp.getFolderById("1IWix3MTEWnGn9lmb91XmCakz7kV3DoCV");

    var files = sigFolder.getFilesByName(sign);
    var n = 0;
    var file;
    while(files.hasNext()){
      file = files.next();
      n++;
    } if(n>1){
      SpreadsheetApp.getUi().alers('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, // As there are only one element in this case you want to  insert at index 1 so it will appear after the text
                                 file.getBlob() // Notice the .getBlob()
                               );
    paragraph.replaceText(sigElectInstaller, ""); // Remove the placeholder

如果您想更好地控制图片的位置,您可以尝试使用 addPositiondImage