从前台导入一个excel文件,解析其中的数据入库;首先根据文件名判断其文件类型是xlsx还是xls,创建对应的workBook并放入文件流;
为了加快文件的读取,减小IO的压力,要快速读取出文件内容,另外保存,及时关闭流!!! (之前忘记关闭流,结果服务器老是重启!!!)
// 读取excel文件每一行的数据
List<Row> rowList = genRowList(multipartFile);
具体实现方法:
/**
* 读取excel文件每一行的数据组成list
*
* @param multipartFile 文件流
* @return 每行数据的list
*/
@Override
public List<Row> genRowList(MultipartFile multipartFile) {
List<Row> rowList = new ArrayList<>();
Workbook hssfWorkbook = null;
try {
String fileName = multipartFile.getOriginalFilename();
InputStream inputStream = multipartFile.getInputStream();
if (fileName.endsWith(OrderLeadinConstants.XLSX)) {
// Excel 2007
hssfWorkbook = new XSSFWorkbook(inputStream);
} else if (fileName.endsWith(OrderLeadinConstants.XLS)) {
// Excel 2003
hssfWorkbook = new HSSFWorkbook(inputStream);
}
// 只读取第一个sheet页
Sheet hssfSheet = hssfWorkbook.getSheetAt(0);
for (int rowNum = 0, size = hssfSheet.getLastRowNum(); rowNum <= size; rowNum++) {
rowList.add(hssfSheet.getRow(rowNum));
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
log.error("根据文件信息获取Workbook错误:{}", e);
}
return rowList;
}
这样就得到了excel文件的一个sheet页的所有行数据,然后就可以遍历此list,处理其中的数据;
注意点:
1.行数的读取,默认第一行是0,就是说,rowList.get(0)得到的是excel的第一行,一般是标题行,可以解析,分析上传的这个excel是不是符合规定的模板;
然后校验excel文件的内容:rowList.size()<=1是否为真,如果是,那就说明此文件只有标题行,或者没有内容;
2.excel文件不同于其他格式文件的一点,你在excel文件中建立5行数据,再手动删除2行表格内容而不是删除整行,那么java读取的时候,rowList.size()就是5!
所以,要对一行的每个cell进行判断,至少一个cell满足StringUtils.isNotBlank()才是非空行;
3.excel的读取中,默认读取的数字是double格式的,所以,excel中的2,读取出来的值是2.0,入库就是2.0;很奇怪的数据,不是我们需要的,就需要将cell格式修改下,定义成String格式的就可以:cell1.setCellType(Cell.CELL_TYPE_STRING);
4.excel的读取中,时间格式的数据"2018-09-11",读取的值是个数字12345(假数据,不要计较),这个是天数(距离1900年1月1日的天数),入库时肯定不能存个天数进去,需要转换:
public String excelTime(Cell cell){
String guarantee_time = null;
if(DateUtil.isCellDateFormatted(cell)){
//用于转化为日期格式
Date d = cell.getDateCellValue();
DateFormat formater = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
guarantee_time = formater.format(d);
}
return guarantee_time;
}
5.excel表格中写的数字,取出来不对,需要转
vinCode = hssfRow.getCell(0, Row.CREATE_NULL_AS_BLANK);
if (vinCode != null) {
vinCode.setCellType(Cell.CELL_TYPE_STRING);
}