使用google documen製作模板套印google spreadsheets資料並轉成PDF
同樣是參考youtube的教學影片
這個程式的套印方式並不是用google spreadsheets內的script
而是利用程式讀取spreadsheets的資料然後
再利用replaceText()置換google documen的內容
但是為了處理自動儲存而在根目錄產生的副本
使用了while進行檔案處理
處理方式是將自動產生的副本檔案移到特定的資料夾裡
因為不管怎麼刪除這些檔案,之後都會自動產生副本…
程式碼的設計流程簡單說明如下
分為兩個function:creatBulkPDFs() 跟 createPDF()
creatBulkPDFs()
1.處理背景參數
例如使用到的google documen、google spreadsheets跟雲端資料夾的ID
2.處理資料
包含將google spreadsheets的資料以參數方式傳到 createPDF()
以及前面提到的處理自動產生的副本檔案
使用了兩種語法 try catch 跟 while迴圈
createPDF()
接收creatBulkPDFs()傳出來的參數
負責複製模板、置換內容、轉換成PDF檔
最後的程式碼如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
function creatBulkPDFs(){ //doc模板 https://docs.google.com/document/d/********************************************/edit const docFile = DriveApp.getFileById("********************************************"); //Logger.log(docFile.getName()); //暫存資料夾 https://drive.google.com/drive/u/0/folders/********************************* const tempFolder = DriveApp.getFolderById("*********************************"); //輸出資料夾 https://drive.google.com/drive/u/0/folders/********************************* const pdfFolder = DriveApp.getFolderById("*********************************"); //工作簿裡的工作表 https://docs.google.com/spreadsheets/d/********************************************/edit#gid=0 const currentSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("名單"); const data = currentSheet.getRange(2, 1, currentSheet.getLastRow()-1, 4).getDisplayValues();//套印資料範圍 A2:D-最後一列的列數-1 let errors = [];//設定錯誤訊息 因為要輸出的是一個範圍 所以要用陣列格式 var i= 1; //Logger.log(data); data.forEach(row => { //相同於 function(row){} //Logger.log(row); try { createPDF(row[0], row[1], row[3], row[0] + " " + row[1], docFile, tempFolder, pdfFolder);//將資料跟參數送到 function createPDF errors.push(["已轉換"+i]);//沒有錯誤 i=i+1; } catch (err) { errors.push(["Failed"]);//輸出"Failed"訊息 } }); //close forEach currentSheet.getRange(2, 5, currentSheet.getLastRow()-1, 1).setValues(errors);//寫出錯誤訊息 setValues 輸出一個範圍 //處理自動儲存的副本 //const autoS = DriveApp.getFileById("********************************************"); //autoS.moveTo(DriveApp.getFolderById("*********************************")); //const autoS=DriveApp.getFilesByName("樣板 的副本"); //Logger.log(autoS.hasNext().valueOf()); var fileName = "樣板 的副本"; var delFold=DriveApp.getFolderById("*********************************"); var files = DriveApp.getFilesByName(fileName); //Logger.log(files.hasNext().valueOf()); while(files.hasNext()) { var objFile = files.next(); objFile.moveTo(delFold); //delFile.removeFile(objFile); objFile.setName("刪除"); } //var delf = DriveApp.getFilesByName("刪除"); //while(delf.hasNext()) //{ // var objFile2 =delf.next(); // delFold.removeFile(objFile2); //} } function createPDF(firstName, lastName, amount, pdfName, docFile, tempFolder, pdfFolder) { const tempFile = docFile.makeCopy(tempFolder); //複製暫存資料夾裡的檔案 const tempDocFile = DocumentApp.openById(tempFile.getId());//設定變數tempDocFile存放複製的檔案 const body = tempDocFile.getBody();//取得檔案內容 body.replaceText("{first}", firstName);//置換資料 body.replaceText("{last}", lastName); body.replaceText("{balance}", amount); tempDocFile.saveAndClose();//存檔 const pdfcontentBlob = tempFile.getAs(MimeType.PDF); //將暫存資料夾裡的檔案轉成PDF pdfFolder.createFile(pdfcontentBlob).setName(pdfName); //產生檔案、命名檔案 tempFolder.removeFile(tempFile);//刪除暫存資料夾裡的檔案 } |
紀錄一下相關的程式碼
DriveApp.getFileById(id)
DriveApp-class的Methods
getFileById(id)
Gets the file with the given ID. Throws a scripting exception if the file does not exist or the user does not have permission to access it.
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(“sheet neme”)
SpreadsheetApp-class的Methods
getActiveSpreadsheet()
Gets the active sheet in a spreadsheet. The active sheet in a spreadsheet is the sheet that is being displayed in the spreadsheet UI.
Spreadsheet-class的Methods
getSheetByName(” neme”)
Returns a sheet with the given name. If multiple sheets have the same name, the leftmost one is returned. Returns null if there is no sheet with the given name.
getRange(row, column, numRows, numColumns)
Sheet-class的Methods
Returns the range with the top left cell at the given coordinates with the given number of rows and columns.
setValues() 、setValue()
Range-class的Methods
setValue(value)
Sets the value of the range. The value can be numeric, string, boolean or date. If it begins with '=' it is interpreted as a formula.
setValues()
Sets a rectangular grid of values (must match dimensions of this range).
DriveApp.getFilesByName()
DriveApp-class的Methods
getFilesByName()
Gets a collection of all files in the user's Drive that have the given name. Return FileIterator — A collection of all files in the user's Drive that have the given name.
FileIterator-class的Methods
hasNext()
Return type-Boolean:Determines whether calling next() will return an item.
next()
Return type-File:Gets the next item in the collection of files or folders.
makeCopy(destination)
File-class的Methods
Creates a copy of the file in the destination directory.
DocumentApp.openById(id)
DocumentApp-class的Methods
Returns the document with the specified ID. If the script is container-bound to the document, use getActiveDocument() instead.
getBody()
Document-class的Methods
Retrieves the active document's Body.
replaceText(searchPattern, replacement)
Text-class的Methods
Replaces all occurrences of a given text pattern with a given replacement string, using regular expressions.
搜尋字串搭配Google’s RE2 regular expression
延伸
forEach迴圈
try catch 語法
new Date()
建立一個 JavaScript Date 物件來指向某一個時間點。Date 物件是基於世界標準時間(UTC) 1970 年 1 月 1 日開始的毫秒數值來儲存時間。 在google apps script 裡則是美西時間,比標準時晚3小時
Utilities.formatDate(date, timeZone, format)
Utilities-class的Methods
Formats date according to specification described in Java SE SimpleDateFormat class.
應用:調整時區以及日期時間格式
Utilities.formatDate(new Date(), “GMT+8”, “yyyy/MM/dd hh:mm:ss Z”)
Utilities.formatString(template, args)
Performs sprintf-like string formatting using '%'-style format strings.
Utilities-class的Methods,似乎只能使用 %f 跟 %s
%f 將浮點 數以10進位方式輸出
%s 使用str()將字串輸出