記得很早以前田榮舉(注:田榮舉現(xiàn)任金蝶集團高級副總裁兼任首席技術(shù)官)和我私下聊過:“打印功能要占到整個系統(tǒng)開發(fā)量的兩成”。打印功能是一個系統(tǒng)開發(fā)的重要組成部分。中國人歷來好面子,往往要求有漂亮的打印,以顯露科技之高深。打印功能對于web報表工具來說就更是不可或缺的了。
因為打印功能的重要性,所以進入web開發(fā)后,很快就開始關(guān)注web打印功能的開發(fā)了,web打印有下面的相關(guān)問題需要考慮清楚:
1 在客戶端還是服務器端打???考慮到數(shù)據(jù)傳遞到客戶端的速度問題,在服務器端做大數(shù)據(jù)量的打印還是不錯的選擇。但在后臺打印必竟很不方便,所以主要還是要在客戶端打印,即利用客戶端的打印機打印。
2 是導出為PDF或EXCEL文件后打印還是直接打?。?/span>將要打印的內(nèi)容生成為PDF或EXCEL文件后再打印,這也是一種方式,這種方式實際上也就幾乎不需要專門考慮打印功能的開發(fā)了,開發(fā)工作量少。但其缺點也很明顯:需要客戶端安裝打開PDF的軟件(或EXCEL軟件),需要在另一個軟件中打印,步驟多,無法實現(xiàn)點擊后直接打印,這種打印模式也無法實現(xiàn)某個單據(jù)是否打印了要當作一個標志保存起來的場合。
3 是利用IE的打印還是自己實現(xiàn)打???如果打印功能全部由自己實現(xiàn),因為要處理數(shù)據(jù),樣式,位置,圖片等的打印,自然程序量小不了,往往會使第一次的下載量很大。而且往打印控件中傳遞要打印的數(shù)據(jù)的過程會比較復雜而且慢。
4 第一次打印時需不需要下載ActiveX控件?如果不需要,則無法用javascript腳本程序控制客戶端的打印機,無法自定義紙張,無法不彈出打印對話框就直接打印。也就是說,最終用戶在每次打印時都要手工選擇好打印參數(shù)(如打印方向,紙張大小等),這樣顯然會使最終用戶的操作比較麻煩。
最開始我是設想直接用javascript腳本來計算分頁,直接利用IE中的打印機制來解決打印問題。后來隨著IE的版本升級,安全機制不斷完善。在不下載ActiveX插件的情況下,IE的安全機制是不可能讓你用javascript腳本來全面控制客戶端的打印機的。試想如果這樣的話就有可能瀏覽網(wǎng)上的某個網(wǎng)頁時,你連接的打印機就自動開始打印東西了。也就是說,要想弄好Web打印,必須要在客戶端下載插件。在中國流氓插件泛濫的情況下,大家一看到插件都怕了。要不就要下載插件,要不打印就不太方便。這成了web打印的死結(jié)。且覺得一樣子無法解開,真是尷尬的Web打印。
既然最佳的方式是無解的,哪就退而求其次吧。用一個小的輕量級的activeX控件來控制客戶端的打印機吧,這樣第一次下載這個activeX控件是也不會很慢。
記得以前在賣web打印控件時,有一用戶將scriptx的網(wǎng)站告訴我,說要能實現(xiàn)這樣的功能就買。于是便開始研究起scriptx來。按照我以前用visual c++編程的經(jīng)驗,覺得大體就是用鉤子函數(shù)來實現(xiàn)。結(jié)合IE的打印模版技術(shù),終于基本上達到了。用visual c++的ATL(為了減少字節(jié)而沒有用MFC)做了一個webprint.dll,這個webprint.dll壓縮成cab文件后只有75K,和一個網(wǎng)頁的大小相當。這樣在第一次下載時便不會太慢了。因為真正的打印機制還是調(diào)用IE內(nèi)部的,并沒有在webprint.dll里面實現(xiàn)具體的打印功能,所以就不需要將要打印的內(nèi)容傳遞到webprint.dll中,這是區(qū)別于其它用activex控件實現(xiàn)web打印的重要一點。如果靠activex控件來實現(xiàn)全部的打印功能的話,就必然要求要將打印的內(nèi)容傳遞到activex控件中,這個傳遞的過程會比較麻煩而且速度也慢。Webprint.dll只完成向IE的內(nèi)部實現(xiàn)的打印功能模塊傳遞打印的基本參數(shù)(如:頁面大小,頁邊距,打印方向,直接打?。?,網(wǎng)頁上顯示什么內(nèi)容就打印什么內(nèi)容,沒有向webprint.dll傳遞打印內(nèi)容的過程。如下圖所示的打印預覽界面圖:
實際上,打印的需求很簡單,無非就是:分頁,頁眉頁腳,頁邊距,打印方向,自定義紙張,直接打印,彈出打印對話框再打印,預覽,放縮打印,成批打印,套打等功能,打印的需求很固定,明確而且通用。將一個多頁的報表一頁頁地打印出來這樣一個簡單的需求,在網(wǎng)頁上卻相當麻煩,我也是在不久前才將它在e表中算是比較理想的實現(xiàn)了,即可以象cs程序一樣,點一下按鈕,就將多頁的報表一頁頁地打印出來。這其中要考慮到在互聯(lián)網(wǎng)上從服務器端向客戶端傳遞大量數(shù)據(jù)時的分頁處理,以及打印了一頁數(shù)據(jù)再傳遞另一頁數(shù)據(jù)的問題。因為如將要打印的多頁內(nèi)容一次從服務器端全部發(fā)送到客戶端的話,在當今互聯(lián)網(wǎng)的條件下很可能會因速度慢而受不了。只能每次從服務器端發(fā)送一頁數(shù)據(jù)到客戶端,打印,然后再發(fā)送下一頁數(shù)據(jù)到客戶端,再打印,如此下去直至打印結(jié)束。這一點也是web打印比c/s程序的打印要麻煩的地方。
總之,Web打印問題已經(jīng)和瀏覽網(wǎng)頁速度慢的問題一樣,成為Web程序的難題之一。只能作一些權(quán)衡。比如象國外因為PDF查看工具的流行,大多選擇生成PDF文件后再打印的方式。我研究Web打印解決方案多年,最終采用的輕量級的ActiveX控件的Web打印方案,是我現(xiàn)在認為最適合中國國情的方案。也許以后還能找到更好的。