Bagaimana cara saya mengirim gabungan dari Google Spreadsheet ke Google Document?

20

Dengan Microsoft Excel dan Microsoft Word, mudah untuk menggabungkan baris dari spreadsheet ke halaman dalam file Word. Ini secara tradisional digunakan untuk membuat surat-surat kertas. Bagaimana saya dapat melakukan hal yang sama dengan Google Drive / Google Documents?

Ada banyak templat yang menawarkan gabungan surat spreadsheet ke email: Bagaimana cara saya menggabungkan surat dengan Gmail? tapi bukan itu yang saya kejar.

Bryce
sumber
Sudahkah Anda mencoba menyalin / menempel?
Jacob Jan Tuinstra
4
Salin / tempel untuk 10.000 baris? Tidak, terima kasih. Word / Excel akan baik-baik saja.
Bryce

Jawaban:

8

Anda harus menulis Skrip Google Apps untuk itu. Anda bisa membiarkan baris pertama spreadsheet menjadi nama bidang, dan membuat dokumen templat tempat bidang yang direferensikan seperti [FIELD].

Jadi jika spreadsheet Anda terlihat seperti:

NAME  |  STREET             | ZIP    | TOWN
---------------------------------------------
Vidar | Karl Johans gate 15 | 0200   | Oslo
John  | 3021 Arlington Road | 123456 | Memphis, TN

... Anda dapat memiliki dokumen templat seperti

[NAMA] yang terhormat, tinggal di [JALAN], [KOTA] [ZIP] ...

Script Anda perlu membuat dokumen baru yang kosong, dan untuk setiap baris dalam spreadsheet Anda, tambahkan halaman baru dan cari / ganti tempat penampung bidang dengan nilai baris.

Saya memiliki versi yang agak berfungsi, yang mungkin perlu dipoles. Itu bisa dipanggil di sini . Ini akan membuat dokumen baru bernama Hasil gabungan surat .

Anda bisa menggunakannya sebagai titik awal untuk skrip Anda sendiri. Beri tahu saya jika Anda menyukainya, atau saya bisa menghabiskan lebih banyak waktu menyelesaikan skrip.

Konten skrip:

var selectedTemplateId = null;
var selectedSpreadsheetId = null;
var spreadsheetDocPicker = null;
var templateDocPicker = null;

function mailMerge(app) {
  var app = UiApp.createApplication().setTitle("Mail Merge");
  templateDocPicker = createFilePicker(app, "Choose template", 
         UiApp.FileType.DOCUMENTS, "templateSelectionHandler"); 
  templateDocPicker.showDocsPicker();
  return app;
};

function createFilePicker(app, title, fileType, selectionHandlerName) {
  Logger.log("Creating file picker for " + fileType);
  var docPicker = app.createDocsListDialog();
  docPicker.setDialogTitle(title);
  docPicker.setInitialView(fileType);
  var selectionHandler = app.createServerHandler(selectionHandlerName);
  docPicker.addSelectionHandler(selectionHandler);
  return docPicker;
}

function templateSelectionHandler(e) {
  var app = UiApp.getActiveApplication();
  selectedTemplateId = e.parameter.items[0].id;
  UserProperties.setProperty("templateId", e.parameter.items[0].id);
  Logger.log("Selected template: " + selectedTemplateId);
  var spreadsheetDocPicker = createFilePicker(app, "Choose spreadsheet", 
        UiApp.FileType.SPREADSHEETS, "spreadsheetSelectionHandler");
  spreadsheetDocPicker.showDocsPicker();
  return app;
}

function spreadsheetSelectionHandler(e) {
  var app = UiApp.getActiveApplication();
  UserProperties.setProperty("spreadsheetId", e.parameter.items[0].id);
  selectedSpreadsheetId = e.parameter.items[0].id;
  Logger.log("Selected spreadsheet: " + selectedSpreadsheetId);
  doMerge();
  return app;
}

function doMerge() {
  var selectedSpreadsheetId = UserProperties.getProperty("spreadsheetId");
  var selectedTemplateId = UserProperties.getProperty("templateId");
  Logger.log("Selected spreadsheet: " + selectedSpreadsheetId);
  var sheet = SpreadsheetApp.openById(selectedSpreadsheetId);
  Logger.log("Spreadsheet opened");
  Logger.log("Opening template: " + selectedTemplateId);
  var template = DocumentApp.openById(selectedTemplateId);
  Logger.log("Template opened");
  var templateFile = DocsList.getFileById(selectedTemplateId);
  var templateDoc = DocumentApp.openById(templateFile.getId());
  //var mergedFile = templateFile.makeCopy();
  var mergedDoc = DocumentApp.create("Result of mail merge");
  var bodyCopy = templateDoc.getActiveSection().copy();
  Logger.log("Copy made");
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var values = rows.getValues();
  var fieldNames = values[0];

  for (var i = 1; i < numRows; i++) {
    var row = values[i];
    Logger.log("Processing row " + i + " " + row);
    var body = bodyCopy.copy();
    for (var f = 0; f < fieldNames.length; f++) {
      Logger.log("Processing field " + f + " " + fieldNames[f]);
      Logger.log("Replacing [" + fieldNames[f] + "] with " + row[f]);
      body.replaceText("\\[" + fieldNames[f] + "\\]", row[f]);
    }
    var numChildren = body.getNumChildren();
    for (var c = 0; c < numChildren; c++) {
      var child = body.getChild(c);
      child = child.copy();
      if (child.getType() == DocumentApp.ElementType.HORIZONTALRULE) {
        mergedDoc.appendHorizontalRule(child);
      } else if (child.getType() == DocumentApp.ElementType.INLINEIMAGE) {
        mergedDoc.appendImage(child);
      } else if (child.getType() == DocumentApp.ElementType.PARAGRAPH) {
        mergedDoc.appendParagraph(child);
      } else if (child.getType() == DocumentApp.ElementType.LISTITEM) {
        mergedDoc.appendListItem(child);
      } else if (child.getType() == DocumentApp.ElementType.TABLE) {
        mergedDoc.appendTable(child);
      } else {
        Logger.log("Unknown element type: " + child);
      }
   }
   Logger.log("Appending page break");
   mergedDoc.appendPageBreak();
   Logger.log("Result is now " + mergedDoc.getActiveSection().getText());
  }
}

function testMerge() {
  UserProperties.setProperty("templateId", 
    "1pAXWE0uklZ8z-O_Tejuv3pWSTiSv583ptUTGPt2Knm8");
  UserProperties.setProperty("spreadsheetId", 
    "0Avea1NXBTibYdFo5QkZzWWlMYUhkclNSaFpRWUZOTUE");
  doMerge();
}


function doGet() {
  return mailMerge();
}
Vidar S. Ramdal
sumber
1
Mengapa Anda memilih untuk menggunakan aplikasi mandiri dan tidak membangun dari dalam spreadsheet? Itu akan membuat OP lebih mudah. Kedua, mengapa ada begitu banyak panggilan Logger dalam skrip? Itu akan membuat naskah terlalu padat.
Jacob Jan Tuinstra
Arsip skrip Google dulunya memiliki beberapa skrip pra-dibangun ... adakah alasan khusus Anda atau yang lain tidak akan diunggah di sana?
Bryce
Tidak memperhatikan komentar Yakub sampai sekarang, dan seperti yang dia katakan, itu mungkin harus berupa skrip spreadsheet alih-alih mandiri. Saya akan melihat apakah saya dapat menemukan waktu untuk mengerjakannya, dan mengirimkannya ke galeri Script.
Vidar S. Ramdal
5
Vidar Ini adalah jawaban yang bagus. Saya membersihkannya, dan memperbarui beberapa metode yang sudah usang, dan menyingkirkan fungsi yang tidak perlu, dan juga memodifikasinya untuk dijalankan dari dalam spreadsheet seperti yang disarankan @JacobJanTuinstra. Kemudian saya menyadari bahwa ada bug yang memecah gambar , dan saya juga membuat solusi untuk bug tersebut. Saya merasa bahwa sekarang sudah cukup bagus untuk mengenakan Github. Saya telah mempostingnya di sana dan di dalamnya disediakan tautan ke respons Anda sebagai versi awal pekerjaan.
hadi
@Hadi Kerja bagus!
Vidar S. Ramdal
6

Melalui Pengaya Google Drive yang baru , ada beberapa kemungkinan gabungan surat yang tersedia, seperti "Yet Another Mail Merge".

Untuk menggunakannya, Anda harus memiliki "Spreadsheet Google" baru, dan menginstal add-on melalui menu Add Ons:

Cuplikan layar dari Google Spreadsheets

Cari Mail merge, dan Anda akan menemukan beberapa opsi.

Vidar S. Ramdal
sumber
Perhatikan bahwa dibatasi hingga 100 email per hari (gratis).
pixeline
5

Pos Google sendiri menjelaskan cara mengatur data umpan dalam satu lembar dan templat di lembar lain, alih-alih Google Spreadsheet + Google Doc: https://developers.google.com/apps-script/articles/mail_merge

Namun, hasil akhirnya adalah MailAppmengirim email, bukan dokumen "kloning" yang diinginkan. Saya akan menyarankan menggabungkan tutorial dan jawaban @ Vidar, sesuatu di sepanjang baris menggantikan:

MailApp.sendEmail(rowData.emailAddress, emailSubject, emailText);

dengan

var mergedDoc, bodyContent,
    // you'd have to make the DocumentTitle column for the following
    newTitle = rowData.DocumentTitle /* or set to a static title, etc */;

// make a copy of the template document -- see http://stackoverflow.com/a/13243070/1037948
// or start a new one if you aren't using the template, but rather text from a template field
if( usingTemplateFile ) {
    mergedDoc = templateDoc.makeCopy(newTitle)
    bodyContent = mergedDoc.getBody();
} else {
    mergedDoc = DocumentApp.create(newTitle);
    bodyContent = mergedDoc.getBody();
    bodyContent.setText(templateFieldContents);
}

// tweak the fillInTemplateFromObject to accept a document Body and use .replaceText() instead of .match as in mailmerge example
// .replaceText see https://developers.google.com/apps-script/reference/document/body#replaceText(String,String)
fillInTemplateFromObject(bodyContent, rowData);

// no append needed?

Referensi AppScripts Acak:

drzaus
sumber
hanya berlari melintasi GIST ini sebagai contoh lain gist.github.com/mhawksey/1170597
drzaus
3
Pertanyaannya secara khusus tidak termasuk gabungan surat email.
Bryce
3

Saya merekomendasikan autoCrat . Ini adalah Google Add-On dengan antarmuka seperti penyihir yang luar biasa untuk membantu Anda menyiapkan penggabungan.

morfatik
sumber
1

Saya memiliki masalah yang sama dan mencoba menyelesaikannya dengan jawaban Vidar tetapi karena penghinaan itu tidak berhasil.

Solusi sebenarnya adalah tautan oleh @hadi dalam komentar di jawaban Vidar.

Vidar :
Ini jawaban yang bagus. Saya membersihkannya, dan memperbarui beberapa metode yang sudah usang, dan menyingkirkan fungsi yang tidak perlu, dan juga memodifikasinya untuk dijalankan dari dalam spreadsheet seperti yang disarankan @ JacobJanTuinstra . Kemudian saya menyadari bahwa ada bug yang memecah gambar, dan saya juga membuat solusi untuk bug tersebut. Saya merasa bahwa sekarang sudah cukup bagus untuk mengenakan Github. Saya telah mempostingnya di sana dan di dalamnya disediakan tautan ke respons Anda sebagai versi awal pekerjaan.
- hadi 4 Maret 2015 pukul 19:24 "

https://github.com/hadaf/SheetsToDocsMerge :

  A Google Apps Script that merges information from a Google Sheet into a 
  Template created by Google Docs. The result is a new Google Docs file 
  that is populated by the Sheet data.

Cukup ikuti langkah-langkah di Readmedan saya dapat membuat dokumen gabungan dari template Google-Doc dan Google-Sheet.

inovasi bennett
sumber