java上傳excel到後臺解析入庫

背景:最近須要作一個excel模板導入的功能,以便用戶能夠本身增刪改查數據,固然,只有特別的用戶纔能有此權限,捋了捋思路,仍是從前端寫起前端

實現:c++

  頁面最後的效果以下,能夠本身修改,刪除,導入導出數據,爲了統一規範,防止數據不規範解析不了,模板由咱們提供下載,用戶填充數據統一導入,ajax

 涉及到機密,打碼請見諒。sql

  

 頁面主要我分爲三大塊功能,json

  一是分權分域,只有特定的用戶才能導入修改,刪除,添加數據,這個看你怎麼保存當前用戶,驗證下用戶權限等,這裏不作過多闡述:數組

  二是數據的查詢,導出,由於以前作的幾乎都有這兩個功能,因此集成過來,須要看導出代碼的能夠看我以前的博客參考;app

  三是數據導入,修改,刪除,添加和模板的下載,這裏主要說模板下載和導入數據的解析工具

  模板下載這塊,前端用的按鈕點擊事件,window.location.href指定到後臺路徑,後臺模板下載方法代碼以下:post

  

public static void getTemplate(HttpServletRequest request, HttpServletResponse response,String filename) throws IOException {

        String path = TEMPLATE_PATH + filename;
        File file = new File(path);

        if(!file.exists()){
            return;
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename="+ new String(filename.getBytes("utf-8"), "ISO-8859-1"));
        BufferedInputStream bi = new BufferedInputStream(new FileInputStream(file));
        OutputStream os = response.getOutputStream();

        byte[] bytes = new byte[1024];
        int i = bi.read(bytes);
        while (i != -1){
            os.write(bytes, 0, i);
            i = bi.read(bytes);
        }
        if (bi != null) {
            try {
                bi.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

這裏path我指定了一個位置來放模板下載的文件,由於模塊較多,因此按照名稱下載,url

 

導入模板,前端代碼以下:

<li class='item'>
                    <input type="button" class="button" id="uploading" value="導入">
                </li>
                <li class='item'>
                    <input type="file" id="file1">
                </li>

兩個按鈕,導入的按鈕綁定click事件,裏面只驗證了文檔的格式是否是excel,使用FormData對象做爲data上傳,FormData對象用以將數據編譯成鍵值對,以便用XMLHttpRequest來發送數據,後臺使用MultipartFile對象接收:

click事件以下:

ExportIn: function () {
                if($("#file1").val().length <=0){
                    alert("請選擇文件");
                    return false;
                }else{
                    var filepath = $("#file1").val();
                    var extStart = filepath.lastIndexOf(".");
                    var ext = filepath.substring(extStart,filepath.length).toUpperCase();
                    if (ext != ".XLSX" && ext != ".XLS" && ext != ".XLSM") {
                        alert("請上傳excel格式文檔");
                        return false;
                    }
                }
                //獲取到上傳的文件信息
                var data =document.getElementById("file1").files[0];
                var fromData = new FormData();

                if(data != null){
                    fromData.append("file",data);
                    $.ajax({
                        type: "post",
                        url: dss.rootPath + "plugin/labourCompetition/NpsCompetitionScore_mobile_uploading",
                        data: fromData,
                        dataType: "json",
                        contentType: false,
                        processData: false,
                        beforeSend: function () {
                            dss.load(true);
                        },
                        complete: function () {
                            dss.load(false);
                        },
                        success: function (data) {
                            if (data.status != "OK") {
                                alert(data.status);
                            }
                            else if (data.status == "OK") {
                                alert("導入成功!");
                            }
                            window.location.reload();
                        }
                    });
                }
                },

 

    後臺使用MultipartFile 接收,綁定了前端的file參數,驗證文件是否爲空,而後判斷文件格式,是xls仍是xlsx格式,建立對應的對象解析,而後把數據存到list<String[]>中,

一行爲一個string數組,由於解析模板要複用,還有驗證不爲空,日期格式等因此有些地方寫的很麻煩,能夠用簡單的辦法解決,可是又不能影響複用的模塊,因此個人處理可

能麻煩了點,各位能夠按照自己的需求來。

 

 後臺接收的方法以下:

@RequestMapping("plugin/labourCompetition/NpsCompetitionScore_mobile_uploading")
    @ResponseBody
    public JsonData importTemplate(@RequestParam(value = "file")MultipartFile file) throws Exception {
        JsonData jsonData = new JsonData();

        Boolean bool = ImportExcel.checkFile(file);
        if(!bool){
           jsonData.setStatus("文件類型不正確或爲空");
           return jsonData;
        }
      //工具類在下面
        HashMap<String, ArrayList<String[]>> hashMap = ImportExcel.analysisFile(file);
        ArrayList<String[]> arrayList = hashMap.get("OK");
        if(arrayList == null){
            Set<String> strings = hashMap.keySet();
            String next = strings.iterator().next();
            jsonData.setStatus(next);
            return jsonData;
        }


        //數據都在arrayList中,循環入庫,記得最後一個字段加上loadTime
        ConnectSettings dwConnect = commUtil.getDwConnect();
        String sql = " INSERT INTO 表名  values ";

        String nowDate = ImportExcel.getNowDate();
        for(int n = 0;n < arrayList.size();n++){
            String[] str = arrayList.get(n);
            sql += " ( ";
            for(int num =0;num<str.length;num++){
                sql += "'" +str[num]+"',";
                if(num == str.length-1){
                    sql += "to_date('"+nowDate+"','yyyy-mm-dd hh24:mi:ss')";
                }
            }
            if( n != arrayList.size()-1 ){
                sql += " ),";
            }else{
                sql += " )";
            }
        }

        System.err.println(sql);

        int i = DbHelper.executeNonQuery(sql, dwConnect);
        System.err.println("成功執行行數"+i);

        if(i < 1){
            jsonData.setStatus("導入失敗");
            return jsonData;
        }
        jsonData.setStatus("導入成功");
        return jsonData;
    }
@Component
public class ImportExcel {

    private static Calendar calendar = Calendar.getInstance();

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月");
    private static SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    private static SimpleDateFormat simpleDateFormat3 = new SimpleDateFormat("yyyy/MM/dd");


    //解析excel文件
    public static HashMap<String, ArrayList<String[]>> analysisFile(MultipartFile file) throws IOException {
        HashMap<String, ArrayList<String[]>> hashMap = new HashMap<>();
        //獲取workbook對象
        Workbook workbook = null;
        String filename = file.getOriginalFilename();
        InputStream inputStream = file.getInputStream();
        //根據後綴名是否excel文件
        if(filename.endsWith("xls")){
            //2003
            workbook = new HSSFWorkbook(inputStream);
        }else if(filename.endsWith("xlsx")){
            //2007
            workbook = new XSSFWorkbook(inputStream);
        }

        //建立對象,把每一行做爲一個String數組,因此數組存到集合中
        ArrayList<String[]> arrayList = new ArrayList<>();
        if(workbook != null){
            //循環sheet,如今是單sheet
            for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){
                //獲取第一個sheet
                Sheet sheet = workbook.getSheetAt(sheetNum);
                if(sheet == null){
                    hashMap.put("文件sheet爲空!",arrayList);
                    return hashMap;
                }
                //獲取當前sheet開始行和結束行
                int firstRowNum = sheet.getFirstRowNum();
                int lastRowNum = sheet.getLastRowNum();
                //循環開始,除了前兩行
                for(int rowNum = firstRowNum + 2;rowNum <= lastRowNum;rowNum++){
                    //獲取當前行
                    Row row = sheet.getRow(rowNum);
                    //獲取當前行的開始列和結束列
                    short firstCellNum = row.getFirstCellNum();
                    short lastCellNum = row.getLastCellNum();

                    //獲取總行數
                    int lastCellNum2 = row.getPhysicalNumberOfCells();
                    String[] strings = new String[lastCellNum2];
                    //循環當前行
                    for(int cellNum = firstCellNum;cellNum < lastCellNum;cellNum++){
                        Cell cell = row.getCell(cellNum);
                        if( cell == null || "".equals(cell) || cell.getCellType()== Cell.CELL_TYPE_BLANK ){
                            hashMap.put("第"+(rowNum+1)+"行,第"+(cellNum+1)+"列爲空",arrayList);
                            return hashMap;
                        }
                        String  cellValue = "";
                        cellValue = getCellValue(cell);
                        strings[cellNum] = cellValue;
                    }
                    arrayList.add(strings);

                }
            }
        }
        inputStream.close();
        hashMap.put("OK",arrayList);
        return hashMap;
    }

    //把每個cell轉換爲string
    public static String getCellValue(Cell cell){
        String cellValue = "";
        if(cell == null){
            return cellValue;
        }
        //把數字轉換成string,防止12.0這種狀況
        if(cell.getCellType() == cell.CELL_TYPE_NUMERIC){
            cell.setCellType(cell.CELL_TYPE_STRING);
        }
        //判斷數據的類型
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_NUMERIC: //數字0
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            case Cell.CELL_TYPE_STRING: //字符串1
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case Cell.CELL_TYPE_BOOLEAN: //Boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA: //公式
                //cellValue = String.valueOf(cell.getCellFormula());
                try {
                    cellValue = String.valueOf(cell.getNumericCellValue());
                } catch (IllegalStateException e) {
                    cellValue = String.valueOf(cell.getRichStringCellValue());
                }
                break;
            case Cell.CELL_TYPE_BLANK: //空值
                cellValue = "";
                break;
            case Cell.CELL_TYPE_ERROR: //故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知類型";
                break;
        }
        return cellValue;
    }

    //判斷row是否爲空
    public static boolean isRowEmpty(Row row) {
        for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
            Cell cell = row.getCell(c);
            if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK) {
                return false;
            }
        }
        return true;
    }

    //檢查文件類型
    public static Boolean checkFile(MultipartFile file){
        //檢查文件是否爲空
        boolean empty = file.isEmpty();
        if(empty || file == null){
            return  false;
        }
        //檢查文件是不是excel類型文件
        String filename = file.getOriginalFilename();
        if(!filename.endsWith("xls") && !filename.endsWith("xlsx")){
            return false;
        }
        return true;
    }

    //轉換excel導入以後時間變爲數字,月時間
    public static String getCorrectMonth(int i){
        calendar.set(1900,0,1);
        calendar.add(calendar.DATE,i);
        Date time = calendar.getTime();
        String s = simpleDateFormat.format(time);
        return s;
    }

    //轉換excel導入以後時間變爲數字,年月日時間
    public static String getCorrectDay(int i){
        calendar.set(1900,0,-1,0,0,0);
        calendar.add(calendar.DATE,i);
        Date time = calendar.getTime();
        String s = simpleDateFormat3.format(time);
        return s;
    }

    //獲取當前時間的字符串
    public static String getNowDate(){
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(date);
        return format;
    }


    //文件讀取到指定的位置
    public String saveFile(MultipartFile file) throws IOException {
        MultipartFile update = file;
        //文件中參數名字
        String name = update.getName();
        //文件名字
        String originalFilename = update.getOriginalFilename();
        //是否爲空
        boolean empty = update.isEmpty();
        //傳輸文件到指定路徑中
        String path = "F://LDJS/boco/uploading/"+originalFilename;
        update.transferTo(new File(path));
        //文件類型
        String contentType = update.getContentType();
        InputStream inputStream = update.getInputStream();
        inputStream.close();
        //是否存在此路徑
        boolean path1 = new File(path).exists();
        if(path1){
            return "OK";
        }else{
            return "導入文件失敗";
        }

    }

    //顯示時間,把數字轉換成時間類型的
    public static String getExcelDate(Cell cell){
        Date dateCellValue = cell.getDateCellValue();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(dateCellValue);
        return format;
    }


    public static String getDetailDate(String date){
        int dayNum = (int)Double.parseDouble(date);

        String s1 = "0."+ date.split("\\.")[1];
        String hour = Double.parseDouble(s1)*24 +"";
        int hourNum = Integer.parseInt(hour.split("\\.")[0]);

        String s2 = "0."+ hour.split("\\.")[1];
        String minte = Double.parseDouble(s2)*60 +"";
        int minteNum = Integer.parseInt(minte.split("\\.")[0]);

        String s3 = "0."+ minte.split("\\.")[1];
        String second = Double.parseDouble(s3)*60 +"";
        int secondNum = Integer.parseInt(second.split("\\.")[0]);
        calendar.set(1900,0,-1,0,0,0);
        calendar.add(calendar.DATE,dayNum);
        calendar.add(calendar.HOUR,hourNum);
        calendar.add(calendar.MINUTE,minteNum);
        calendar.add(calendar.SECOND,secondNum);
        Date time = calendar.getTime();
        String s = simpleDateFormat2.format(time);
        return s;
    }

    //檢查是不是數字
    public static Boolean checkWhetherNumber(String str){
        try {
            BigDecimal bigDecimal = new BigDecimal(str);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    //檢查是否是時間類型
    public static Boolean checkWhetherDate(String str){
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            // 設置lenient爲false. 不然SimpleDateFormat會比較寬鬆地驗證日期,好比2007/02/29會被接受,並轉換成2007/03/01
            simpleDateFormat.setLenient(false);
            simpleDateFormat.parse(str);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    //檢查是否是時間類型
    public static Boolean checkWhetherDate2(String str){
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
            simpleDateFormat.setLenient(false);
            simpleDateFormat.parse(str);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    //檢查是否是月的時間類型
    public static Boolean checkWhetherMonth(String str){
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月");
            simpleDateFormat.setLenient(false);
            simpleDateFormat.parse(str);
        }catch (Exception e){
            return false;
        }
        return true;
    }




}
相關文章
相關標籤/搜索