ALL is Well!

敏捷是一条很长的路,摸索着前进着

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  30 随笔 :: 23 文章 :: 71 评论 :: 0 Trackbacks

最近项目中要将较大数据生成Excel2003或Excel2007文件。

由于POI很好的采用了面向接口编程的思想,所以其实生成Excel2003和生成Excel2007的代码多数是可以复用的。

 

我的做法是:

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时,确定是

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

还是

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

即可。

后续的Sheet,Row 都是根据 workbook 创建的。

 

问题的出现:

 

在对每一个Cell进行设置Style和Value的时候,我先根据DB中的配置,取得每个单元格的格式,再对其进行设定值。

 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

再进行设置其他单元格格式。

只列实现代码:

 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,再调用Cell对象的 cell.setCellStyle(Style) 进行设置格式。

 

因为这段代码是生成Excel2003和Excel2007时候都要用到的。

 

生成1w的数据,Excel2003是没有问题的,速度很快。

但是同样的数据,生成Excel2007时,速度慢的可以,让人不能接受。

 

最后调查得出的结果是:瓶颈在于org.apache.poi.xssf.usermodel.XSSFWorkbook 在生成字体和样式对象时。

问题的解决:

由于对于文件体的单元格设置,每一列几乎是相同的。所以将生成字体和单元格样式的代码做了一些小调整:

 1    private static Font getFont(Workbook workbook, int fontHeight, short boldWeight) {
 2        // 字体 fontMap为全局的Map,用来保存相同字体要求的Font对象
 3         // 当要取得字体对象时,先判断是否已经缓存了,如果是,则不需要再创建
 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        // 设定样式,然后将样式缓存在全局的HashMap对象styleMap 中
4         // ..
5        // 略..styleMap.put(***);
6}

7
8return style;


这样改了之后,速度立刻提高了。

当然,在用完之后,记得clear。

 

 

这里要注意的是,缓存HashMap对象中的Key的设定。

Key在组合时要体现出你的单元格格式,又不会因为组合,使得缓存中对象混乱了。

本文为原创,欢迎转载,转载请注明出处BlogJava

posted on 2010-09-01 12:36 李 明 阅读(2584) 评论(1)  编辑  收藏 所属分类: POI

评论

# re: POI3.6 生成Excel2007 效率低的解决办法 2016-03-07 14:14 老左
本来就应该这样写,而且可以直接在构造方法中实例化这些样式,然而即使这样也没有根本性的解决问题。当数据量稍微大些,多用户操作的时候就不知道怎么死的了。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: