ALL is Well!

          敏捷是一條很長的路,摸索著前進(jìn)著

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            30 隨筆 :: 23 文章 :: 71 評論 :: 0 Trackbacks

          最近項(xiàng)目中要將較大數(shù)據(jù)生成Excel2003或Excel2007文件。

          由于POI很好的采用了面向接口編程的思想,所以其實(shí)生成Excel2003和生成Excel2007的代碼多數(shù)是可以復(fù)用的。

           

          我的做法是:

          1.定義Excel2003FileCreator,用來生成Excel2003文件

          2.定義Excel2007FileCreator,用來生成Excel2007文件,Excel2007FileCreator extends Excel2003FileCreator。

           

          在Excel2003FileCreator中定義

          protected org.apache.poi.ss.usermodel.Workbook workbook;

          protected org.apache.poi.ss.usermodel.Sheet  sheet;

          private org.apache.poi.ss.usermodel.Row        row

           

          Workbook,Sheet ,Row均為接口。

           

          只要在生成workbook時(shí),確定是

          org.apache.poi.hssf.usermodel.HSSFWorkbook   // 生成Excel2003文件用

          還是

          org.apache.poi.xssf.usermodel.XSSFWorkbook   // 生成Excel2007文件用

          即可。

          后續(xù)的Sheet,Row 都是根據(jù) workbook 創(chuàng)建的。

           

          問題的出現(xiàn):

           

          在對每一個(gè)Cell進(jìn)行設(shè)置Style和Value的時(shí)候,我先根據(jù)DB中的配置,取得每個(gè)單元格的格式,再對其進(jìn)行設(shè)定值。

           1    // 取得字體
           2
           3    private static Font getFont(Workbook workbook, int fontHeight, short boldWeight) {
           4        // 字體
           5        font = workbook.createFont();
           6        // Font font = workbook.createFont();
           7        font.setFontName("宋體");
           8        font.setFontHeightInPoints((short)fontHeight);
           9        font.setBoldweight(boldWeight);
          10        return font;
          11    }
          12

          再進(jìn)行設(shè)置其他單元格格式。

          只列實(shí)現(xiàn)代碼:

           1            style = workbook.createCellStyle();
           2
           3            // 邊框
           4            if (hasBorder) {
           5                style.setBorderBottom((short)1);
           6                style.setBorderLeft((short)1);
           7                style.setBorderRight((short)1);
           8                style.setBorderTop((short)1);
           9            }

          10
          11            // 背景顏色
          12            if (isEvenRow) {
          13                style.setFillPattern(CellStyle.SOLID_FOREGROUND);
          14                style.setFillForegroundColor(colorIndex);
          15            }

          16
          17            // 對齊
          18            style.setAlignment(align);
          19            style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
          20            style.setFont(font);
          21            style.setWrapText(true);
          22            
          23            if(!"".equals(excelFmt)) {
          24                short format = HSSFDataFormat.getBuiltinFormat(excelFmt);
          25                style.setDataFormat(format);
          26            }


          取得的Style,再調(diào)用Cell對象的 cell.setCellStyle(Style) 進(jìn)行設(shè)置格式。

           

          因?yàn)檫@段代碼是生成Excel2003和Excel2007時(shí)候都要用到的。

           

          生成1w的數(shù)據(jù),Excel2003是沒有問題的,速度很快。

          但是同樣的數(shù)據(jù),生成Excel2007時(shí),速度慢的可以,讓人不能接受。

           

          最后調(diào)查得出的結(jié)果是:瓶頸在于org.apache.poi.xssf.usermodel.XSSFWorkbook 在生成字體和樣式對象時(shí)。

          問題的解決:

          由于對于文件體的單元格設(shè)置,每一列幾乎是相同的。所以將生成字體和單元格樣式的代碼做了一些小調(diào)整:

           1    private static Font getFont(Workbook workbook, int fontHeight, short boldWeight) {
           2        // 字體 fontMap為全局的Map,用來保存相同字體要求的Font對象
           3         // 當(dāng)要取得字體對象時(shí),先判斷是否已經(jīng)緩存了,如果是,則不需要再創(chuàng)建
           4        Font font = fontMap.get(fontHeight + boldWeight);
           5        if (font == null{
           6            font = workbook.createFont();
           7            // Font font = workbook.createFont();
           8            font.setFontName("宋體");
           9            font.setFontHeightInPoints((short)fontHeight);
          10            font.setBoldweight(boldWeight);
          11            fontMap.put(fontHeight + boldWeight, font);
          12        }

          13        return font;
          14    }


          取得樣式
          1CellStyle style = styleMap.get(Key);
          2        if (style == null{
          3        // 設(shè)定樣式,然后將樣式緩存在全局的HashMap對象styleMap 中
          4         // ..
          5        // 略..styleMap.put(***);
          6}

          7
          8return style;


          這樣改了之后,速度立刻提高了。

          當(dāng)然,在用完之后,記得clear。

           

           

          這里要注意的是,緩存HashMap對象中的Key的設(shè)定。

          Key在組合時(shí)要體現(xiàn)出你的單元格格式,又不會(huì)因?yàn)榻M合,使得緩存中對象混亂了。

          本文為原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處BlogJava

          posted on 2010-09-01 12:36 李 明 閱讀(2636) 評論(1)  編輯  收藏 所屬分類: POI

          評論

          # re: POI3.6 生成Excel2007 效率低的解決辦法 2016-03-07 14:14 老左
          本來就應(yīng)該這樣寫,而且可以直接在構(gòu)造方法中實(shí)例化這些樣式,然而即使這樣也沒有根本性的解決問題。當(dāng)數(shù)據(jù)量稍微大些,多用戶操作的時(shí)候就不知道怎么死的了。  回復(fù)  更多評論
            


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 蓝山县| 新兴县| 临城县| 南雄市| 枞阳县| 浮山县| 霍邱县| 东源县| 神池县| 涟源市| 平利县| 朝阳县| 长兴县| 古丈县| 大姚县| 綦江县| 察哈| 吐鲁番市| 望奎县| 清徐县| 新昌县| 巴林左旗| 卓资县| 库车县| 灵川县| 遂溪县| 靖江市| 岢岚县| 老河口市| 常熟市| 江孜县| 明溪县| 荃湾区| 绍兴县| 宣汉县| 托克逊县| 永吉县| 洞头县| 雷波县| 岗巴县| 麻栗坡县|