首先判断是不是是不是模板文档,并且读取成XSSFSheet
@Override
public XSSFSheet bulkLoadInformation(MultipartFile file) {
try {
InputStream inputStream = new ByteArrayInputStream(file.getBytes());
ZipSecureFile.setMinInflateRatio(-1.0d);
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
//读取第一个sheet页的数据
XSSFSheet sheet = workbook.getSheetAt(0);
//第一行
XSSFRow row1 = sheet.getRow(0);
//第一列
XSSFCell cell = row1.getCell(0);
//设置单元格格式
cell.setCellType(CellType.STRING);
//获取单元格中的字符串
String stringCellValue = cell.getStringCellValue();
//截取其中的一部分字符串
String substring = stringCellValue.substring(10, 14);
//第二行
XSSFRow row2 = sheet.getRow(1);
//第二行的列数
int physicalNumberOfCells = row2.getPhysicalNumberOfCells();
//校验是否是模板文档,设置的关键字是12列并且标题的其中一段为“测试用例”,这里因为我假设的第一行第一列是合并单元格的标题,
//第二行是字段列名
if (!"测试用例".equals(substring) || physicalNumberOfCells != 12){
return null;
}
return sheet;
} catch (IOException | StringIndexOutOfBoundsException e) {
return null;
}
}
然后对XSSFSheet进行分析
可以用这个代码来获得excel中的真实行数,但是有时候会失效,所以我用了另一种方法
Integer rows = sheet.getPhysicalNumberOfRows();
/**
* 用来得到真实行数
* @param sheet 需要读取的Excel表格(excel文件的工作簿的名称)
* @return
*
*/
public int readExcelValueRows(XSSFSheet sheet) {
int realRow = 0;// 返回的真实行数
// 标题行有几行就从几开始
for (int i = 0; i <= sheet.getLastRowNum(); i++) {
//i从1开始,不判断第一行标题行
XSSFRow row = sheet.getRow(i);
if (row == null){
continue;
}
for (Cell cell : row) {
if (cell == null){
continue;
}
String value = cell.getStringCellValue().trim();
if (value == null || "".equals(value)){
continue;
} else{
realRow++;
break;
}
}
}
return realRow;
}
对于身份证号的读取,因为身份证号都是15位或者18位的,所以我也写了个小方法
private boolean isLetterOrDigits(String string) {
boolean flag = false;
if (string.length() == 15 || string.length() == 18) {
for (int i = 0; i < string.length(); i++) {
if (Character.isUpperCase(string.charAt(i)) || Character.isDigit(string.charAt(i))) {
flag = true;
} else {
flag = false;
return flag;
}
}
} else {
flag = false;
}
return flag;
}
excel中的时间读取出来会变成时间戳,所以需要自己转换一下
比如excel中的2019/6/17实际上就是43633,指的是从1900年到2019年6月17日间隔多少天
public String formatExcelDate(int day) {
Calendar calendar = new GregorianCalendar(1900, 0, -1);
Date time = calendar.getTime();
return DateUtil.addDate(time, day);
}
这个小方法可以简单的判定是不是小数
public boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*\\.?[0-9]+");
Matcher isNum = pattern.matcher(str);
if (!isNum.matches()) {
return false;
}
return true;
}
可以去除空格、回车、换行符、制表符
private static String StringTrim(String str){
String dest = "";
if (str!=null) {
//空格\t、回车\n、换行符\r、制表符\t
Pattern p = Pattern.compile("\\s*|\\t|\\r|\\n");
Matcher m = p.matcher(str);
dest = m.replaceAll("");
}
return dest;
}
@Override
@Transactional
public void bulkLoadInformation(XSSFSheet sheet) {
//获取真实行数
Integer rows = readExcelValueRows(sheet);
//遍历处理数据
for (int i = 2; i < rows; i++) {
XSSFCell cell = row.getCell(0);
cell.setCellType(CellType.STRING);
//第一列的数据
String example = StringTrim(cell.getStringCellValue());
......
......
}
}