• 【Java】【46】导入Excel到数据库


    前言:

    业务场景:用户提供Excel表,在页面上点击“导入按钮”,系统读取Excel中的数据,存到对应的数据库

    注:

    1,目前仅提供导入简单的Excel表,没有合并单元格,只能读取单页sheet

    2,方法里用到了具体业务场景的实体类,所以适用性不是很强,其他场景要用的话,还需要修改代码。但是也具有一定的参考性,所以先记录下来。我的后续思路是:在 工具类(ReadExcelUtil) 里根据导入的Excel表头确定要处理的字段名,然后拼成json格式的数据,传到Service层,再做处理。之后再做更新 //TODO

    3,用的jar包:POI

    正文:

    html:

    <div>
        <span><input type="file" id="upfile" name="upfile" placeholder=""/></span>
        <button onclick="importExp();">导入</button>
        <span>格式:.xls</span>
    </div>

    JS:

    function importExp() {
        var name = $("#upfile").val();
        var file =  $("#upfile")[0].files[0];
        // ajax...
    }

    Java:

    Controller层

    @ApiOperation(value = "导入Excel")
    @RequestMapping(value="excel/import", method = RequestMethod.POST)
    public void importExcel(MultipartFile file) {
        return this.theService.importExcel(file);
    }

    Service层

    public void importExcel(MultipartFile file) {
        if(file.isEmpty()){
            //请先选择Excel文件。是否把报错等信息返回到前端,视情况而定。
            return;
        }
    
        Result readResult = ReadExcelUtil.readExcel(file);  //Result是封装了返回值的类,相当于实体类
    
        if(readResult.getCode() != 0){ 
            //错误:readResult.msg
            return;
        }
        List<Award> list = (List<Award>) readResult.getData(); //Award是数据库表对应的实体类 
    
        //获取了list之后,insert到数据库... 
    }

    工具类:

    ReadExcelUtil

    package com.bf.base.utils;
    
    import com.bf.base.entity.DripAward;
    import com.bf.base.params.Result;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.List;
    
    public class ReadExcelUtil {
    
        /**
         * 读取 单页sheet,返回一个集合
         * @return
         */
        public static Result<?> readDripAwardExcel(MultipartFile file) {
            Result result = new Result<>();
            InputStream is = null;
            Workbook wb = null;
            String fileName = file.getOriginalFilename();
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
    
            try {
                is = file.getInputStream();
    
                if (fileType.equals("xls")) {
                    wb = new HSSFWorkbook(is);
                } else if (fileType.equals("xlsx")) {
                    wb = new XSSFWorkbook(is);
                } else {
                    return new Result<>(Result.FAIL, "读取的不是excel文件", null, null);
                }
    
                int sheetSize = wb.getNumberOfSheets();//有多少sheet页
                if(sheetSize >= 2){
                    return new Result<>(Result.FAIL, "请核对Excel的页数", null, null);
                }
    
                Sheet sheet = wb.getSheetAt(0);
                result = sheetData2List(sheet); //关键,sheet表数据 转 集合
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return result;
        }
    
        //获取数据
        private static Result sheetData2List(Sheet sheet) {
            Result result = new Result<>();
            List<Award> awards = new ArrayList<>();
            int CELL_SIZE = 3; //excel固定三列(编码、金额)       
            int rowSize = sheet.getLastRowNum() + 1;
    
            for (int j = 0; j < rowSize; j++) { //读取每一行
                Row row = sheet.getRow(j);
                if (row == null) {
                    continue;
                }
    
                if(row.getLastCellNum() != CELL_SIZE){
                    result.setCode(2);
                    result.setMsg("第"+ j +"行数据异常,请核对后再上传!");
                    return result;
                }
    
                if (j == 0) {
                    continue;
                } else {
                    DripAward rowObj = new DripAward();
                    for (int k = 0; k < CELL_SIZE; k++) { //获取列的数据
                        Cell cell = row.getCell(k);
                        String value = getCellFormatValue(cell);
                        switch (k) {
                            case 0:
                                rowObj.setCode(AESUtil.encrypt(value));
                                break;
                            case 1:
                                rowObj.setAmount(Double.parseDouble(value));
                                break;
                            case 2:
                                rowObj.setClassify(Integer.parseInt(value));
                                break;
                            default:
                                break;
                        }
                    }
                    awards.add(rowObj);
                }            
            }
    
            result.setCode(0);
            result.setData(awards);
            return result;
        }
    
        //获取列的数据
        private static String getCellFormatValue(Cell cell) {
            String cellvalue = "";
            if (cell != null) {
                CellType cellType = cell.getCellTypeEnum();
                switch (cellType) {
                    case NUMERIC: {
                        if(String.valueOf(cell.getNumericCellValue()).indexOf("E") == -1){
                            cellvalue =  String.valueOf(cell.getNumericCellValue());
                        }else {
                            cellvalue =  new DecimalFormat("#").format(cell.getNumericCellValue());
                        }
                        break;
                    }
                    case STRING:
                        cellvalue = cell.getRichStringCellValue().getString();
                        break;
                    default:
                        cellvalue = "-";
                }
            }
    
            return cellvalue;
        }
    }

    其他:

    Result (封装了返回值的类,相当于实体类)

    package com.bf.base.params;
    
    import org.apache.commons.lang.StringUtils;
    
    /**
     * 传给前端数据的统一格式
     * code = 0时,表示调用成功
     * 其余code均表示调用接口异常,异常时,标明异常码,并给出msg和detail注释,同步文档
     */
    public class Result<T> {
        
        private int code;//状态返回码
        
        private String msg;//返回码描述
        
        private String detail;//错误详细描述或返回码对应处理方案
        
        private T data;//返回的主体数据
    
        public static final int FAIL = -1;
    
        public static final int SUCCESS = 0;
    
        @Override
        public String toString() {
            return "Result [code=" + code + ", msg=" + msg + ", detail=" + detail + ", data=" + data + "]";
        }
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public String getDetail() {
            return detail;
        }
    
        public void setDetail(String detail) {
            this.detail = detail;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
        
    }

    Award(数据库表对应的实体类)

    public class Award {
        private String code;
    
        private Double amount;
    
        private int classify;
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        public Double getAmount() {
            return amount;
        }
    
        public void setAmount(Double amount) {
            this.amount = amount;
        }
    
        public int getClassify() {
            return classify;
        }
    
        public void setClassify(int classify) {
            this.classify = classify;
        }
    }
  • 相关阅读:
    在日本被禁止的コンプガチャ設計
    Starling常见问题解决办法
    Flixel引擎学习笔记
    SQLSERVER中修复状态为Suspect的数据库
    T4 (Text Template Transformation Toolkit)实现简单实体代码生成
    创建Linking Server in SQL SERVER 2008
    Linq to Sql 与Linq to Entities 生成的SQL Script与分页实现
    Linq to Entity 的T4 模板生成代码
    在VisualStudio2008 SP1中调试.net framework 源代码
    使用HttpModules实现Asp.net离线应用程序
  • 原文地址:https://www.cnblogs.com/huashengweilong/p/11363014.html
Copyright © 2020-2023  润新知