java: Using HSSFWorkbook to achieve excel import (xls, xlsx compatible)

Business: Import file information of different users in batches. The excel format is: information user (unique)-name-gender-... the
database file field value table is: information user id-file field id-file field value
has been inserted method: add ( String username, Integer [] fieldIds, String [] fieldValues), incoming information user, file field id, file field value, where the information user username will be used to query the corresponding information user id in the database for operation; fieldIds and fieldValues ​​are pressed The subscripts in the array correspond one-to-one.

I think so, first return the rows of data in excel into an operable form.
First declare a Map <String, Object> resultMap = new HashMap <> (), which is used to put the execution result code and data rowList .
Where
code is the execution result , for example, if the file value is empty or the format is incorrect;
rowList is the row-by-row data returned by excel , that is, a string array 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);
                // 得到sheet
                HSSFSheet 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;
        }
    }

Then determine the execution result code, if successful, then get rowList.
The rowList the first row header that is traversed and the database query to obtain the corresponding field file ID , returned to Integer [] fieldIds ; rowList then the other rows is traversed to obtain the value to be inserted , return to String [] cellArr, where cellArr [0] is the information user username . And convert the encoding format of the remaining values ​​in the cellArr array to utf-8, and return to String [] fieldValues .
Use the add (String username, Integer [] fieldIds, String [] fieldValues) method mentioned above to add the last line.

 /**
     * 批量导入信息数据
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @PostMapping("/batchAdd")
    @ResponseBody
    public AjaxResult batchAdd(@RequestParam(value = "file", required = false) MultipartFile file) {
        try {
            Map<String, Object> excelToMap = ExcelUtils.excelToMap(file);//将excel转成map
            Integer 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遍历,获取数据库中对应字段id
             for (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以及fieldValues
                    Integer resultCode;//导入后返回code
                    int 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();
        }
    }

Then front end

             <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文件");
        }


    }

The message pop-up box is Ruoyi, and the
Ruoyi operation manual is attached: https://www.w3cschool.cn/ruoyi/ruoyi-8cnv311f.html

68 original articles have been published · 128 praised · 80,000 views

Guess you like

Origin blog.csdn.net/qq_39380155/article/details/104970747
Recommended