跳到主要內容區塊

ntuccepaper2019

專題報導

使用jqGrid (jQuery Grid Plugin)匯出HTML、Excel及PDF檔案
  • 卷期:v0046
  • 出版日期:2018-09-20

作者:唐瑤瑤 / 臺灣大學計算機及資訊網路中心程式設計師


有別於伺服器端網頁應用程式開發技術,客戶端(client-side)技術主要利用使用者之瀏覽器,負責資料的顯示及互動溝通。jQuery挾其龐大開發者貢獻的套件plugins,是目前客戶端最常使用的技術。今天我們要實作的範例即是利用jqGrid - jQuery Plugin從伺服器端動態取得資料後,先以表格grid方式呈現在客戶端瀏覽器頁面,接著利用客戶端資源產生HTML頁面及匯出MS Excel、PDF檔案。

 

需求

因客戶需求,希望將DB資料匯出成MS Excel檔案以利離線使用。以往的作法是在伺服器端(server-side)將資料擷取後,包裝整理成Excel格式檔輸出讓使用者下載。但資料量大時會耗費伺服器資源,易造成連線逾時無法下載之窘境。

 

有別於伺服器端網頁應用程式開發技術,客戶端(client-side)技術主要利用使用者之瀏覽器,負責資料的顯示及互動溝通。jQuery挾其龐大開發者貢獻的套件Plugins,是目前客戶端最常使用的技術。今天我們要實作的範例即是利用jqGrid - jQuery Plugin從伺服器端動態取得資料後,先以表格(Grid)方式呈現在客戶端瀏覽器頁面,接著利用客戶端資源產生HTML頁面及匯出MS Excel、PDF檔案。

 

開發前必要條件

開發者必須熟悉jQuery語法及基本jqGrid 建構,以下幾個js套件程式碼皆為必要。若要匯出Excel檔,jszip 為負責之套件,匯出PDF需要pdfmake 模組套件及字型檔vfs_fonts.js。

 

<!-- The jQuery library is a prerequisite for all plugin products -->
    <script type="text/ecmascript" src="jquery20/jquery.min.js"></script>
<!-- This is the Javascript file of jqGrid -->  
    <script type="text/ecmascript" rc="jquery20/jquery.jqGrid.min.js"></script>
<!-- For generate excel -->
    <script type="text/ ecmascript" src="//cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js"></script>
<!-- Load pdfmake lib files -->
           <script type="text/javascript" language="javascript" src="//cdn.rawgit.com/bpampuch/pdfmake/0.1.20/build/pdfmake.min.js"></script>
           <script type="text/javascript" language="javascript" src="//cdn.rawgit.com/bpampuch/pdfmake/0.1.20/build/vfs_fonts.js"></script>

 

輸出功能注意事項 Common rules
1. grid建構時的datatype必須設定為local;或者loadonce參數必須為true。
2. datatype若設定為json或xml皆無法輸出。
3. 輸出時會以目前顯示之資料集為限(例如已排序、篩選過)。
4. 隱藏欄位無法輸出。
5. 欄位在colModel之屬性exportcol 若設為false無法輸出。
6. 客製化欄位輸出時,選項參數isExported必須設為true,且exporttype 可設定為pdf, csv, 或excel。

 

實作步驟1 - 建立Grid基本架構
HTML內容如下:

 

<div id="div_summary">
    <table id="jqGrid"></table>
    <div id="jqGridPager"></div>                      
    <input class="button" type="button" id="export" value="產生 Excel 檔"/>
    <input class="button" type="button" id="print" value="產生 HTML "/>   
<input class="button" type="button" id="pdf" value="產生 PDF 檔"/>   
</div>

 

Script內容如下:

 

<script type="text/javascript">
$("#jqGrid").jqGrid({
            colModel: [
                { label: 'Course No', name: 'cno', width: 50 },
                { label: 'Course Name', name: 'Title', width: 50 },
                              其他欄位省略…
            ],
            viewrecords: true, // show the current page, data rang and total records on the toolbar           
            其他設定省略…
            datatype: 'local',
            pager: "#jqGridPager",
            caption: "Course List"
        });
</script>

 

實作步驟2 – 使用ajax動態存取JSON資料
前面注意事項提到,grid之datatype屬性只能設為local或者loadonce屬性設為true,若我們想動態讀取各系所之課程資料該如何處理呢?下圖為利用Web API讀取到之JSON課程資料格式,

 

 

JavaScript 程式碼實作部分,利用ajax $.get() 取得資料後,先存入local 陣列 gridArrayData中。接者呼叫 jqGrid() API,method ‘setGridParam’ 設定參數data 為 local 變數 gridArrayData。若需要查看或驗證變數值,console.log() 可以幫助我們在瀏覽器上偵錯。
以下為取得使用者輸入之系所代碼後,按下”開始”按鈕,資料呈現之完整程式碼:

 

$('#form').submit(function (event) {
var keyword = $("#keyword").val();            
     fetchCourseData (keyword);           
     });
function fetchCourseData(keyword) {
var gridArrayData = [];
// show loading message
     $("#jqGrid")[0].grid.beginReq();
$.get('https://xxx.ntu.edu.tw/webservice/api/CourseList/'+keyword, function (result, textStatus, XMLHttpRequest) {
for (var i = 0; i < result.dptCourseList.row.length; i++) {
                    var item = result.dptCourseList.row[i];                   
                    gridArrayData.push({
                        Title: item.crs_cname,
                        cno: item.course_no,
                        Teacher: item.teacher_cname,
                        Day1: item.day1,
                        Day2: item.day2,
                        Day3: item.day3,
                        Day4: item.day4,
                        Day5: item.day5,
                        Day6: item.day6,
                    });
                }
                console.log(gridArrayData);
                // clear first
                $("#jqGrid").clearGridData(true);               
                // set the new data
                $("#jqGrid").jqGrid('setGridParam', { data: gridArrayData });
                $("#jqGrid").jqGrid('setCaption', "Course List( "+keyword+" )");
                // hide the show message
                $("#jqGrid")[0].grid.endReq();
                // refresh the grid               
                $("#jqGrid").trigger('reloadGrid');
            });       
        }

 

執行畫面輸出如下圖:

 

 

實作步驟2
現在來處理匯出excel檔案功能,這部份十分簡單,一旦使用者觸發按鈕click事件,只要呼叫 jqGrid() API,method ‘exportToExcel’ 並設定相關參數即可,完整程式碼如下:

 

$("#export").on("click", function(){
            $("#jqGrid").jqGrid("exportToExcel",{
                includeLabels : true,
                includeGroupHeader : true,
                includeFooter: true,
                fileName : "course-export-"+caption+".xlsx",
                maxlength : 80 // maxlength for visible string data
            })
        })

 

執行結果如下圖,可直接使用Microsoft Excel開啟檔案。

 

 

檔案內容編排會完全依照網頁顯示之結果。如下圖:

 

 

實作步驟3
接著我們來處理HTML輸出功能,這部份不需額外引用jszip plugin,因為已經包含在jqGrid中,是非常實用的功能。一旦使用者觸發按鈕click事件,只要呼叫jqGrid() API,method ‘exportToHtml’ 並設定相關參數即可。

 

其中有2個參數特別介紹給大家,tableClass可以指定客製化CSS樣式設定,達成自訂版面功能。另一個是autoPrint,設定為true會立即呼叫使用者瀏覽器的列印功能。完整程式碼及執行結果如下:

 

$("#print").on("click", function () {
            $("#jqGrid").jqGrid("exportToHtml", {
                title: caption,
                tableClass: 'jqgridprint',
                includeLabels: true,
                includeGroupHeader: true,
                includeFooter: true,
                autoPrint: false
            });
        })

 

 

實作步驟4
最後我們來處理PDF輸出功能,這部份需額外引用pdfmake模組及字型檔,預設提供之字型檔vfs_fonts.js (Roboto.ttf)是無法正確顯示中文字型的,使用者必須自行包裝置換該檔案並設定好相關之pdfmake.js,以便能正確引用支援中文的字型。這部分網路上的資源很多,各位不妨搜尋看看。在此實作範例中,我們更換字型為標楷體kaiu.ttf。

 

同樣的,一旦使用者觸發按鈕click事件,只要呼叫jqGrid() API,method ‘exportToPdf’ 並設定相關參數即可。其中onBeforeExport事件函數,可以在輸出檔案前做一些頁面修改,例如字型大小等。完整程式碼及檔案輸出結果如下:

 

$("#pdf").on("click", function () {
            $("#jqGrid").jqGrid("exportToPdf", {
                onBeforeExport: function (doc) {
                    doc.styles.tableBody.fontSize = 10;
                },
                title: '課程列表',
                orientation: 'portrait',
                pageSize: 'A4',
                description: '課程列表',
download: 'download',
                includeLabels: true,
                includeGroupHeader: true,
                includeFooter: true,
                fileName: "ExportPDF.pdf"
            })
        })

 

 

網頁應用程式前端開發偵錯

目前Chrome, Firefox及Microsoft Edge等各大瀏覽器都提供網頁開發者工具Ctrl+Shift+I,讓前端開發者可以很方便的偵錯,不妨多多使用。

 

結語

jqGrid匯出功能還包含CSV,以及PDF中文字型製作就留給各位開發者自行研究。

 

參考資料

http://www.guriddo.net/demo/guriddojs/
http://www.guriddo.net/documentation/guriddo/javascript/user-guide/exporting/
https://github.com/bpampuch/pdfmake/wiki/Custom-Fonts---client-side