暑假实习期间,作为一名Java后台开发的小白实习生,项目组老大分发给我的一项任务就是实现在SSM下实现Excel数据的导入/导出
,咱总不能手动Ctrl+C/Ctrl+V实现吧hhh,于是经过查阅资料,发现Apache的一个子项目POI可以帮助解析Office文档并实现需求。分享如下:
Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。本例中主要使用其中的两个包:HSSF提供读写Microsoft Excel XLS(2003版本)格式档案的功能。XSSF提供读写Microsoft Excel OOXML XLSX(2007版本)格式档案的功能。
1、下载POI
首先进入POI首页:http://poi.apache.org/`,之后点击download进入下载页。
下载一个3.16二进制版,即编译版,不想自己编译,毕竟麻烦。图中两个下载版本的区别在于压缩格式不同,请择一下载。
2、解压POI并加入项目lib中
若未参考文档,咱不知道需要哪些包导入,so先一股脑儿导入项目。全部解压后如下:
测试项目架构如下:
3、设置测试环境
在本例中未编写上传Excel表的功能,仅在jsp页面上点击,后台处理器读取特定位置的Excel文件,然后解析,入库。
3.2 、创建Excel表
为了测试2003和2007两个版本,创建不同版本的测试表:
3.3、jsp页面中设置触发操作
3.4、生成Mapper文件
数据库中的数据表有新添成员people表,so重新配置下mybatis.generator然后重新生成新的mapper和pojo:
在项目中得到对应people表的mapper类和pojo类:
3.5、编写解析入库处理器
下面开始编写处理器,这里简化处理,直接在handler中完成所有操作。更好地作法是在service层完成解析入库的工作。
3.5.1、2003版本处理
@Autowired
PeopleMapper peopleMapper;
@RequestMapping("readXLS")
public String readXLS() {
InputStream is = null;
HSSFWorkbook hssfWorkbook = null;
try {
// 1 打开Excel文件
is = new FileInputStream("d:\\excel\\people.xls");
// 2 通过POI的工作薄类解析xls文件
hssfWorkbook = new HSSFWorkbook(is);
} catch (Exception e) {
is = null;
e.printStackTrace();
}
if (is == null)
return "failed";
// 3 创建people对象准备接收数据
People people = new People();
// 4 循环工作表Sheet,一个excel中可能有多个sheet
for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
if (hssfSheet == null) {
continue;
}
// 循环行Row,一个sheet中可以有多行
for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
// 取得当前行的数据
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
if (hssfRow != null) {
// 获取单元格对象
HSSFCell id = hssfRow.getCell(0);
HSSFCell name = hssfRow.getCell(1);
HSSFCell sex = hssfRow.getCell(2);
HSSFCell birthday = hssfRow.getCell(3);
HSSFCell workday = hssfRow.getCell(4);
// 全部先作为字符串数据提取出来
String idstr = getValue(id);
String namestr = getValue(name);
String sexstr = getValue(sex);
String birthdaystr = getValue(birthday);
String workdaystr = getValue(workday);
try {
// 转换并赋值给people
// id是long类型
people.setId(Long.parseLong(idstr));
// name是String类型
people.setName(namestr);
// sex是Boolean类型
if (sexstr.equals("男")) {
people.setSex(true);
} else if (sexstr.equals("女")) {
people.setSex(false);
}
// birthday是日期型
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
people.setBirthday(sdf.parse(birthdaystr));
people.setWorkday(sdf.parse(workdaystr));
// 入库
peopleMapper.insert(people);
} catch (Exception e) {
}
} // 结束不为空的行的处理
} // 结束循环处理row
} // 结束循环处理sheet
// 关闭EXCEL表
try {
hssfWorkbook.close();
} catch (Exception e) {
}
return "success";
}
//对应版本读取数据的函数
private String getValue(HSSFCell hssfCell) {
if (hssfCell.getCellTypeEnum() == CellType.BOOLEAN) {
// 返回布尔类型的值
return String.valueOf(hssfCell.getBooleanCellValue());
} else if (hssfCell.getCellTypeEnum() == CellType.NUMERIC) {
// 返回数值类型的值,日期类型的数据在EXCEL表中也是数值型
String cellValue = "";
if (HSSFDateUtil.isCellDateFormatted(hssfCell)) { // 判断是日期类型
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");
Date dt = HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue());// 获取成DATE类型
cellValue = dateformat.format(dt);
} else {
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(hssfCell.getNumericCellValue());
}
return cellValue;
} else if (hssfCell.getCellTypeEnum() == CellType._NONE) {
return "";
} else if (hssfCell.getCellTypeEnum() == CellType.BLANK) {
return "";
} else if (hssfCell.getCellTypeEnum() == CellType.STRING) {
// 返回字符串类型的值
return String.valueOf(hssfCell.getStringCellValue());
}
return null;
}
3.5.1、2007版本处理
@RequestMapping("readXLSX")
public String readXLSX() {
InputStream is = null;
XSSFWorkbook xssfWorkbook = null;
try {
// 1 打开Excel文件
is = new FileInputStream("d:\\excel\\people.xlsx");
// 2 通过POI的工作薄类解析xls文件
xssfWorkbook = new XSSFWorkbook(is);
} catch (Exception e) {
is = null;
e.printStackTrace();
}
if (is == null)
return "failed";
// 3 创建people对象准备接收数据
People people = new People();
// 4 循环工作表Sheet,一个excel中可能有多个sheet
for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
if (xssfSheet == null) {
continue;
}
// 循环行Row,一个sheet中可以有多行
for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
// 取得当前行的数据
XSSFRow xssfRow = xssfSheet.getRow(rowNum);
if (xssfRow != null) {
// 获取单元格对象
XSSFCell id = xssfRow.getCell(0);
XSSFCell name = xssfRow.getCell(1);
XSSFCell sex = xssfRow.getCell(2);
XSSFCell birthday = xssfRow.getCell(3);
XSSFCell workday = xssfRow.getCell(4);
// 全部先作为字符串数据提取出来
String idstr = getXValue(id);
String namestr = getXValue(name);
String sexstr = getXValue(sex);
String birthdaystr = getXValue(birthday);
String workdaystr = getXValue(workday);
try {
// 转换并赋值给people
// id是long类型
people.setId(Long.parseLong(idstr));
// name是String类型
people.setName(namestr);
// sex是Boolean类型
if (sexstr.equals("男")) {
people.setSex(true);
} else if (sexstr.equals("女")) {
people.setSex(false);
}
// birthday是日期型
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
people.setBirthday(sdf.parse(birthdaystr));
people.setWorkday(sdf.parse(workdaystr));
// 入库
peopleMapper.insert(people);
} catch (Exception e) {
}
} // 结束不为空的行的处理
} // 结束循环处理row
} // 结束循环处理sheet
// 关闭EXCEL表
try {
xssfWorkbook.close();
} catch (Exception e) {
}
return "success";
}
//对应版本读取数据的函数
private String getXValue(XSSFCell xssfCell) {
if (xssfCell.getCellTypeEnum() == CellType.BOOLEAN) {
// 返回布尔类型的值
return String.valueOf(xssfCell.getBooleanCellValue());
} else if (xssfCell.getCellTypeEnum() == CellType.NUMERIC) {
// 返回数值类型的值,日期类型的数据在EXCEL表中也是数值型
String cellValue = "";
if (HSSFDateUtil.isCellDateFormatted(xssfCell)) { // 判断是日期类型
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");
Date dt = HSSFDateUtil.getJavaDate(xssfCell.getNumericCellValue());// 获取成DATE类型
cellValue = dateformat.format(dt);
} else {
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(xssfCell.getNumericCellValue());
}
return cellValue;
} else if (xssfCell.getCellTypeEnum() == CellType._NONE) {
return "";
} else if (xssfCell.getCellTypeEnum() == CellType.BLANK) {
return "";
} else if (xssfCell.getCellTypeEnum() == CellType.STRING) {
// 返回字符串类型的值
return String.valueOf(xssfCell.getStringCellValue());
}
return null;
}
3.6、触发操作
将项目部署到tomcat上启动index.jsp 并触发响应的操作,DB中的数据表有以下变化:
former:
latter:
感谢各位看官阅读本例,若有疑问,欢迎留言讨论,嘻嘻。