数据库
首页 > 数据库> > 上传模板文件批量插入数据库

上传模板文件批量插入数据库

作者:互联网

小编在实习的时候,遇到了一个比较常见的需求,就是用户上传一个模板文件,里面有很多条数据,而我们要根据传入的模板文件,将模板文件里面的数据插入到数据库中。

首先我先列举一下思路:

一.拿到文件的输入流;

二.拿到得到Excel文件的workbook和sheet,用for循环去读取数据,将每一行数据插入到数据库里面;

三.读取Excel不同单元格的数值用到工具类,这个可以自己写一个;

以下的testImport(),就是通过前端拿到一个file,也就是模板文件,我们通过这个文件得到的输入流,然后进入readExcel2007()或者readExcel2003(),这个方法就是通过我们得到的输入流,再去得到模板文件的工作表和工作簿(workbook和sheet),然后将模板文件里面的每一行数据存到一个map里面,再将map插入到数据库里面,这里用到了mybatis,(我们拿到service之后去调用insert()方法,具体的就是我们将map数据按照格式存到一个实体类里面,将实体类插入到数据库里面)

    
public String testImport(HttpServletRequest request, HttpServletResponse response,MultipartFile file) throws Exception{
     if(file == null){ return "文件不见了^_^,请重新传入文件"; } String fileName = file.getName(); String suffix = file.getName().substring(fileName.lastIndexOf("."));//获取文件后缀 File targetFile = new File(fileName);//获取文件 //根据不同的excel版本,将数据插入到数据库中 //2003版的为HSSFWorkbook,2007版为XSSFWorkbook if ("xlsx".equals(suffix) || "XLSX".equals(suffix) ) { FileInputStream targetStream= new FileInputStream(targetFile); readExcel2007(targetStream);      return "导入成功^_^"; }else if("xls".equals(suffix) || "XLS".equals(suffix) ){ FileInputStream targetStream= new FileInputStream(targetFile);   readExcel2003(targetStream);   return "导入成功^_^"; }else{ return "请传入格式正确的Excel文件^_^"; } }

这里我就举例readExcel2003方法,两个方法都写出来太长了,都是差不多的,区别就在于excel的版本导致的workbook和sheet的不同。这个方法确实有点复杂,但总的来说就是拿到输入字节流,根据字节流创建excel的工作簿,然后一个for循环去读这个excel表,读取到模板文件的第一行也就是数据库的字段,这里我们将这些字段放到一个Header的map里面,这里是为了后面我们读取到真正的数据的时候,放到map里面的key为数据库的字段

    private String readExcel2003(InputStream inputStream) throws Exception {
        int sheetnum = 0, startrow = 0, startcol = 0, errorRow = 0;
        try {
            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
            HSSFSheet sheet = workbook.getSheetAt(sheetnum); // sheet 從0開始
            int rowNum = sheet.getLastRowNum() + 1; // 取得最後一行的行號
            Map<String, Object> Header = new HashMap<String, Object>(); // 表頭的下標和內容
            for (int i = startrow; i < rowNum; i++) { // 行循環開始
                Map<String, String> map = null;// 每一行數據的map
                HSSFRow row = sheet.getRow(i); // 行
                if (row == null)
                    break; // 中間如果有空行,則退出
                int lastCellNum = row.getLastCellNum(); // 每行的最後一個單元格位置
                if (i != 0) {// 記錄數據的行號
                    map = new HashMap<String, String>();
                    map.put("lineNumber", i + "1");
                }
                for (int j = startcol; j < lastCellNum; j++) { // 列循環開始
                    HSSFCell cell2 = row.getCell(j);
                    String cellValue = getCellValue2003(cell2);
                    if (i == 0) {
                        switch (cellValue){
                        case "id": Header.put(j + "", "id"); break;
                        case "交易日期": Header.put(j + "", "tradeDate"); break;
                        case "公司名称": Header.put(j + "", "companyName"); break;
                        case "开户银行名称": Header.put(j + "", "bankAccountName"); break;
                        case "开户银行账户": Header.put(j + "", "bankAccountNo"); break;
                        case "唯一流水号": Header.put(j + "", "serialNumber"); break;
                        case "对方账户名称": Header.put(j + "", "sideAccountName"); break;
                        case "对方账户": Header.put(j + "", "sideAccount"); break;
                        case "收入": Header.put(j + "", "income"); break;
                        case "摘要": Header.put(j + "", "digest"); break;
                        case "已核销额度": Header.put(j + "", "haveVerLines"); break;
                        case "未核销额度": Header.put(j + "", "notVerLines"); break;
                        case "退款": Header.put(j + "", "refund"); break;
                        case "项目类别": Header.put(j + "", "projectCategory"); break;
                        case "核销状态": Header.put(j + "", "verState"); break;
                        case "代付标识": Header.put(j + "", "paidLogo"); break;
                        case "新台账标识": Header.put(j + "", "newLedgerLogo"); break;
                        }
                    } else {
                        map.put((String) Header.get(j + ""), cellValue);
                    }
                }
                // 每一行數據的過濾,如果一行中所有列都爲null,則不生成該行數據,
                if (null != map) {
                    Collection<String> values = map.values();
                    Set<String> keySet = map.keySet();
                    long count2 = keySet.stream().filter(o -> !o.equals("lineNumber")).count();// 總條數
                    long count = values.stream().filter(o -> null == o).count();// 爲空的條數
                    if (count < count2) {
                        SubcarBankStatement subcarBankStatement = new SubcarBankStatement();
                        subcarBankStatement.setId(map.get("id"));//遇到日期格式,需要转换格式,不然插入数据库时会报错
                        String tradeDate =map.get("tradeDate");
                        DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
                        subcarBankStatement.setTradeDate(formater.parse(tradeDate));
                        
                        subcarBankStatement.setCompanyName(map.get("companyName"));
                        subcarBankStatement.setBankAccountName(map.get("bankAccountName"));
                        subcarBankStatement.setBankAccountNo(map.get("bankAccountNo"));
                        subcarBankStatement.setSerialNumber(map.get("serialNumber"));
                        subcarBankStatement.setSideAccountName(map.get("sideAccountName"));
                        subcarBankStatement.setSideAccount(map.get("sideAccount"));
                        subcarBankStatement.setIncome(map.get("income"));
                        subcarBankStatement.setDigest(map.get("digest"));
                        subcarBankStatement.setHaveVerLines(map.get("haveVerLines"));
                        subcarBankStatement.setNotVerLines(map.get("notVerLines"));
                        subcarBankStatement.setRefund(map.get("refund"));
                        subcarBankStatement.setProjectCategory(map.get("projectCategory"));
                        subcarBankStatement.setVerState(map.get("verState"));
                        subcarBankStatement.setPaidLogo(map.get("paidLogo"));
                        subcarBankStatement.setNewLedgerLogo(map.get("newLedgerLogo"));
                        subcarBankStatementService.insert(subcarBankStatement);
                    }
                }
            }
            workbook.close();
        } catch (Exception e) {
            throw e;
        }
        return "success";
    }

 下面的这个是根据excel的不同单元格格式拿到对应的数值,很简单的方法。

    private String getCellValue2003(HSSFCell cell) {
         String cellvalue = null;  
            if (cell != null) {  
                // 判斷當前Cell的Type  
                switch (cell.getCellType()) {  
                // 如果當前Cell的Type爲NUMERIC  
                case NUMERIC: {  
                    short format = cell.getCellStyle().getDataFormat();  
                    if(format == 14 || format == 31 || format == 57 || format == 58){   //excel中的時間格式  
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");    
                        double value = cell.getNumericCellValue();    
                        Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);    
                        cellvalue = sdf.format(date);    
                    }  
                    // 判斷當前的cell是否爲Date  
                    else if (HSSFDateUtil.isCellDateFormatted(cell)) {  //先註釋日期類型的轉換,在實際測試中發現HSSFDateUtil.isCellDateFormatted(cell)只識別2014/02/02這種格式。  
                        // 如果是Date類型則,取得該Cell的Date值           // 對2014-02-02格式識別不出是日期格式  
                        Date date = cell.getDateCellValue();  
                        DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");  
                        cellvalue= formater.format(date);  
                    } else { // 如果是純數字  
                        // 取得當前Cell的數值  
                        cellvalue = NumberToTextConverter.toText(cell.getNumericCellValue());   
                          
                    }  
                    break;  
                }  
                // 如果當前Cell的Type爲STRIN  
                case STRING:  
                    // 取得當前的Cell字符串  
                    cellvalue = cell.getStringCellValue().replaceAll("'", "''");  
                    break;  
                case  BLANK:  
                    cellvalue = null;  
                    break;  
                // 默認的Cell值  
                default:{  
                    cellvalue = "";  
                }  
                }  
            } else {  
                cellvalue = "";  
            }  
            return cellvalue;  
        }

 上面的工程可能有点复杂,如果还有不懂的小兄弟可以加我qq联系我,或者直接发邮箱给我(674085128)

标签:case,map,break,Header,put,subcarBankStatement,文件批量,上传,模板
来源: https://www.cnblogs.com/carryup/p/13542180.html