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 ...
随机推荐
- git 添加ssh的方法 push免登陆
在github.com上 建立了一个小项目,可是在每次push 的时候,都要输入用户名和密码,很是麻烦 原因是使用了https方式 push 在termail里边 输入 git remote -v ...
- Windows上管理远程Linux VPS/服务器文件工具 - winscp
Linux上经常会经常需要编辑文件,特别是Linux VPS/服务器安装好系统之后配置环境会需要修改很多的配置文件等,对于常用Linux的基本上都能够熟练使用vi或者nano等SSH下面的文件编辑工具 ...
- iar 错误解决
使用原来备份的项目可以正确烧写并进入调试状态,但使用新项目则报错,错误提示为Failed to load debugee: E:\工作\项目-农业\KaCES-F\Debug\Exe\kaces.tx ...
- .net framework 4.0 从 GAC 卸载 程序集
.net framework 4.0 的 GAC 目录: C:\Windows\Microsoft.NET\assembly\GAC_MSIL 要卸载,仍然使用 gacutil 命令,不要带扩展名: ...
- centos网卡eth1变成eth0修改方法
centos网卡eth1变成eth0修改方法 2013年03月29日 ⁄ Linux基础 ⁄ 共 406字 ⁄ 暂无评论 ⁄ 被围观 8,266 views+ 虚拟化中,从模板克隆出来的虚拟机网卡都会 ...
- [转]MYSQL远程登录权限设置
Mysql默认关闭远程登录权限,如下操作允许用户在任意地点登录: 1. 进入mysql,GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED B ...
- ElasticSearch中的简单查询
前言 最近修改项目,又看了下ElasticSearch中的搜索,所以简单整理一下其中的查询语句等.都是比较基础的.PS,好久没写博客了..大概就是因为懒吧.闲言少叙书归正传. 查询示例 http:// ...
- Django教程
开发环境:Centos7,Django 1.10,Python 2.7 Django入门 本教程内容大部分来源于Django官网,有翻译不到位的欢迎大家指正,这部分的内容有助于新手快速搭建一个网站,让 ...
- IOS开发-封装数据库sqlite3之为何选择FMDB
为什么使用第三方轻量级框架FMDB? FMDB是用于进行数据存储的第三方的框架,它与SQLite与Core Data相比较,存在很多优势. FMDB是面向对象的,它以OC的方式封装了SQLite的C语 ...
- OpenCV GPU CUDA OpenCL 配置
首先,正确安装OpenCV,并且通过测试. 我理解GPU的环境配置由3个主要步骤构成. 1. 生成关联文件,即makefile或工程文件 2. 编译生成与使用硬件相关的库文件,包括动态.静态库文件. ...