问题背景:对于一些需要快速生成大量数据的情况,通过系统一个一个去生成基本上是不现实的,一般都会采用导入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);
		}
	}
}

学海无涯苦作舟!!!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐