posts - 36, comments - 419, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          基于模板的excel導出

          Posted on 2010-08-03 21:18 BearRui(AK-47) 閱讀(4401) 評論(5)  編輯  收藏 所屬分類: Java

              產品中有很多模塊需要導出excel功能,導出excel幾乎都是把頁面已經顯示出來的數據列表導出為excel。但后臺使用poi生成excel卻要1個單元格1個單元格的去編寫。每個模塊都需要單獨寫導出excel的代碼,導致代碼里充斥了createRow,createCell,setCellValue的代碼。但這不是要命的,要命的是當前臺數據列表格式變了的時候,后臺生成excel代碼的修改非常麻煩,特別是當產品經理要求在excel中也要保留WEB樣式的時候(背景色,字體色,寬度),就只能oh shit!

          HTML直接另存為excel

          最開始想的解決辦法是直接把數據列表的html代碼另存為xls后綴的excel文件,這樣是最方便,也最容易維護的方式。   可惜因為只是改了文件的后綴,所以當用excel打開的時候就會彈出"您嘗試打開的文件格式與文件擴展名指定格式不一致。"的提示。最終放棄了該方法。

          基于模板引擎的excel數據導出
          在一次跟朋友szyicol(http://www.cnblogs.com/szyicol/)聊天中,聊起該問題,他也碰見了類似的問題,目前也是每個模塊都寫單獨的導出excel代碼。但他說想使用xls模板+xml映射文件(類似與hibernate的映射文件)來做通用導出excel。經他提醒,我最終選擇使用模板引擎生成html代碼,然后把html代碼通過poi生成為excel。這樣開發人員以后導出excel只需要編寫html模板就行。

          選擇html的原因

             選擇通過html代碼(而不是xml或者其他)生成excel的原因有下:

              1、html對于開發人員來可讀性最強,可以說看到這段html代碼就知道生成的excel會是什么樣子。
            2、因導出的就是前臺的數據列表,所以html代碼幾乎可以直接從前臺頁面中copy到模板中就可以了,維護也比較方便,不需要額外比較多的工作量。

           

          HTML格式       

          為了易解析和增加可讀性,要求生成的html代碼只有table tr td標簽,而且只能有1個table,類似下面的代碼:

          <table>
              
          <tr>
                  
          <td colspan="7" align="center">項目名稱</td>
              
          </tr>
              
          <tr>
                  
          <td colspan="7" align="center">(導出時間:2010-08-01)</td>
              
          </tr>
              
          <tr align="center" bgcolor="#9AB0AD">
                  
          <td width="150">記賬人</td>
                  
          <td width="100">日期</td>
                  
          <td width="80">金額</td>
              
          </tr>
              
          <tr bgcolor="#ABCDC1" color="#14645E">
                  
          <td color="#00000">x1</td>
                  
          <td>2010-08-01</td>
                  
          <td>100</td>
              
          </tr>
            
          <tr bgcolor="#ABCDC1" color="#14645E">
                  
          <td color="#00000">x1</td>
                  
          <td>2010-08-01</td>
                  
          <td>100</td>
              
          </tr>
          </table>

           

          模板引擎   

          要根據一些數據生成上面的html代碼,當然需要使用模板引擎,當然選擇什么模板引擎就看自己了,我們選擇了freemarker

          html代碼轉excel
            對于html代碼的解析,因為我們要求html代碼只能有1個table,可以看出我們的html代碼也是符合xml格式的,所以我們就使用xml庫解析html代碼。
          通過xml解析循環所有tr,td標簽,并調用對應的createRow,createCell就能生成excel了,這里不貼出所有代碼,有興趣的自己研究下,只說說poi的幾個問題。

             1、合并單元格    

          當html中出現colspan的時候,就需要用到合并單元格,HSSFSheet.addMergedRegion 支持合并單元格    

            2、設置顏色    

          poi設置顏色比較麻煩,不能直接設置自定義的顏色值,默認只能使用內置的一些顏色。如果要使用自定義的顏色,需要先把內置的一些顏色替換成自定義顏色。建議先選出一些不常用的poi內置顏色(我們選了15個,應該夠用了),當發現有自定義顏色的時候,就循環進行替換這些不常用的顏色。    

           具體可看:http://poi.apache.org/spreadsheet/quick-guide.html#CustomColors    

            3、設置寬度    

          這個在poi文檔中沒看到很詳細的介紹,因為 HSSFSheet.setColumnWidth 方法,使用的并不是像素單位,也不知道是什么單位。經過嘗試發現把像素寬度*40,導出的excel列寬剛好是像素寬度。



          [作者]:BearRui(AK-47)
          [博客]: http://www.aygfsteel.com/bearrui/
          [聲明]:本博所有文章版權歸作者所有(除特殊說明以外),轉載請注明出處.
          英雄,別走啊,幫哥評論下:  

          精彩推薦 好文要頂 水平一般 看不懂 還需努力

          評論

          # re: 基于模板的excel導出  回復  更多評論   

          2010-08-04 09:27 by 遲宏澤
          好文章,頂一下!

          # re: 基于模板的excel導出  回復  更多評論   

          2010-08-04 09:29 by BearRui(AK-47)
          @遲宏澤
          謝謝支持!

          # re: 基于模板的excel導出  回復  更多評論   

          2010-08-05 09:17 by heqs
          樓主的思路講的很清晰,不過還是很想看到代碼啊。呵呵

          # re: 基于模板的excel導出  回復  更多評論   

          2010-08-05 09:33 by BearRui(AK-47)
          @heqs
          謝謝支持,不過代碼還是不放出來了,因為沒經過公司同意,不好意思。^_^

          # re: 基于模板的excel導出  回復  更多評論   

          2010-08-05 12:10 by 一杯清茶
          博主還需努力啊!
          主站蜘蛛池模板: 九龙坡区| 和硕县| 怀远县| 滁州市| 穆棱市| 三穗县| 红河县| 高陵县| 化州市| 北流市| 济阳县| 姜堰市| 扎兰屯市| 普洱| 邻水| 金坛市| 苗栗市| 柳州市| 交城县| 普宁市| 伊吾县| 逊克县| 莱芜市| 收藏| 巢湖市| 福泉市| 澄江县| 马边| 吉木乃县| 宁德市| 南乐县| 监利县| 安溪县| 潞城市| 安平县| 江达县| 岳阳市| 徐汇区| 阿勒泰市| 远安县| 兰坪|