java, poi, excel
工作需要用java操作Excel,现在网上搜索了一下,决定选取POI包来操作。pom内容如下:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.8</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.8</version> </dependency>
两个版本需要一致,否则会出错。
excel 03和07版本对应不同的操作类,分别是HSSFWorkbook和XSSFWorkbook。他们都继承自接口Workbook,所以在打开文件的时候,判断是哪一个版本,然后使用Workbook操作:
private static Workbook createWorkBook(String path) { try { InputStream in = new FileInputStream(path); if (!in.markSupported()) { in = new PushbackInputStream(in, 8); } if (POIFSFileSystem.hasPOIFSHeader(in)) { return new HSSFWorkbook(in); } if (POIXMLDocument.hasOOXMLHeader(in)) { return new XSSFWorkbook(OPCPackage.open(in)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } throw new IllegalArgumentException("打开excel文件(" + path + ")错误"); }
相应的Sheet,Row 和 Cell也都使用最上层的接口类:
private static Sheet getSheetByName(Workbook workbook, String s) { Sheet sheet = workbook.getSheet(s); if (sheet == null) sheet = workbook.createSheet(s); return sheet; } private static Row getRowFromSheet(Sheet sheet, int rowNum) { Row row; row = sheet.getRow(rowNum); if (row != null) return row; else { row = sheet.createRow(rowNum); return row; } }
以Sheet为例, workbook.getSheet(i)是获得第i个sheet表单,如果不存在,则返回空。 workbook.createSheet(i)是创建表单,会覆盖原有表单。
从Cell中读取数据,有时候使用poi读取出来的单元格式会和在excel中看到的不一样。所以在读取数据时需要多判断一下类型,在poi源码的基础上修改一下:
private static String handleCellV1(Cell cell, int type) { // 读取日期形式单元格数据,返回字符串数据 String var1 = null; int cellType = cell.getCellType(); switch (cellType) { case 0: // numeric if (DateUtil.isCellDateFormatted(cell)) { // 如果是日期格式 SimpleDateFormat sdf = null; if (type == 1) { sdf = new SimpleDateFormat(DATE); // String DATE = "yyyy-MM-dd"; } else { sdf = new SimpleDateFormat(TIME); } Date date = cell.getDateCellValue(); var1 = sdf.format(cell.getDateCellValue()); } else { // 有时候也会变成数字格式 String res = String.valueOf(cell.getNumericCellValue()); BigDecimal bd = new BigDecimal(res); // 数字格式在excel中都是double,所以需要去掉小数点后的数(直接int??) res = bd.toPlainString(); String[] ss = res.split("\\."); res = ss[0]; var1 = res; } break; case 1: // text var1 = cell.getStringCellValue(); break; default: // #unknown cell type var1 = "Unknown Cell Type: " + cell.getCellType(); var1 = null; } return var1; }
写入excel单元格数据,可以使普通的写入:
Row row = sheet.createRow(rowNum); row.createCell().setCellValue("日期");
也可以写入公式:
row.createCell().setCellFormula("IF(B" + rowNum + "=\"初始\",(SUMIFS(F:F,E:E,E" + rowNum + ",C:C,C" + rowNum + ",D:D,D" + rowNum + ",B:B,\"初始\")" + "-SUMIFS(F:F,E:E,E" + rowNum + ",C:C,C" + rowNum + ",D:D,D" + rowNum + ",B:B,\"平\"))" + "/COUNTIFS(E:E,E" + rowNum + ",C:C,C" + rowNum + ",D:D,D" + rowNum + ",B:B,B" + rowNum + "),IF(B" + rowNum + "=\"开\",F" + rowNum + ",F" + rowNum + "))");
写入公示后读取公式的结果摸索了一阵,网上有两种说法:
FormulaEvaluator evaluator = new XSSFFormulaEvaluator((XSSFWorkbook)workbook); CellValue cellValue = evaluator.evaluate(cell1); String res = cellValue.getStringValue();
try { value = String.valueOf(cell.getNumericCellValue()); } catch (IllegalStateException e) { value = String.valueOf(cell.getRichStringCellValue()); }
尝试了之后发现都不能正确读出来。
后来无意中发现,需要手动把写入公式的excel文件打开再保存一下,就可以正常读取。保存之后,在知道类型的情况下直接使用简单语句:
row.getCell(9).getNumericCellValue();
写入excel文件:
FileOutputStream fout = null; Workbook workbook = null;// 创建工作薄 try { workbook = createWorkBook(dir + filename); // workbook = createWorkBook(dir+"test123.xlsx"); // workbook = new XSSFWorkbook(); Sheet sheet0 = getSheetByName(workbook, sheet1Name); Sheet sheet1 = getSheetByName(workbook, sheet2Name); // .... // fout = new FileOutputStream(dir + filename); // fout = new FileOutputStream(dir + "test123.xlsx"); workbook.write(fout); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fout != null) { fout.close(); } } catch (IOException e) { e.printStackTrace(); } }
java, poi, excel的更多相关文章
- java POI excel 导出复合样式(一个单元格两个字体)
前言:java poi 导出 excel 时,需要设置一个单元格有多个字体样式,有点类似于富文本. 想要达到的效果(一个单元格里): 我使用的 poi 版本是 <dependency> & ...
- java POi excel 写入大批量数据
直接贴代码: package jp.co.misumi.mdm.batch.common.jobrunner; import java.io.File; import java.io.FileNotF ...
- java poi excel 生成表格的工具封装
效果如下: 代码如下: import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import ...
- Java POI Excel 导入导出
这个东西很容易懂,不是特别难,难就难在一些复杂的计算和Excel格式的调整上. 近期写了一个小列子,放上来便于以后使用. POI.jar下载地址:http://mirror.bit.edu.cn/ap ...
- java POI Excel 单元格样式
正如Html需要CSS一样,我们的POI生成的Excel同样需要样式才能更完美的表现我们的数据.下面还是从简单的例子出发,学习和了解POI的样式设计. 一.我的位置. 1 package com.my ...
- java poi excel操作 下拉菜单 及数据有效性
1 private InputStream updateTemplateStyleHSSF(InputStream inputStream,CsCustCon csCustCon) throws IO ...
- java poi excel导入模板设置下拉框
import org.apache.poi.hssf.usermodel.DVConstraint; import org.apache.poi.hssf.usermodel.HSSFCell; im ...
- java poi Excel导入 整数浮点数转换问题解决
/** * 获取单元格数据 */ protected static String getCellValue(Cell cell) { String cellValu ...
- java poi excel操作 把第一列放到最后去
@Override public void adjustExcleColumnPosition(String filePath,int col) throws Exception{ File file ...
随机推荐
- 点击按钮回到页面顶部或者某个高度时的问题,JQUERY
$('#shang').click(function(){ $('html,body').animate({scrollTop: '0px'}, 800); }); 不能写成$(window).ani ...
- vitruviano
维特鲁威人(意大利语:Uomo vitruviano) 是列奥纳多·达·芬奇在1487年前后创作的世界著名素描. 它是钢笔和墨水绘制的手稿,规格为34.4 cm × 25.5 cm. 根据约1500年 ...
- 简介C#读取XML的两种方式
简介C#读取XML的两种方式 作者: 字体:[增加 减小] 类型:转载 时间:2013-03-03 在程序中访问进而操作XML文件一般有两种模型,分别是使用DOM(文档对象模型)和流模型,使用DOM的 ...
- H5 认识canvas
不同于SVG,HTML中的元素canvas只支持一种原生的图形绘制:矩形.所有其他的图形的绘制都至少需要生成一条路径.不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能. canvas提供了三 ...
- position置顶或某固定位置 兼容ie6ie7
用absolute来模拟fixed效果: /*相当于正常的position:fixed;top:0 */.sl_fixed_top{bottom:auto;top:0;_bottom:auto;_to ...
- webservice可以访问但是不能调用方法
<webServices> <protocols> <add name="HttpSoa ...
- LA 4329 ping-pong树状数组
题目链接: 刘汝佳,大白书,P197. 枚举裁判的位置,当裁判为i时,可以有多少种选法,如果已经知道在位置i之前有ci个数比ai小,那么在位置i之前就有i-1-ci个数比ai大. 在位置i之后有di个 ...
- sqlserver sum 和count在关于进行统计时的区别
sum是对内容的数量进行相加,count 对表行数 对象进行统计 在使用 case 时,如 select subject,count(case when score>80 then score ...
- 关于nginx配置的不完全总结
请参考官方: http://wiki.nginx.org/HttpRewriteModule#Synopsis 关于缓存大小权限 error log 有如下日志:an upstream respons ...
- IE中Keep-Alive机制引起的错误
我们知道Http协议是基于TCP/IP连接的,也就是说客户端浏览器向服务器发出一个Http请求并得到响应是要建立一条TCP/IP连接的,但是如果每发出一个Http请求客户端就要向服务器端建立一条TCP ...