锁定老帖子 主题:Java 操作 Excel (读)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (5) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-01-25
最后修改:2009-01-25
一个项目要求读Excel表格,于是Google、baidu查了查,看到不少关于Java读Excel到文章,讲解的比较详细。今天开博,第一篇文章,对Java读Excel进行一下总结,内容全都是来自网络,我只是做了一些修改、总结。经过挑选决定采用poi和fastexcel。
1、poi读取Excel (poi-3.2-FINAL-20081019)
// 构造 HSSFWorkbook 对象,strPath 传入文件路径 HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(strPath)); // 读取文件中的第一张表格 HSSFSheet sheet = wb.getSheetAt(0); // 定义 row、cell HSSFRow row; // HSSFCell cell; String cell; // 循环输出表格中的内容 for (int i = sheet.getFirstRowNum(); i < sheet.getPhysicalNumberOfRows(); i++) { row = sheet.getRow(i); for (int j = row.getFirstCellNum(); j < row.getPhysicalNumberOfCells(); j++) { // 推荐通过 row.getCell(j).toString() 获取单元格内容, cell = row.getCell(j).toString(); System.out.print(cell + "\t"); } System.out.println(""); }
2、fastexcel读Excel (fastexcel-0.2-2009-01-16)
// 打开表格文件,strPath设置文件所在路径 Workbook workBook = FastExcel.createReadableWorkbook(new File(strPath)); workBook.open(); // 基于事件的读取 // workBook.getSheet(0, new SheetReadAdapter() { // public void onCell(int row, int col, String content) { // System.out.println(row + "," + col + "," + content); // } // }); // 基本的读取 // 操作第一张表格 Sheet s = workBook.getSheet(0); // 设置 row、cell String[] row; String cell; // 循环输出表格内容 for (int i = s.getFirstRow(); i < s.getLastRow(); i++) { row = s.getRow(i); for (int j = s.getFirstColumn(); j < s.getLastColumn(); j++) { cell = s.getCell(i, j); System.out.print(cell + "\t"); } System.out.println(""); } // 关闭连接 workBook.close();
3、简单测试读取速度 (Intel(R) Pentium(R) Dual T2330 @ 1.60GHz 内存:2G)
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SS"); TimeZone t = sdf.getTimeZone(); t.setRawOffset(0); sdf.setTimeZone(t); Long startTime = System.currentTimeMillis(); // 检测代码 String fileName = "F:\\我的文档\\专业实训\\07信管缴费代码.xls"; try { // 性能更好,读取更快 FastexcelReadExcel fre = new FastexcelReadExcel(); fre.testFastExcel(fileName); } catch (Exception ex) { Logger.getLogger(FastexcelReadExcel.class.getName()).log(Level.SEVERE, null, ex); } Long endTime = System.currentTimeMillis(); System.out.println("用时:" + sdf.format(new Date(endTime - startTime))); startTime = System.currentTimeMillis(); // 检测代码 try { PoiReadExcel er = new PoiReadExcel(); er.testPoiExcel(fileName); } catch (Exception ex) { Logger.getLogger(FastexcelReadExcel.class.getName()).log(Level.SEVERE, null, ex); } endTime = System.currentTimeMillis(); System.out.println("用时:" + sdf.format(new Date(endTime - startTime)));
fastexcel 读取用时:656ms,poi 读取用时:735ms。 Excel 表格 为 80行8列。
总结:poi是非常强大的,可以完成设置各种格式,但是相对的也可能更慢一些(猜测),fastexcel则更适合读取数据,不需要控制太多的格式,只是简单的读取。 两者的具体实现没有过深入的了解过。 对于读取Excel内容,导入数据库中,优先选用fasteexcel。 对于要求更高的格式控制,优先选用poi。 另外还有JXL等其他操作Excel的开源项目,没有使用过,感觉有以上两者已经足够。 对于office2007格式还没有研究,等待…… 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-01-25
POI确实很强大,但是当你的Excel文件里包含日期类型的字段时你会遇到麻烦的,比如说用PB把数据库导出来,然后直接用POI读取内容时,如果遇到有日期类型会报错,而且POI还没有解决这个问题,我用jxl读取同样的情况下只会报警搞,但是数据能读得出来的,其他方面还没有具体用过。。。
|
|
返回顶楼 | |
发表时间:2009-01-26
heqteyur 写道 POI确实很强大,但是当你的Excel文件里包含日期类型的字段时你会遇到麻烦的,比如说用PB把数据库导出来,然后直接用POI读取内容时,如果遇到有日期类型会报错,而且POI还没有解决这个问题,我用jxl读取同样的情况下只会报警搞,但是数据能读得出来的,其他方面还没有具体用过。。。 不怕你笑话,我还没有遇到过这样的情况,也才刚学习Java一年,没有经验,这次主要是Java读取Excel,把数据导入到MySQL中,所使用的数据不包含日期类型,所以没有碰到你所说的情况。 通过Google查到 HSSFDateUtil.isCellDateFormatted(cell) 可以判断出单元格的值是否为日期 读取日期的话,我感觉可以通过读取文本的方式来实现,在程序中实现转换成日期类型。 不知道 对不对 |
|
返回顶楼 | |
发表时间:2009-01-27
开心就好 写道 heqteyur 写道 POI确实很强大,但是当你的Excel文件里包含日期类型的字段时你会遇到麻烦的,比如说用PB把数据库导出来,然后直接用POI读取内容时,如果遇到有日期类型会报错,而且POI还没有解决这个问题,我用jxl读取同样的情况下只会报警搞,但是数据能读得出来的,其他方面还没有具体用过。。。
不怕你笑话,我还没有遇到过这样的情况,也才刚学习Java一年,没有经验,这次主要是Java读取Excel,把数据导入到MySQL中,所使用的数据不包含日期类型,所以没有碰到你所说的情况。 通过Google查到 HSSFDateUtil.isCellDateFormatted(cell) 可以判断出单元格的值是否为日期 读取日期的话,我感觉可以通过读取文本的方式来实现,在程序中实现转换成日期类型。 不知道 对不对 excel中的数据格式很多,而且很大一部分是可以自定义的,内建格式一般的都可以读出来,但是对于用户自定义的格式在程序分析的时候就会遇到很多麻烦,程序只能一个一个的试。其实最好的方式就是把原生的内建数据读出来,对日期来说就是一个数字,然后自己转换。 许多程序导出的excel在数据的一致性方面还有不同。所以就会出现少读几行之类的情况。程序在读到这种情况的时候也只能打印警告信息。 ps excel在时间的表示方面还有一些bug |
|
返回顶楼 | |
发表时间:2009-02-25
lz对poi操作excel还不深入,在贴出的poi读excel的Java代码中第10行和12行的方法是不正确的,之所以能用是因为你那是从第0行0列开始的数据。
|
|
返回顶楼 | |
发表时间:2009-02-25
几万行的excel 怎么办?
|
|
返回顶楼 | |
发表时间:2009-02-25
几个月前我一直在做导入导出
就是日期的导入会出问题 |
|
返回顶楼 | |
发表时间:2009-02-25
fmzrt 写道 几个月前我一直在做导入导出
就是日期的导入会出问题 日期有问题是因为excel内建的日期格式和java用的日期格式有出入引起的 fastexcel在0.3.1版本中已经加入对这些内建格式的转化,基本上都可以读出来 |
|
返回顶楼 | |
发表时间:2009-02-25
baoq 写道 几万行的excel 怎么办?
这个倒是我一开始做导入导出时一直很困惑的问题,对于b/s应用来说搞个几万行的excel(好像最多是65536吧)出来,如果把它们逐一读取到内存中,再进行业务逻辑上的验证,服务器内存好像吃不消。后来我们在项目中是搞个提示,导入的附件最多只能3M之类的。 不过这样从用户体验来说也不怎么爽吧。 我还真不知道有什么好的解决办法。 |
|
返回顶楼 | |
发表时间:2009-02-28
niwei 写道 baoq 写道 几万行的excel 怎么办?
这个倒是我一开始做导入导出时一直很困惑的问题,对于b/s应用来说搞个几万行的excel(好像最多是65536吧)出来,如果把它们逐一读取到内存中,再进行业务逻辑上的验证,服务器内存好像吃不消。后来我们在项目中是搞个提示,导入的附件最多只能3M之类的。 不过这样从用户体验来说也不怎么爽吧。 我还真不知道有什么好的解决办法。 我用jxl+JDBC+jdk1.5做的导入,最多只能一次导入1.5万条数据,郁闷死我了,再多1条,就报告说虚拟内存不够,开始以为是我程序问题,结果后来发现不是我的,是jxl包中抛了异常,哎,这个问题至今还没解决掉,哎 |
|
返回顶楼 | |