Gg / 使用google documen製作模板套印google spreadsheets資料並轉成PDF

使用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.

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”)

Class SimpleDateFormat

Utilities.formatString(template, args)

Performs sprintf-like string formatting using '%'-style format strings.

Utilities-class的Methods,似乎只能使用 %f 跟 %s

%f 將浮點 數以10進位方式輸出

%s 使用str()將字串輸出

 

參考資源

How to format the date in this Google Apps Script

js字串轉換成數字,數字轉換成字串