java如何实现excel导入数据功能?

java如何实现excel导入数据功能?

在我们日常开发中,经常会遇到excel导入数据功能,如何实现?主要用到了org.apache.poi.xssf.usermodel.XSSFWorkbook类;下面上代码

controller层
	@ApiOperation(value = "导入", notes = "导入")
    @PostMapping("import")
    public CommonResponse<Object> importData(@Validated ImportEntity importEntity) {
        govFinInfoService.importData(importEntity);
        return new CommonResponse<>(null);
    }
实体类:
	@Data
	public class ImportEntity {
	    @NotNull(message = "上传文件不能为空!")
	    private MultipartFile attachment;
	    //导入类型,1:全量导入;0:增量导入
	    private String importType;
	}
	MultipartFile 类型接收前端传入的文件

service层:
 	@Override
    public void importData(ImportEntity importEntity) {
        List<String> columns = getColumns();
        List<List<Object>> excelData = CommonUtils.getExcelData(importEntity,columns);
        List<Integer> idList = govFinInfoDAO.queryIds();
        govFinInfoDAO.importData(excelData);
        //全量导入时 导入成功再删除之前的数据
        if (ONE_OF_IMPORT_TYPE.equals(importEntity.getImportType()) && !idList.isEmpty()) {
            govFinInfoDAO.deleteData(idList);
        }
    }
主要实现getExcelData:
   public static List<List<Object>> getExcelData(ImportEntity importEntity, List<String> columns) {
   		//主要是做文件的校验
        MultipartFile file = importEntity.getAttachment();
        if (file.getSize() == 0) {
            throw new ParamErrorAppException("请不要上传空文件!");
        }
        String filename = file.getOriginalFilename();
        assert filename != null;
        String suffix = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
        if (!"xlsx".equals(suffix)) {
            throw new ParamErrorAppException("只能上传xlsx格式的文件!");
        }
        //文件校验end
        List<List<Object>> dataList = new ArrayList<>();
        try {
        	//这里主要用workBook类解析excel表格的数据
            Workbook workbook = new XSSFWorkbook(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);
            Row titleRow = sheet.getRow(0);
            List<Object> titleData = getCellValue(null, titleRow);
            if (!columns.toString().equals(titleData.toString())) {
                throw new ParamErrorAppException("模板文件有误!");
            }
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) {
                    continue;
                }
                List<Object> rowData = getCellValue(columns.size(), row);
                dataList.add(rowData);
            }
        } catch (Exception e) {
            throw new ParamErrorAppException("数据异常,导入失败:" + e.getMessage());
        }
        return dataList;
    }  
    这里主要是将excel数据解析成List<List<Object>>类型,内层List<Object>主要是每一行数据,
    直接insert到数据库即可;当然也可以实现excel数据与实体类映射,思路是可以使用自定义注解
    做映射。这边为了节约时间,直接使用了简单的写法。大家有兴趣可以尝试一下自定义注解做映射。

解析excel数据getCellValue:
    private static List<Object> getCellValue(Integer columnSize, Row row) {
        List<Object> rowData = new ArrayList<>();
        columnSize = columnSize == null ? row.getLastCellNum() : columnSize;
        for (int j = 0; j < columnSize; j++) {
            Object value = null;
            try {
                Cell cell = row.getCell(j);
                CellType cellTypeEnum = cell.getCellTypeEnum();
                //数值类型
                if (cellTypeEnum == CellType.NUMERIC) {
                    value = cell.getNumericCellValue();
                } else {
                //其他就string类型
                    value = cell.getStringCellValue();
                    value = StringUtils.isEmpty(value) ? null : value;
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
            rowData.add(value);
        }
        return rowData;
    }
 解析完数据后,insert到数据库中:
  <insert id="importData">
        insert into qc_gov_fin(<include refid="baseColumn"/>)
        values
        <foreach collection="list" item="row" separator=",">
            (
            <foreach collection="row" item="item" separator=",">
                #{item}
            </foreach>
            )
        </foreach>
    </insert> 
    根据数据结构做了一个双重循环。
    **注意:获取的数据顺序一定要跟你的数据库字段顺序保持一致!这也是不用实体类映射的弊端,需要人为控制插入字段顺序。** 

至此,excel导入数据功能结束。

记录工作点滴,每日进步一点点~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值