Как создать новый документ из шаблона с заполнителями - PullRequest
1 голос
/ 29 октября 2019

Я пытаюсь создать скрипт, который будет создавать новые документы из шаблона-документа. Замените заполнители в документах данными из листа на основе поиска по ключевым словам в определенном столбце. А затем измените значение строки в определенном столбце, чтобы строка не обрабатывалась при повторном запуске сценария.

Я думаю, что я правильно понял с первым поиском по ключевому слову и циклом по строкам. Но последняя часть, чтобы получить данные для слияния с заполнителями, я не могу понять, как. Я просто получаю значение «объект Объект» и другие значения в документе.

var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var lastColumn = s.getLastColumn();
function createDocFromSheet() {
  var headers = getUpsertHeaders(s);//function is defined outside of this function

  var statusColNum = headers.indexOf('Status')+1;

  var row = getRowsData(s); //The function is defined outside this function.
  for (var i=0; i<row.length; i++) {
     var jobStatus = '';
     if (row[i]['Status'] === '') {

//New: write the status to the correct row and column - this will be moved to the end when I get the rest right
      var jobStatus = "Created";
      s.getRange(i+2, statusColNum).setValue(jobStatus);

//Find the template and make a copy. Activate the body of the new file.
      var templateFile = DriveApp.getFileById('1lkfmqsJMjjPujHqDqKtcDmL-5GMIxpOWTyCOaK29d2A');
      var copyFile = templateFile.makeCopy()      
      var copyId = copyFile.getId()
      var copyDoc = DocumentApp.openById(copyId)
      var copyBody = copyDoc.getActiveSection()

//Find the rows Values as an object.
      var rows = s.getRange(i+2,1,1,lastColumn)
      var rowsValues = rows.getValues();
Logger.log(rowsValues)
//Until here I think it's okay but the last part?

//HOW TO replace the text???
      for (var columnIndex = 0; columnIndex < lastColumn; columnIndex++) {
        var headerValue = headerRow[columnIndex]
        var rowValues = s.getActiveRange(i,columnIndex).getValues()
        var activeCell = rowsValues[columnIndex]
        //var activeCell = formatCell(activeCell);
Logger.log(columnIndex);

        copyBody.replaceText('<<' + headerValue + '>>', activeCell)
}

Шаблон документа: Ссылка Шаблон листа: Ссылка

Ответы [ 2 ]

1 голос
/ 03 ноября 2019

После некоторого кодирования я получил этот код для автоматической обработки всего. Еще раз спасибо @ carlesgg97.

Единственное, что я сейчас просто не могу понять, это как генерировать тело письма из шаблона с динамическими заполнителями, как в документе. Как сгенерировать var patternToFind - но для emailbody?

Я пробовал for (var .... как в документе, но вывод не заменяет заполнители.

var DESTINATION_FOLDER_ID = '1inwFQPmUu1ekGGSB5OnWLc_8Ac80igK0';
var TEMPLATE_FILE_ID = '1lkfmqsJMjjPujHqDqKtcDmL-5GMIxpOWTyCOaK29d2A';

function fillTemplates() {
//Sheet variables
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data');
  var values = sheet.getDataRange().getDisplayValues();
//Header variables
  var headers = sheet.getDataRange().getValues().shift();
  var idIndex = headers.indexOf('ID');
  var nameIndex = headers.indexOf('Name');
  var emailIndex = headers.indexOf('Email');
  var subjectIndex = headers.indexOf('Subject');
  var statusIndex = headers.indexOf('Status');
  var fileNameIndex = headers.indexOf('File Name');
  var filerIndex = headers.indexOf('Filer');
  var birthIndex = headers.indexOf('Date of birth');
  //Logger.log(statusIndex)
//Document Templates ID
  var templateFile = DriveApp.getFileById(TEMPLATE_FILE_ID);
//Destination
  var destinationFolder = DriveApp.getFolderById(DESTINATION_FOLDER_ID);

var templateTextHtml = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Email').getRange('D11').getValue();

//Run through the variables
for (var i=1; i<values.length; i++) {
//If first column is empty then stop
  var index0 = values[i][0];
  if(index0 == "") continue;
    var rowElements = values[i].length;
    var fileStatus = values[i][statusIndex];
//If the row already processed then stop
  if (fileStatus == "Created") continue;
//If the row is not processed continue
//Define the new filename by the relevant Column
    var fileName = values[i][fileNameIndex];
    var newFile = templateFile.makeCopy(fileName, destinationFolder);
    var fileToEdit = DocumentApp.openById(newFile.getId());
//Replace placeholders in the new document
  for (var j=1; j<rowElements-1; j++) {
      var header = values[0][j];
      var docBody = fileToEdit.getBody();
      var patternToFind = Utilities.formatString('{{%s}}', header);
      docBody.replaceText(patternToFind, values[i][j]); 
     }

//Create the PDF file
      fileToEdit.saveAndClose();
      var newPdf = DriveApp.createFile(fileToEdit.getAs('application/pdf'));
      DriveApp.getFolderById(DESTINATION_FOLDER_ID).addFile(newPdf);
      DriveApp.getRootFolder().removeFile(newPdf);
      newFile.setTrashed(true);
      var newPdfUrl = newPdf.getUrl();

//Create the emailbody  
  var textBodyHtml = templateTextHtml.replace("{{Name}}",values[i][nameIndex]).replace("{{Date of birth}}",values[i][birthIndex]);
  var textBodyPlain = textBodyHtml.replace(/\<br>/mg,"");

//Will send email to email Column
    var email = values[i][emailIndex];
    var emailSubject = values[i][idIndex]+" - "+values[i][fileNameIndex]+" - "+values[i][nameIndex];
    MailApp.sendEmail(email,emailSubject,textBodyPlain,     
    {
    htmlBody: textBodyHtml+
              "<p>Automatic generated email</p>",
    attachments: [newPdf],
    });    

      sheet.getRange(i+1, filerIndex+1).setValue(newPdfUrl);
      sheet.getRange(i+1, statusIndex+1).setValue('Created');

  }//Close for (var i=1...

}
1 голос
/ 31 октября 2019

Вы можете использовать следующий код GAS для достижения ваших целей:

var DESTINATION_FOLDER_ID = 'YOUR_DESTINATION_FOLDER_ID';
var TEMPLATE_FILE_ID = 'YOUR_TEMPLATE_FILE_ID';

function fillTemplates() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var templateFile = DriveApp.getFileById(TEMPLATE_FILE_ID);
  var values = sheet.getDataRange().getDisplayValues();
  var destinationFolder = DriveApp.getFolderById(DESTINATION_FOLDER_ID);
  for (var i=1; i<values.length; i++) {
    var rowElements = values[i].length;
    var fileStatus = values[i][rowElements-1];
    if (fileStatus == 'Created') continue;
    var fileName = values[i][0];
    var newFile = templateFile.makeCopy(fileName, destinationFolder);
    var fileToEdit = DocumentApp.openById(newFile.getId());
    for (var j=1; j<rowElements-1; j++) {
      var header = values[0][j];
      var docBody = fileToEdit.getBody();
      var patternToFind = Utilities.formatString('<<%s>>', header);
      docBody.replaceText(patternToFind, values[i][j]); 
    }
    sheet.getRange(i+1, rowElements).setValue('Created');
  }
}

Вам необходимо только заменить 1-ю и 2-ю строки в зависимости от ситуации. Пожалуйста, учтите также, что в коде предполагается, что первый столбец - file name, а последний - status. Вы можете вставить столько столбцов, сколько хотите между ними.

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