EEP全新Word&Excel套表方案
訊光科技/Ken
前言
在現今的Web資訊系統中,除了UI介面的基本操作變化與後端邏輯的運算處理外,文件匯出的需求也是相當頻繁。
而常見的文件匯出方法如下:
1. 將畫面HTML組合後,透過Content-Disposition以附件的形式,和MIME 通訊協定設定ContentType,直接將畫面上的HTML轉為Word格式,提供使用者下載,基本上可以達到所見即所得的結果,但設計畫面的部分就都是在網頁HTML上,適合具備網頁開發能力者。
2. 利用報表工具,設計資料呈現格式,處理一些複雜的運算或是分頁分群等功能,大部分會需要安裝報表環境,或是有額外的License或Runtime時的費用支出。使用者在線上瀏覽後,透過報表的轉檔功能產生輸出文件,偶爾會有格式跑掉的問題。適合有程式撰寫與報表開發工具能力者。
3. 利用Word或Excel設定套表格式,並把資訊系統所整理出來的資料欄位,Mapping到文件畫面上的相對位置,套印在Office文件中。現今大多數一般使用者皆具備操作Office軟體的能力,簡單好上手。
其中Word 和Excel有功能強大、介面親合和門檻較低的優勢,讓使用者快速完成套表排版樣式設計。當格式需要異動時,可直接修改範本檔,存檔便完成更新,不須重新編譯程式。
套表原理
一般套表的基本作法就是將系統資料顯示在Office文件中輸出或再利用。在資訊系統中存放所需的欄位資料,而文件處理的使用者通常已經有一份既定格式的Office文件,當畫面排版完成後,最後的步驟就是把資料放在相對應的位置上呈現。
此次的套表功能適用在RWD & JQuery的UI設計中,直接將畫面上的資料丟給iCoder的文件處理引擎,產生出套表範本所定義好的Word & Excel文件。
與先前套表的差異
先前JQ模組所使用的套表功能,底層使用的是Com Class。透過Microsoft.Office.Interop來產生Office文件。本質上是利用程式碼模擬操作Office Application,在Server端執行Word或Excel處理程序,所以Server端需要安裝Office環境,且權限設定等等的步驟相對複雜。且執行過程中容易有一些不穩定的錯誤,或是背景執行時若遇到Error,處理程序並無法自動釋放,資源會被咬住等等的問題。
正式上線時,遇到多人同時使用文件產生的功能,每個人都會在Server端產生一個Office處理程序,如果程式有錯誤,處理程序不會自動回收,久了就造成Server效能低落甚至直接掛掉等問題。且藉由Client端呼叫Server端的處理程序,會有一些安全上的疑慮。
這種設計方式在微軟的文件中(KB255757)有一段說明,表示他們不建議用這種方式進行從Server透過程式自行產生文件。
原文與翻譯節錄如下:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
Microsoft 目前建議不要從任何無人參與、非交互式客戶端應用程式或組件(包括 ASP、DCOM 和 NT Service)中進行 Microsoft Office 應用程式的“自動化”,也不為此提供支援,因為Office 在這種環境中執行時可能會出現不穩定的現象也可能會有Deadlock的現象。
參考網址:
https://support.microsoft.com/en-us/help/257757/considerations-for-server-side-automation-of-office
現在EEP所推出的套表方案,使用第三方的類別庫(NPOI)。對於Microsoft Office格式檔案擁有讀寫功能,可以在Server端產生Office文件。
優點除了只需要獨立引用,無須安裝Office環境之外,因為NPOI提供了許多封裝好的各類方法,開發時的程式碼相對簡潔而且靈活。檔案格式支援Office 2003與2007的.doc/.docx和.xls/.xlsx檔案類型等,對於處理文件時的效能表現大幅提升。
另外針對套表範本文件中欄位的標籤設定,簡化成跟iCoder相同概念的標記方式,套表設計人員不需要完全了解資料表結構,只要套表範本的欄位名稱與RWD表單上的顯示名稱相同時,便可自動找到Mapping定義。
Word套表實例
舉例有一張員工資料表格式如下,我們可以將各欄位所在的顯示名稱右方或下方,填上”#”符號,系統會自動對應。除了一般欄位,還有日期格式、數值格式和圖片顯示等功能。
日期欄位: “#D 日期格式” #D yyyy/MM/dd HH:mm:ss
數值欄位: “#N N小數位數” #N N2
圖片欄位: “#P”系統會直接抓取DataGrid中該欄位Image路徑下的圖檔
從RWDForm的設計畫面中,找到DataGrid元件,從ToolItems的屬性中增加一個按鈕,呼叫myExport方法(也可自訂其他名稱)。
接著在網頁的原始檔中,貼上這段JavaScript程式碼。
<script>
function myExport() {
$('#dgMaster').datagrid('exportWord', '員工資料表範本');
}
</script>
其中dgMaster是畫面上的DataGridID。
第一個參數:exportWord 是固定的共用方法,代表套表的格式為Word。
如果希望匯出PDF格式的檔案,可以改用exportWordPdf。
第二個參數:員工資料表範本 是範本Word文件的檔案名稱(不需要副檔名)。
範本放置路徑固定為JQWebClient網站下的DocFiles資料夾(如果不存在,可自行手動新增)。
在Runtime畫面中的DataGrid中點選按鈕,執行套表功能。
產生的套表結果如下:
如果Word套印中有明細表的需求,則是使用”##”符號。
系統會直接把RWD網頁上的明細資料自動帶入。
例如以下的範本設計:
再次點選套表按鈕後,輸出結果如下圖:
Excel套表實例
■統計式套表範例
在Excel套表範本中,設定的方法與上述的Word套表大致相同。
只要把呼叫的方法名稱改為exportExcel,或是PDF格式就使用exportExcelPdf。
<script>
function myExport() {
$('#dgMaster').datagrid('exportExcel', '出貨統計表範本');
}
</script>
功能差異的地方則是多了群組功能和統計功能。
如果在資料中需要設定群組,可以在該欄位填入”#G”,同時支援多欄位分群,會依照順序由左至右依序分群。
在畫面中我們設定合計欄位的格式為 ”#NT N0 總計 小計”,
首先”#N”代表數值格式,
若我們設定”#NT”代表此欄位需要加總統計,
接著“N0”代表小數點位數到整數,
最後的”總計”與”小計”是因應上述的分群,可自定義的顯示名稱字串。
最後呈現結果如下圖:
■清單式套表範例
在Excel中,有時一筆資料會有同欄多列呈現的情形,這時欄位名稱也可直接作定義。
範本設定如下圖所示:
可以看到上述的客戶資料,在欄位的排列上就可以有多種變化,可以滿足多樣化的套表需求。
總計的欄位除了先前提到的”NT”之外,也可使用Excel原生的函式SUM()的運算方法。
套表輸出的結果如下圖:
總結
透過EEP的全新Word & Excel套表方案,新增按鈕呼叫共用方法,不須複雜的程式碼撰寫,即可快速完成。在Office的範本文件中只需要簡單的”#”符號即可完成Mapping定義,整體概念與設計方法和iCoder的精神一致,學習門檻極低。
除了報表範本的設計變得容易之外,此次結合了iCoder的文件處理引擎,在產生文件的效能方面有顯著的提升,並提高Server端印表的穩定性。
此次的Word & Excel套表方案,將於下一版的EEP RWD/JQuery模組中, 免費提供。讓一般使用者就能簡單設計套表範本,既能節省程式開發人員的時間成本,使得套印文件的過程更加輕鬆寫意。