1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > java:用HSSFWorkbook实现excel导入(xls xlsx兼容)

java:用HSSFWorkbook实现excel导入(xls xlsx兼容)

时间:2021-09-28 00:15:43

相关推荐

java:用HSSFWorkbook实现excel导入(xls xlsx兼容)

业务:批量导入不同用户的档案信息,excel格式为:信息用户(独一无二)- 姓名 - 性别 - …

数据库档案字段值表为:信息用户id-档案字段id-档案字段值

已有插入方法:add(String username, Integer[] fieldIds, String[] fieldValues),传入信息用户、档案字段id、档案字段值,其中信息用户username将用来查询得到数据库中对应的信息用户id进行操作;fieldIds与fieldValues按数组中的下标一一对应。

效果图:

思路:

我是这样想的,先把excel中的一行行数据返回成可以操作的形式。

首先声明一个Map<String, Object> resultMap = new HashMap<>(),用于放入执行结果code以及数据rowList

其中

code是代表执行结果,如文件值为空/格式有误情况;

rowList是excel返回成的一行一行的数据,即一个个字符串数组List<String[]> rowList = new ArrayList<>();

/*** 将excel文件返回成Map** @param file* @return 返回Map<String, Object> key有两种, ①code为状态码;②rowList为数据集合 */public static Map<String, Object> excelToMap(MultipartFile file) {Map<String, Object> resultMap = new HashMap<>();List<String[]> rowList = new ArrayList<>();try {String suffer = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf(".") + 1);if ("xls".equals(suffer) || "xlsx".equals(suffer)) {InputStream in = file.getInputStream();HSSFWorkbook workbook = new HSSFWorkbook(in);// 得到sheetHSSFSheet sheet = workbook.getSheetAt(0);if (sheet != null) {// 得到每行的值// getLastCellNum比列标大1,行标&列标都以0开始。int size = sheet.getRow(0).getLastCellNum();for (int i = 0; i <= sheet.getLastRowNum(); i++) {HSSFRow row = sheet.getRow(i);String[] cellArr = new String[size];// 得到一行每列的值for (int j = 0; j < size; j++) {HSSFCell cell = row.getCell(j);if (cell == null || cell.getCellTypeEnum() == CellType.BLANK) {cellArr[j] = new String(" ".getBytes("UTF-8"));continue;}cell.setCellType(CellType.STRING);//单元格类型统一设置为String,便于取出String cellValueStr = new String(cell.getStringCellValue().getBytes("UTF-8"));cellArr[j] = cellValueStr;}rowList.add(cellArr);resultMap.put("rowList", rowList);}resultMap.put("code", 200);return resultMap;}//文件值为空resultMap.put("code", 0);return resultMap;}//文件格式有误resultMap.put("code", -1);return resultMap;} catch (Exception e) {logger.info(e.toString());//文件格式有误resultMap.put("code", -1);return resultMap;}}

然后判断执行结果code,如果成功则接着获取rowList。

将rowList中的第一行即标题进行遍历并在数据库中查询,得到其对应的档案字段id,返回成Integer[] fieldIds;再将rowList中的其他行进行遍历,得到要插入的值,返回成String[] cellArr,其中cellArr[0]为信息用户username。并将cellArr数组里其余的值的编码格式转换成utf-8,返回成String[] fieldValues

最后一行一行用前面说的add(String username, Integer[] fieldIds, String[] fieldValues)方法进行添加操作。

/*** 批量导入信息数据*/@Transactional(propagation = Propagation.REQUIRED)@PostMapping("/batchAdd")@ResponseBodypublic AjaxResult batchAdd(@RequestParam(value = "file", required = false) MultipartFile file) {try {Map<String, Object> excelToMap = ExcelUtils.excelToMap(file);//将excel转成mapInteger code = (Integer) excelToMap.get("code");//自动拆箱与int比大小if (code == 200) {List<String[]> rowList = (List<String[]>) excelToMap.get("rowList");//判断第一个单元格值是否为信息用户String firstCell = rowList.get(0)[0];if (firstCell.equals("信息用户")) {List<String[]> rowList = (List<String[]>) excelToMap.get("rowList");String[] firstRow = rowList.get(0);//获取到第一行,即excel标题行Integer[] fieldIds = new Integer[(firstRow.length - 1)];//将excel标题行的value遍历,获取数据库中对应字段idfor (int i = 1; i < firstRow.length; i++) {String cellValue = firstRow[i];QueryWrapper<Field> queryWrapper = new QueryWrapper<>();queryWrapper.eq("field_name", cellValue);Integer id = fieldService.list(queryWrapper).get(0).getId();fieldIds[(i - 1)] = id;}//获得username以及fieldValuesInteger resultCode;//导入后返回codeint sum = 0;//总需导入数int successNum = 0;//成功导入数//int quitNum = 0;//跳过导入数int failNum = 0;//失败导入数for (int i = 1; i < rowList.size(); i++) {String[] cellArr = rowList.get(i);//判断username是否为空String username = cellArr[0];if (username.trim().length() != 0) {sum = sum + 1;String[] fieldValues = new String[(firstRow.length - 1)];for (int j = 1; j < cellArr.length; j++) {if (cellArr[j] == null) {continue;}fieldValues[(j - 1)] = new String(encoder.encode(cellArr[j].getBytes("UTF-8")), StandardCharsets.UTF_8);//编码转换成utf-8}//获得成功导入数以及跳过数resultCode = add(username, fieldIds, fieldValues).getCode();switch (resultCode) {case 200:successNum = successNum + 1;break;default:failNum = failNum + 1;}} else continue;}String message = "总需导入用户数:" + sum + "</br>导入成功用户数:" + successNum + " </br>导入失败用户数:" + failNum + "。";return success(message);}}return error("导入文件有误,请检查文件格式!");} catch (Exception e) {logger.info(e.toString());return error();}}

然后前端

<form class="form-horizontal m"><div class="form-group"><label class="col-sm-3 control-label ">Excel文件:</label><div class="col-sm-8"><input class="" type="file" id="file" name="file"accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"/></div></div><button type="button" class="btn btn-primary" onclick="uploadFile()">提交</button></form>

function uploadFile() {let formData = new FormData();let file = $('#file')[0].files[0];if (typeof (file) != "undefined") {$.modal.msgLoading("处理中,请稍后...");formData.append("file", file);$.ajax({cache: true,type: "POST",url: rootPath + "/xxxController/batchAdd",data: formData,processData: false,contentType: false,dataType: "json",async: false,error: function (request) {$.modal.alertError("上传文件有误");},success: function (data) {let content = data.message;if (data.code == 200) {layer.alert(content, {icon: 1,title: "系统提示",btn: ["确认"],btnclass: ["btn btn-primary"],}, function () {$.modal.close();$.table.refresh(window.rootPath + "/UserController/list");});} else {$.modal.alertError(data.message);}}});}}else {$.modal.alertError("未上传Excel文件");}}

消息弹出框用的是若依,

附上若依操作手册:/ruoyi/ruoyi-8cnv311f.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。