zoukankan      html  css  js  c++  java
  • 【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;
        }
    }
  • 相关阅读:
    Effective C++_笔记_条款00_基本术语
    SVM(三)—Kernels(核函数)
    SVM(支持向量机)(二)—Lagrange Duality(拉格朗日对偶问题)
    Logistic Regression(逻辑回归)(二)—深入理解
    java程序验证用户名密码和验证码登录的小例子
    java连接MySQL数据库并读取内容
    一个简单的模板了解css+div网页布局
    HTML文件中css样式的引用
    慕课笔记利用css进行布局【混合布局练习】
    慕课笔记利用css进行布局【混合布局】
  • 原文地址:https://www.cnblogs.com/huashengweilong/p/11363014.html
Copyright © 2011-2022 走看看