问题背景:对于一些需要快速生成大量数据的情况,通过系统一个一个去生成基本上是不现实的,一般都会采用导入excel的方式去实现。例如:学校的成绩分析管理,需要通过导入一次考试的excel生成必要的分析数据。
实现必要基础,个人认为需要接口传文件的时候附加其他业务参数,如年级等,其次还需要比较完整的解析excel文件
(1)、接口调用方式和接口定义
接口定义如下,用MultipartFile来接收文件,其他入参包含在对象中
接口调用,使用post/form-data的请求,文件传File,其他参数传Text
如果是需要登录用户才可以调用接口,需要在header中设置cookie的请求参数
2、基本解析方式
Workbook可以理解成就是一个excel文件,Sheet为excel的一个sheet,Row为一个sheet的一行。
Workbook有两种实现方式XSSFWorkbook和HSSFWorkbook,前者X开头的为解析xlsx结尾的excel文件,后者为xls结尾的excel文件,前者为office2007后的excel文件类型,后者是office2003版本的excel文件类型,2003的xls在导出的时候会有列数量的限制,最多255列,所以导出的时候建议都是采用2007类型的方式导出,即使用SSFWorkbook生成Workbook对象。解析主要代码如下
file.getOriginalFilename();获取文件的名称
is = file.getInputStream(); 生成文件输入流
注意如果加载方式是本地,不是fastdfs的话,休要加大配置,否则很可能出现失败的情况,因为默认的maxInMemorySize是10K,超出10K的文件会出问题
workbook = new XSSFWorkbook(is); 生成WorkBook对象,即理解为一个excel文件
sheet = workbook.getSheetAt(0); 获取第1个sheet,注意poi解析的时候开始值为0,即第一个sheet
Row titleRow = sheet.getRow(0); 或者sheet的第一行
for (int colum = titleRow.getFirstCellNum(); colum < titleRow.getLastCellNum(); colum++) {} 获取这一行的第一个下标和最后一个下标数值,从0开始
Cell cell = titleRow.getCell(colum); 获取cell对象
for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) // 遍历,从excel的第一行,到最后一行
以下为获取cell对象值的方法,[\\s\\u00A0]为excel中出现的空格问题,用java的trim方法去不掉,亲测以下的方式可以去除excel解析出来值的空格。读取cell内容的方式
public static String getStringValue(Cell cell) {
if (cell == null) {
return null;
}
CellType cellType = cell.getCellType(); // 获取cell的类型
switch (cellType) {
case STRING: // 字符串类型
return cell.getStringCellValue().replaceAll("[\\s\\u00A0]+", "").trim();
case NUMERIC: // 数字类型
double value = cell.getNumericCellValue();
return String.valueOf(value).replaceAll("[\\s\\u00A0]+", "").trim();
case BOOLEAN: // boolean类型
return String.valueOf(cell.getBooleanCellValue()).replaceAll("[\\s\\u00A0]+", "").trim();
case FORMULA: // 计算的表达式
return String.valueOf(cell.getNumericCellValue()).replaceAll("[\\s\\u00A0]+", "").trim();
default: // 其他类型
return null;
}
}
主要调用使用的代码
// Excel解析
Workbook workbook = null;
String excelFile = file.getOriginalFilename(); // 文件名称,包含后缀名
Sheet sheet = null;
Row row = null;
InputStream is = null;
try {
is = file.getInputStream();
// 获取文件workBook
if (excelFile.endsWith("xlsx")) {
workbook = new XSSFWorkbook(is);
} else {
workbook = new HSSFWorkbook(is);
}
if (workbook == null) {
return RespModelFactory.fail("Excel文件有问题,请检查!");
}
// 获取Excel的第一个sheet
sheet = workbook.getSheetAt(0);
Row titleRow = sheet.getRow(0); // excel标题行(默认模板必须是第1行)
List<String> titleList = new ArrayList<>(); // excel标题行的解析内容值
Map<String, String> subjectNameToIdMap = new HashMap<>();
// 解析表头
String titleValue = "";
for (int colum = titleRow.getFirstCellNum(); colum < titleRow.getLastCellNum(); colum++) {
titleValue = ExamExportUtils.getStringValue(titleRow.getCell(colum));
if (StringUtils.isNoneBlank(titleValue)) {
titleList.add(titleValue);
}
}
} catch (Exception e) {
logger.error("" + e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
logger.error("" + e);
}
}
}
学海无涯苦作舟!!!