Получить значения из пользовательских столбцов электронной таблицы и поместить в шаблон документа - PullRequest
0 голосов
/ 04 апреля 2020

Этот скрипт в моей электронной таблице извлекает все значения столбцов "A" и "B", которые одинаковы для всех строк, и извлекает все значения столбцов "C", "D" и "E". это переменные для всех строк.
Сценарий создает один документ Google, заменяя заполнитель значениями из электронной таблицы.
Заполнитель заключен в%.

Как установить в скрипте столбцы, если они меняются, и установить настраиваемые столбцы?

function myFunction() {
  var templateGoogleDocumentID = "###";  // Please set the template Google Document ID.

  // 1. Retrieve values from Spreadsheet.
  var activeSheet = SpreadsheetApp.getActiveSheet();
  var values = activeSheet.getDataRange().getValues();

  // 2. Create an object for putting to Google Document.
  var object = {headers: {}, table: {}};
  var headerRow = values.shift();
  object.headers[headerRow[0]] = values[0][0];
  object.headers[headerRow[1]] = Utilities.formatDate(values[0][1], Session.getScriptTimeZone(), "yyyy/MM/dd");
  object.table = values.map(r => r.splice(2, 5));

  // 3. Copy a template Google Document.
  var copiedTemplateDoc = DriveApp.getFileById(templateGoogleDocumentID).makeCopy();
  var docId = copiedTemplateDoc.getId();

  // 4. Put the header values to the copied Document using the object.
  var doc = DocumentApp.openById(docId);
  var body = doc.getBody();
  Object.keys(object.headers).forEach(h => body.replaceText(`%${h.toLowerCase()}%`, object.headers[h]));

  // 5. Put the table values using the object.
  // If the table rows of Google Document are less than that of Spreadsheet, the rows are added.
  var table = body.getTables()[0];
  var r = object.table.length - table.getNumRows();
  if (r > 0) {
    for (var i = 0; i < r; i++) {
      var tr = table.appendTableRow();
      for (var j = 0; j < 3; j++) {
        tr.appendTableCell();
      }
    }
  }
  object.table.forEach((row, i) => (row.forEach((col, j) => (table.getCell(i, j).setText(col)))));
  doc.saveAndClose();

  // If you want to export the Google Document as PDF file, please use the following script.
  // var newFile = DriveApp.createFile(doc.getBlob());
}

1 Ответ

1 голос
/ 06 апреля 2020

Вы хотите сделать следующее:

  • Скопировать определенные строки в шаблон документа.
  • Скопировать только некоторые столбцы (вы будете указывать их индексы вручную).
  • Некоторые столбцы являются «фиксированными данными» и заменят некоторые заполнители в верхней части документа.
  • Некоторые столбцы являются «переменными данными», и таблица будет создана с такими данными.
  • Некоторые «переменные данные» представляют собой даты, которые необходимо отформатировать.
  • Данные копируются в копию шаблона документа в указанную папку.

В зависимости от того, как Вы хотите выбрать строки для копирования в шаблон, есть два метода, которые вы можете использовать:

Метод # 1: Копирование выбранных строк:

Этот метод создаст документ быстрее, но вы необходимо вручную выбрать все строки, которые вы хотите скопировать в шаблон, по одной (исключая строку заголовков) .

function exportSelectedRows() {
  var templateGoogleDocumentID = "#########";  // Please set the template Google Document ID.
  var destinationFolderID = "#########"; // Please set the destination folder ID
  var activeSheet = SpreadsheetApp.getActiveSheet();
  var headers = activeSheet.getRange(1, 1, 1, activeSheet.getLastRow()).getValues()[0]; // Get header values
  var values = activeSheet.getActiveRangeList().getRanges().map(range => range.getValues()).flat(); // Get the values of the selected rows
  values.unshift(headers);
  var fixedColumns = [1, 3, 4, 9]; // Fixed column indexes: B, D, E, J  
  var variableColumns = [10, 11, 12, 13, 21, 33]; // Variable column indexes: K,L,M,N,V,AH
  var fixedValues = removeUnwantedColumns(fixedColumns, values).slice(0, 2); // Retrieve fixed values (only header and one row is needed)
  var varValues = removeUnwantedColumns(variableColumns, values).map(row => row.map(value => { // Retrieve variable values (dates are formatted)
    if (Object.prototype.toString.call(value) === "[object Date]") {
      return Utilities.formatDate(new Date(value), Session.getScriptTimeZone(), "yyyy/MM/dd");
    } else return value;
  }));  
  // Create template copy:
  var folder = DriveApp.getFolderById(destinationFolderID); // Get folder with specified destinationFolderID
  var copiedTemplateDoc = DriveApp.getFileById(templateGoogleDocumentID).makeCopy(folder); // Copy template to destination folder
  var docId = copiedTemplateDoc.getId();
  var doc = DocumentApp.openById(docId);
  var body = doc.getBody();
  for (var i = 0; i < fixedValues[0].length; i++) {
    body.replaceText(`%${fixedValues[0][i]}%`, fixedValues[1][i]); // Replace fixed data with placeholders
  }
  body.appendTable(varValues); // Insert new table to document
  var table = body.getTables()[0];
  table.removeFromParent(); // Remove old table
}

function removeUnwantedColumns(columnsToKeep, values) {
  return values.map(row => row.filter((col, i) => columnsToKeep.includes(i)));
}

Метод № 2: Копирование отфильтрованных строк:

В этом методе выполнение займет В особенности, если на листе много строк, но нет необходимости выбирать строки вручную, фильтр обрабатывает это.

Сценарий почти такой же, как в методе № 1, но вам придется замените эту строку:

var values = activeSheet.getActiveRangeList().getRanges().map(range => range.getValues()).flat(); // Get the values of the selected rows

На эту:

var values = activeSheet.getDataRange().getValues().filter((row, i) => !activeSheet.isRowHiddenByFilter(i + 1)); // Remove filtered data

Примечания:

  • Вы должны вручную определить индексы (1) фиксированных столбцов ( fixedColumns), (2) переменные столбцы (variableColumns) и (3) переменные столбцы с форматируемой датой (formatDateColumns).
  • Вы должны вручную указать templateGoogleDocumentID и destinationFolderID в вашем коде (проверьте встроенные комментарии).
  • Заголовки листа должны соответствовать значениям заполнителя в документе, чтобы это работало, включая регистр (в копии, которой вы поделились, например, заполнитель был написан как Codice FIscale, вместо Codice Fiscale).
  • Столбцы таблицы копируются не в соответствии с заполнителями, а в соответствии с их относительным положением на листе. Заголовки также копируются.
  • Вместо того, чтобы проверять, соответствуют ли измерения таблицы измерениям данных, лучше создать новую таблицу с правильными измерениями и удалить старую.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...