seasun  
          在不斷模仿、思考、總結(jié)中一步一步進步!
          公告
          •     我的blog中的部分資源是來自于網(wǎng)絡(luò)上,如果您認(rèn)為侵犯了您的權(quán)利,請及時聯(lián)系我我會盡快刪除!E-MAIL:shiwenfeng@aliyun.com和QQ:281340916,歡迎交流。

          日歷
          <2009年10月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          常用鏈接

          隨筆分類

          good blog author

          積分與排名

          • 積分 - 81738
          • 排名 - 700

          最新評論

          閱讀排行榜

           
              項目中需要將查詢結(jié)果導(dǎo)出成Excel,由于使用了DisplayTag,知道這個標(biāo)簽庫具有導(dǎo)出Excel的功能,不過之前一直沒有使用過,剛好今天體驗一把。
          使用實在是太Easy了,只需要在display:table標(biāo)簽上設(shè)置一下參數(shù),export="true",就可以在表格下邊看到導(dǎo)出Excel的鏈接了,其他什么都不用做!

              對他的實現(xiàn)方式有點好奇,遂查看一下這個導(dǎo)出功能的鏈接,乖乖,那是相當(dāng)簡潔啊,就是把我這個頁面的全部參數(shù)添加到URL里,然后附加上了幾個奇怪?jǐn)?shù)字組成的參數(shù),估計就是DisplayTag用來識別我要做導(dǎo)出操作的了。從這個鏈接來看,做導(dǎo)出操作時還是要到我這個Action去進行邏輯處理,但我這個Action輸出的內(nèi)容可是一個完整的HTML,而不是Excel啊,他是怎么實現(xiàn)的呢?帶著個大大的問號,開始去挖源代碼。順便提一下,m2eclipse確實方便,不但幫我管理了項目的依賴,還能幫我把源代碼拽下來關(guān)聯(lián)到相應(yīng)的jar,所以我直接在項目依賴?yán)锩嬲业絛isplaytag.jar,就可以查看源代碼了。

              代碼其實很簡單,其實是利用了ServletRsponse的緩存機制,當(dāng)我們調(diào)用response.getWriter().print()方法時,打印的內(nèi)容是不會立即發(fā)送到客戶端的,在發(fā)送到客戶端之前,還可以對其進行操作,哈哈,有點明白了吧?DisplayTag就是利用了這個原理,在TableTag這個類中,導(dǎo)出Excel時,趁ServletResponse還沒有提交到客戶端,先執(zhí)行了一下response.reset()和pageContext.getOut().clearBuffer(),這樣就把前面jsp里面輸出的所有內(nèi)容都清除掉了~然后再使用response.setContentType()重新設(shè)置文件類型,輸出表格內(nèi)容,完事了再返回Tag.SKIP_PAGE,這樣JSP里面剩下的內(nèi)容也不會再輸出了,客戶端得到的就完全是在DisplayTag控制下的內(nèi)容了,牛吧!

              其實這個response.reset以前也見過,讀servlet API文檔時也看過方法的解釋,但如果不是今天看這個Display的源代碼,還真不會想到這樣子來應(yīng)用,看來這就是理論和實踐的差距呀!!!

              PS:上面這種方法,只適用于輸出文本內(nèi)容。DisplayTag自帶的Excel導(dǎo)出工具其實就是輸出了一個csv文件,把擴展名改成xls了而已。如果要輸出真正的xls文件獲者PDF這樣的二進制文件,使用上面的方法在某些中間件上就會有問題了。因為原則上response.getOutputStream方法是只能被調(diào)用一次的,這在進入jsp處理時就被調(diào)用了,而輸出PDF文件這樣二進制流時又必須使用這個方法,那就出錯了。DisplayTag很巧妙的提供了一個Filter,對標(biāo)準(zhǔn)的ServletRepsonse做了一個包裝(Wrap),在執(zhí)行Export導(dǎo)出時,如果是jsp等其他請求執(zhí)行的response.getOutputStream,就返回自己的一個緩存的OutputStream,而不是真正去調(diào)用容器的這個方法。直到執(zhí)行Export時,才去調(diào)用容器的方法,保證這個response.getOutputStream只執(zhí)行一次。

              DisplayTag的地址:http://displaytag.sourceforge.net/1.2/index.html,很簡單,很強大,強烈推薦,可以少寫N多表格和分頁標(biāo)簽



          posted on 2009-10-30 11:29 shiwf 閱讀(4054) 評論(4)  編輯  收藏 所屬分類: 1.09 displaytag
          評論:
          • # re: DisplayTag導(dǎo)出Excel的處理過程  留香 Posted @ 2010-01-23 13:56
            導(dǎo)出Excel只能導(dǎo)出當(dāng)前分頁的內(nèi)容,沒多少實際意義。  回復(fù)  更多評論   

          • # re: DisplayTag導(dǎo)出Excel的處理過程  ping Posted @ 2015-01-04 17:11
            我導(dǎo)出了3萬條數(shù)據(jù),但監(jiān)控內(nèi)存變化時,在堆中的老生代中,已經(jīng)到處過得list內(nèi)同一直占用著內(nèi)存,無法回收,只有重新刷新頁面,才能回收垃圾。很容易造成內(nèi)存溢出,為什么。。。???  回復(fù)  更多評論   

          • # re: DisplayTag導(dǎo)出Excel的處理過程  34 Posted @ 2015-04-13 09:52
            斯蒂芬都算  回復(fù)  更多評論   

          • # re: DisplayTag導(dǎo)出Excel的處理過程  fgbsf Posted @ 2016-04-05 15:16
            sdfsfsd  回復(fù)  更多評論   


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
           
          Copyright © shiwf Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 海阳市| 财经| 利辛县| 新巴尔虎右旗| 休宁县| 湘乡市| 石楼县| 革吉县| 锡林郭勒盟| 天全县| 古浪县| 互助| 泊头市| 革吉县| 镇赉县| 阳西县| 瑞丽市| 错那县| 理塘县| 美姑县| 内江市| 蓬溪县| 鹤壁市| 青冈县| 龙胜| 南江县| 建湖县| 罗城| 崇义县| 泰来县| 香格里拉县| 延川县| 丹江口市| 稷山县| 肥城市| 潞西市| 互助| 东辽县| 巩义市| 叙永县| 阆中市|