嗯,都说要学会写博客,那从现在开始尝试写一写了。
最近有个需求,有一个通过上传excel批量进件的功能,需要新加一个控制,进行一个分支操作。找到了对应的代码,一个方法一千多行,idea的代码规范插件满屏幕的报警。没忍住去重构了一下,哪晓得还是太年轻了,还是掉坑了了。此文权当警醒自己,选择重构就一定要弄清楚原有代码的细节,完善原有代码,切记不可简单的对代码进行一些方法抽取就完事了。
CellType | 类型 | 值 |
---|---|---|
CELL_TYPE_NUMERIC | 数值型 | 0 |
CELL_TYPE_STRING | 字符串型 | 1 |
CELL_TYPE_FORMULA | 公式型 | 2 |
CELL_TYPE_BLANK | 空值 | 3 |
CELL_TYPE_BOOLEAN | 布尔型 | 4 |
CELL_TYPE_ERROR | 错误 | 5 |
上表转自:https://blog.csdn.net/qq_36668778/article/details/82382333
有几个细节还是值得关注的,excel的日期是归类到数值类型的,如果用cell.getNumericCellValue()是取不到想要的值,如果用cell.getStringCellValue()来操作会直接报错:Cannot get a text value from a numeric cell,即使cell.setCellType(Cell.CELL_TYPE_STRING)也不给面子。
实际项目中用到的类型大部分都是String的数据(当然有些报表系统会用到很多其他类型),列出来的函数类型,主要是为了让代码更健壮,函数类型可以按照Numeric和String两种来读取,用错了同样会报错,所以保险起见就用cv.formatAsString()来解决了。
Numeric可以通过cell.setCellType(Cell.CELL_TYPE_STRING)来获取String,但是会丢失精度(2.00会变成2)。
excel里的数值、货币、会计专用、百分比、分数、科学计数这些在excel中显示会不同,但通过cell.getNumericCellValue()读取到的都是double ,所以不用担心"¥","%","/","E+"这些东西会不会有影响(估计只有我才会傻傻的担心这个去把每种都试一遍)。
但是日期格式,这个我就有些吃不准了。测试的时候没发现问题,生产使用时却出问题了,拿到出问题的excel没看出来到底是哪里不对,问了操作员是怎么操作的,说是仅仅把数据拷贝到模板中保存而已(担心格式不对还特意格式刷刷了整个表格),最后是通过选中日期列在上图中重新选择类型后上传读取成功(比较烦的是我还没发复现操作员的操作效果)。
以前的项目中也多少会涉及到excel的读写,也大部分是操作员页面上传一些文件(有时候为了简单起见通常也会说服产品使用csv格式),不过更多的还是系统间到处txt或者del文件进行处理。
开源的excel读写框架比较出名的应该是阿里开源的easyexcel了,本想看看它具体的读取数据的源码,但是太懒了就放弃了。算了,贴一段代码结束吧:
@Test
public void forTest() {
File excel = new File("C:\\Users\\Desktop\\test.xls");
try (FileInputStream in = new FileInputStream(excel);){
HSSFWorkbook wb = new HSSFWorkbook(in);
Sheet sheet = wb.getSheetAt(0);
int firstRowNum = sheet.getFirstRowNum();
int lastRowNum = sheet.getLastRowNum();
for (int i = firstRowNum; i <= lastRowNum; i++) {
Row row = sheet.getRow(i);
Cell cell = row.getCell(0);
if (cell != null) {
switch (cell.getCellType()){
case Cell.CELL_TYPE_STRING:
String strVal = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_NUMERIC:
if (HSSFDateUtil.isCellDateFormatted(cell)){
Date dateVal = cell.getDateCellValue();
} else {
double numVal = cell.getNumericCellValue