POI使用:解析xls/xlsx文件(兼容office2003/2007/2010版本)
package cn.eguid; import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory; /**
* --2016.3.23
* 解析EXCEL文档1.2
* 支持xlsx和xls文档解析,全面兼容OFFICE所有EXCEL版本文件
* @author eguid
*
** --2016.3.21
* 解析EXCEL文档1.1
* 支持xls文档解析
* @author eguid
*/
public class poi {
/**
* 按照给定的字段进行解析
* 如给定数组:{id,name,sal,date}
* @throws IOException
* @throws InvalidFormatException
*/
public static Map<String, List<String>> parseByfield(File file,String[] fields) throws InvalidFormatException, IOException
{
Workbook wb=createWorkbook(file);
Sheet sheet=wb.getSheetAt(0);
//列
Cell cell=null;
//暂时存放
String data=null;
//最大行数
int maxRowNum=sheet.getLastRowNum();
//最大列数
int MaxCellNum=sheet.getRow(0).getLastCellNum();
List<String>list=null; Map<String,List<String>>map=null;
map=new HashMap<String,List<String>>(); for(int i=0;i<maxRowNum;i++){ list=new ArrayList<String>();
String title=null;
for(int j=0;j<MaxCellNum;j++){
//获取第j行第i列的值
cell=sheet.getRow(j).getCell(i); data=getValue4Cell(cell); //如果标题与给定字段对应,则记录值;否则进入下个整列
if(ishave(fields,data))
{
if(j==0)
{
title=data;
}else{
list.add(data);
}
}
else{
break;
} }
map.put(title, list);
}
return map;
}
/**
* 是否有此字段
* @param fields
* @param field
* @return
*/
private static boolean ishave(String[] fields,String field)
{
if(field==null||fields==null||fields.length<1){
return false;
} for(int index=0;index<fields.length;index++)
{
if(field.equals(fields[index]))
return true;
else
return false;
}
return false;
}
/**
*
* 解析
* 第一行是标题行
* 第二行以后都是内容
* 例如:
* id sex name
* 1 男 王
* 2 女 李
*
*
* 解析后的map格式:
* key value
* 0 List()一行
* 1 List()一行
* 2 List()一行
*
*例如:
*0 [id , name, sex, sal , date]
*1 [1.0, wang, 1.0, 1000.0, 42287.0]
*2 [2.0, liang, 1.0, 1001.0, 42288.0]
*@param file
*@throws IOException
* @throws InvalidFormatException
*/
public static Map parse1(File file) throws IOException, InvalidFormatException
{
//提取并创建工作表
Workbook wb=createWorkbook(file);
//获取sheet页第0页
Sheet sheet = wb.getSheetAt(0);
//获取行迭代器
Iterator rows = sheet.rowIterator();
//解析出来的数据存放到这个map里面,value套了一层List,key用于存放标题,List用于存放标题下的所有数据
Map<String,List<String>> map=new HashMap<String,List<String>>(); String title=null;//标题
int rowindex=0;//行数
int cellindex=0;//列数
String data=null;//用于暂存数据
while(rows.hasNext())
{
List<String> list=new ArrayList<String>();
cellindex=0;
//获取行中数据
Row row = (Row) rows.next();
//获取列迭代器
Iterator cells = row.cellIterator(); while(cells.hasNext())
{
//获取列中数据
Cell cell = (Cell) cells.next();
//获取每个单元格的值
//将标题下的内容放到list中
list.add( getValue4Cell(cell));
}
//将解析完的一列数据压入map
map.put(""+rowindex++, list);
} return map;
}
/**
* 把默认的格式转换成这种格式
* id [1,2,3,4,5]
*name [wang,liang,eguid,qq,yy]
*
* @param map map格式:Map<String,List<String>>
* @return Map<String,List<String>>
*/
public static Map<String,List<String>> format(Map<String,List<String>> map)
{
Map<String,List<String>> newmap=new HashMap<String,List<String>>();
//获取标题行有多少列
String[] titles=new String[map.get("0").size()];
int index=0;
//获取所有标题
for(String s:map.get("0"))
{
titles[index++]=s;
}
//控制List
for(int i=0;i<titles.length;i++)
{
List<String>newlist=new ArrayList<String>();
//控制map
for(int j=1;j<map.size();j++)
{
newlist.add(map.get(j+"").get(i));
}
newmap.put(titles[i],newlist);
}
return newmap;
}
/**
* 解析文件名后缀
* @return
*/
private static String parseFileSuffix(File file)
{
String fileName=file.getName();
return fileName.substring(fileName.lastIndexOf(".")+1, fileName.length());
}
/**
* 提取文件并创建工作表
* @throws IOException
* @throws InvalidFormatException
*/
private static Workbook createWorkbook(File file) throws InvalidFormatException, IOException
{
//如果文件不存在,抛出文件没找到异常
InputStream input = new FileInputStream(file); Workbook wb=null;
//如果创建工作表失败会抛出IO异常
wb=WorkbookFactory.create(input);
return wb;
}
/**
* 提取单元格中的值
*/
private static String getValue4Cell(Cell cell)
{
String data=null;
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC: // 数字
data=String.valueOf(cell.getNumericCellValue()) ;
break;
case Cell.CELL_TYPE_STRING: // 字符串
data=String.valueOf(cell.getStringCellValue()) ;
break;
case Cell.CELL_TYPE_BOOLEAN: // Boolean
data=String.valueOf( cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA: // 公式
data=String.valueOf(cell.getCellFormula()) ;
break;
case Cell.CELL_TYPE_BLANK: // 空值
data=String.valueOf("");
break;
case Cell.CELL_TYPE_ERROR: // 故障
System.out.println(" 故障");
break;
default:
System.out.print("未知类型 ");
break;
}
return data;
}
/**
* 用于关闭流(暂不用)
* @throws IOException
*/
private void closeAll(Closeable...closes) throws IOException
{
if(closes==null)
{
return;
}
if(closes.length<1)
{
return;
}
for(Closeable c:closes)
{
if(c!=null)
{
try {
c.close();
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
}
}
/**
* 格式:
key value id [1.0, 2.0, 3.0, 4.0, 5.0]
sex [1.0, 1.0, 1.0, 0.0, 0.0]
name [wang, liang, eguid, qq, yy]
date [42287.0, 42288.0, 42289.0, 42290.0, 42291.0]
sal [1000.0, 1001.0, 1002.0, 1003.0, 1004.0]
* @throws InvalidFormatException
*/ public static void test1() throws IOException, InvalidFormatException
{
Map<String, List<String>>map=parse1(new File("测试.xlsx"));
Map <String,List<String>>newmap=format(map);
for(Entry<String,List<String>>e:newmap.entrySet())
{
System.out.println(e.getKey());
System.out.println(e.getValue());
}
}
/**
格式:
key value
0 [id, name, sex, sal, date]
1 [1.0, wang, 1.0, 1000.0, 42287.0]
2 [2.0, liang, 1.0, 1001.0, 42288.0]
3 [3.0, eguid, 1.0, 1002.0, 42289.0]
4 [4.0, qq, 0.0, 1003.0, 42290.0]
5 [5.0, yy, 0.0, 1004.0, 42291.0]
* @throws InvalidFormatException
*/
public static void test2() throws IOException, InvalidFormatException
{
Map<String, List<String>>map=parse1(new File("测试.xlsx"));
for(Entry<String,List<String>>e:map.entrySet())
{
System.out.println(e.getKey());
System.out.println(e.getValue());
}
}
public static void main(String[]args) throws IOException, InvalidFormatException
{
//System.out.println(parseFileSuffix(new File("测试.xlsx")));
// test1();
// test2();
Map<String, List<String>> map=parseByfield(new File("测试.xlsx"),new String[]{"id","name"});
System.out.println(map);
}
}
POI使用:解析xls/xlsx文件(兼容office2003/2007/2010版本)的更多相关文章
- 使用POI读取/创建Execl(.xlsx)文件
最近项目中用到了解析Execl表格的功能,在网上百度了一下自己写了一个小Demo.由于项目中使用的是Execl2007,就是后缀为.xlsx的,所以只研究了解析和创建Execl2007的文件,解析Ex ...
- 【POI】解析xls报错:java.util.zip.ZipException: error in opening zip file
今天使用POI解析XLS,报错如下: Servlet.service() for servlet [rest] in context with path [/cetBrand] threw excep ...
- R 读取xls/xlsx文件
包readxl install.packages('readxl',repois='https://mirrors.utsc.edu.cn/CRAN/) library(readxl) # read_ ...
- java使用poi(XSSFWorkbook)读取excel(.xlsx)文件
经过一番搜索发现,java操纵excel文件常用的有jxl和poi两种方式,孰好孰坏看自己需求而定.其中最主要的区别在于jxl不支持.xlsx,而poi支持.xlsx这里介绍的使用poi方式(XSSF ...
- ajaxfileupload.js上传文件兼容IE7及以上版本
要兼容IE789,要修改ajaxfileupload.js;要将此处的代码替换掉 if(window.ActiveXObject) { var io = document.createElement( ...
- 添加找回鼠标右键新建菜单里的新建office2003/2007/2010文档的简洁方法
鼠标右键新建菜单里的新建office文档丢失了怎么办?我们可以通过一些优化设置软件如优化大师来定制,但更简单的方法是只需要导入相应的注册表设置就行了. 下面即在鼠标右键新建菜单里添加新建office2 ...
- office2003?2007共存?版本各自打开的解决方案
在现在的办公软件中, Microsoft出品的 Office集成办公软件占据了绝大多数的市场份额,从最初的 Office 2000,到后面的 Office 2003以至近两年刚发行的 Office 2 ...
- java读取excel文件(.xls,xlsx,csv)
前提,maven工程通过poi读写excel文件,需要在pom.xml中配置依赖关系: 在<dependencies>中添加如下代码 <dependency> <grou ...
- java实现文件批量导入导出实例(兼容xls,xlsx)
1.介绍 java实现文件的导入导出数据库,目前在大部分系统中是比较常见的功能了,今天写个小demo来理解其原理,没接触过的同学也可以看看参考下. 目前我所接触过的导入导出技术主要有POI和iRepo ...
随机推荐
- 函数指针|指针函数|C文件操作
body,table { font-family: 微软雅黑; font-size: 10pt } table { border-collapse: collapse; border: solid g ...
- ES6入门
整理了ES6常用的一些语法,跟大家分享(promise.generator什么的还没有梳理清楚,后续再更新...) 1⃣️ 变量声明-let 与 const (首先关于测试结果:这里有个小问题,如果用 ...
- python——面向对象基础
概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强...” 面向过程编程最易被初学 ...
- php-fpm死机解决办法,脚本后台自动重启
本人用nginx+php7搭建了一台服务器,因为请求量太大,而且php里面又有挂起的任务,导致php-fpm在高峰期的时候经常死掉,吧php-fpm的最大进程数已经改到1000了,还是吃不消,cpu也 ...
- SQL*Plus快速入门
连接数据库sqlplus hr@\"//mymachine.mydomain:port/MYDB\" --连接到MYDB数据库的一个HR数据集里sqlplus hr@MYDB -- ...
- 实体类和数据表的映射异常(XXX is not mapping[ ])
在使用SSH框架开发过程,使用hibernate框架提供的工具类实现与数据库数据交互,在执行cmd操作时,如果出现以下异常: org.hibernate.hql.ast.QuerySyntaxExce ...
- Kafka 源码剖析
1.概述 在对Kafka使用层面掌握后,进一步提升分析其源码是极有必要的.纵观Kafka源码工程结构,不算太复杂,代码量也不算大.分析研究其实现细节难度不算太大.今天笔者给大家分析的是其核心处理模块, ...
- C++高精度模板
原文地址:http://blog.csdn.net/wall_f/article/details/8373395 原文只附代码,没有解析,本文增加了一些对代码的解释. 请注意:本模板不涉及实数运算与负 ...
- 如何在R中导入不同类型的数据
这个表格是我在datacamp学习R导入文件的课程的归纳 遇到的问题及解决方法(环境: Rv3.2.5,win7,32位) 1. 使用gdata中的read.xls时提示找不到Perl路径 >l ...
- hdu4639 hehe 递推
此题为递推题 现场比赛中由于心态问题没能快速推出来定义f[i]为i个连续的he可以表示的语意的个数 则如果第i个he单独考虑f[i]=f[i-1];如果将第i个he和第i-1个he组合 则其只能表示为 ...