java後臺讀取/解析 excel表格

需求描述

前臺須要上傳excel表格,提交到後臺,後臺解析並返回給前臺,展現在前臺頁面上!html

前臺部分代碼與界面

<th style="padding: 7px 1px;width:150px;height: 43px;">excel導入推送人:</th>
                <td>
                    <input id="file01" type="file" class="width_250" name="file">

                    <button class="button button-highlight button-pill  button-large" onclick="fileUpload()">肯定導入<i
                            class="fa fa-plus"></i></button>
                </td>
//文件上傳事件
function fileUpload(){
    var fileName = $("#file01").val();  
     if(isEmpty(fileName)){
         showTips("請選擇文件");  
        $("#file01").focus();
        return false;  
     }
     if(fileName.lastIndexOf(".")!=-1){
        var fileType = (fileName.substring(fileName.lastIndexOf(".")+1,fileName.length)).toLowerCase();  
        var suppotFile = new Array();  
        suppotFile[0] = "xls";  
        suppotFile[1] = "xlsx";
        if($.inArray(fileType, suppotFile)<0){
            showTips("不支持文件類型"+fileType);  
            return false;
            }
     }else{
         showTips("文件只支持xls,xlsx");
          return false;
     }
     console.log('xxxxxxxx')
     showLoading();
     
    $.ajaxFileUpload({
        url : getRootPath()+'/addUserPush/fileupload.do',           //用於文件上傳的服務器端請求地址
        secureuri : false,                                          //是否啓用安全提交,默認爲false。
        fileElementId : 'file01',                                   //須要上傳的文件域的ID,即<input type="file">的ID
        dataType : 'text',                                          //服務器返回的數據類型。能夠爲xml,script,json,html。若是不填寫,jQuery會自動判斷。
        //data:param,                                               //自定義參數。
        success : function(data) {  
            console.log(data);
            //提交成功後自動執行的處理函數,參數data就是服務器返回的數據。
            closeLoading();
            console.log(data.result);
            //var userList = eval('('+data.result+')');  此方法沒法轉成 json
            var userList = $.parseJSON(data).result;
                            
            if(typeof userList=='string') {//userList instanceof Array ---> 攔不住
                showTips(userList);
                return;
            }else {
                //遍歷 userList
                //屢次導入 
                var len = $('#userInfo tr').length-1;
                for(var i = 0; i < userList.length; i++){
                    //賦值給頁面下方
                    userList[i].no = len+ i+1;
                    
                    addTr2('userInfo', -1,userList[i]);
                }
            }
        },
        error : function(data) {                            //提交失敗自動執行的處理函數。
            closeLoading();
            console.log(data);
            showTips("系統繁忙!");
            
            $("#confirm").bind('click',function(){
                validate();
            });
            return;
        }
        
    });
    
    return false;       //用於避免重複提交
}

界面大概張這樣

後端接收此excel並解析,返回json格式數據給前臺!代碼以下:

public class ReadExcel4UPUtils {

    public ReadExcel4UPUtils() {
        throw new IllegalAccessError("工具類不能經過構造器初始化!");
    }

    /**
     * @Description 將MultipartFile -> File
     * @param file
     * @return resultMap
     * @author kangkai on 18/04/03
     */
    public static Map<String, Object> readMultipartFile(MultipartFile file)throws IOException {
        InputStream input = file.getInputStream();

        String path = ApplicationPropertiesUtil.getProperty("excel.inputRoot");
        File folder = new File(path);
        if(!folder.exists()){
            folder.mkdirs();
        }

        String tmpFileName = path +"/_" + UUID.randomUUID().toString() + "." + FilenameUtils.getExtension(file.getOriginalFilename());
        File tmpFile = new File(tmpFileName);
        FileOutputStream output = null;
        try {
            output = new FileOutputStream(tmpFile);
            int n = 0;
            try {
                while((n=input.read()) != -1){
                    output.write(n);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally{
            output.close();
            input.close();
        }
        return readFile(tmpFile);
    }

    /**
     * @Description 讀取文件
     * @param file
     * @return resultMap
     * @author kangkai on 18/04/03
     */
    public static Map<String,Object> readFile(File file){
        Map<String,Object> resultMap = new HashMap<String, Object>();
        List<UserPushSave.UserInfo> userList = new ArrayList<UserPushSave.UserInfo>();
        String error = "";
        int num =0;
        /**------------- 第一步 將file文件解析爲對象 ---------------*/
        String fileName = file.getName();
        //根據表格不一樣結尾,不一樣方式獲取 Workbook
        Workbook wb = null;
        try {
            wb = fileName.endsWith("xlsx")? new XSSFWorkbook(new FileInputStream(file)):new HSSFWorkbook(new FileInputStream(file));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        userList = readExcel4user(wb);
        num = (null != userList)? userList.size():0;
        //行數
        int _index;
        //**------------- 第二步 逐條對數據進行校驗 ---------------*//*
        if (num>0) {
            for (int i = 0; i < num; i++) {
                String result = checkUser(userList.get(i));
                _index = i +1;
                if (null != result) {
                    error = "第"+_index+"行   "+result+"  上傳失敗!";
                    resultMap.put("result", error);
                    //** 保存操做信息 *//*
                    return resultMap;
                }else {
                    continue;
                }
            }
        }else {
            resultMap.put("result", "導入數據不能爲空!");
            return resultMap;
        }
        resultMap.put("result",userList);
        return resultMap;

    }

    /**
     * @Description 解析數據
     * @param wb
     * @return userList
     * @author kangkai on 18/04/03
     */
    public static List<UserPushSave.UserInfo> readExcel4user(Workbook wb){
        //返回結果list
        List<UserPushSave.UserInfo> result = new ArrayList<UserPushSave.UserInfo>();
        //表格數據
        List<List<String>> excelData = new ArrayList<List<String>>();
        Workbook workbook = wb;
        //workbook                                                  //這種方式 Excel 2003/2007/2010 都是能夠處理的
        Sheet sheet = workbook.getSheetAt(0);               //目前只處理第一個sheet
        int rowCount = sheet.getPhysicalNumberOfRows();             //獲取總行數
        for (int r = 1; r < rowCount; r++) {                        //從第2行開始遍歷,第一行爲表頭忽略掉
            if (sheet.getRow(r) == null) {
                continue;
            }else {
                Row row = sheet.getRow(r);
                int cellCount = row.getPhysicalNumberOfCells();     //獲取當前行總列數
                //遍歷每一列
                List<String> tempList = new ArrayList<String>();            //存儲每一行的解析數據
                cellCount = 5;                                      //因爲模板中運行存在爲空的字段,因此強制設爲長度5
                for (int c = 0; c < cellCount; c++) {
                    //獲取第 c 列
                    Cell cell = row.getCell(c);
                    String cellValue = "";
                    if (cell != null) {
                        cell.setCellType(Cell.CELL_TYPE_STRING);        //這裏將每一個字段都指定爲string類型
                        cellValue = getCellValue(cell);
                    }else {
                        cellValue = "";
                    }
                    tempList.add(cellValue);    //存儲excel中每一行解析後的數據
                }
                excelData.add(tempList);
            }//存儲excel解析後的數據
        }
        //將解析後的數據封裝爲對象
        for(List<String> dataList : excelData) {
            List<String> propertyList = getPropertyName(com.cpic.ttkh.server.vo.push.UserPushSave.UserInfo.class);

            List<String> setList = new ArrayList<String>();
            for(String s :propertyList){
                setList.add(getProperty("set",s));
            }
            int count_property = propertyList.size();
            //定義記錄字段爲空個數
            int count_empty = 0;
            UserPushSave.UserInfo user = new UserPushSave.UserInfo();
            for(int i = 0;i < count_property;i++) {
                count_empty = 0;
                Method m = null;
                try {
                    m = user.getClass().getDeclaredMethod(setList.get(i),String.class);
                } catch (SecurityException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    String column = dataList.get(i);
                    if("".equals(column)) {
                        count_empty += 1;
                    }else {
                        //去下空格
                        column.trim();
                    }
                    m.invoke(user,column);
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
            //所有字段都是空,不添加
            if(count_empty != count_property) {
                result.add(user);
            }else {continue;}
        }
        return result;
    }
    /**
     * @Title: getCellValue
     * @Description: 獲取excel單元格數據
     * @author: huitong.xia   2016年4月12日 下午1:13:28
     * @param cell
     * @return String
     * @throws
     */
    private static String getCellValue(Cell cell){
        int cellType = cell.getCellType();
        String cellValue = null;
        switch(cellType) {
            case Cell.CELL_TYPE_STRING: //文本
                cellValue = cell.getStringCellValue();
                break;
            case Cell.CELL_TYPE_NUMERIC: //數字、日期
                cellValue = String.valueOf(cell.getNumericCellValue()); //數字
                break;
            case Cell.CELL_TYPE_BOOLEAN: //布爾型
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_BLANK: //空白
                cellValue = cell.getStringCellValue();
                break;
            case Cell.CELL_TYPE_ERROR: //錯誤
                cellValue = "";
                break;
            case Cell.CELL_TYPE_FORMULA: //公式
                cellValue = "";
                break;
            default:
                cellValue = "";
        }
        return cellValue;
    }


    /**
     * @Description:校驗各個字段非空與是否合法
     * @author: kangkai
     * @param user
     * @return message or null
     */
    private static String checkUser(UserPushSave.UserInfo user){

        // 中國公民身份證格式:長度爲15或18位,最後一位能夠爲字母
        Pattern idNumPattern = Pattern.compile("(\\d{14}[0-9a-zA-Z])|(\\d{17}[0-9a-zA-Z])");
        //獲取全部屬性
        List<String> getList = new ArrayList<String>();
        List<String> propertyList = getPropertyName(com.cpic.ttkh.server.vo.push.UserPushSave.UserInfo.class);
        for(String s :propertyList) {
            getList.add(getProperty("get",s));
        }
        Method m = null;
        for(int i = 0,size = getList.size();i < size;i++) {
            try {
                m = user.getClass().getDeclaredMethod(getList.get(i));
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            String column = "";
            try {
                column = (String)m.invoke(user);
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if(i == 0 && "".equals(column)) {
                return "推送人姓名爲空";
            }
            if(i == 2 && !idNumPattern.matcher(column).matches()) {
                return "證件號格式不正確";
            }
            if(i == 4 && "".equals(column)) {
                return "推送內容爲空";
            }
        }
        return null;        //用戶驗證合法
    }
    /**
     * Description:根據類名 獲取其全部屬性名
     * @param clazz
     * @return stringList
     */
    private static List<String> getPropertyName(Class<?> clazz) {
        Field[] fds = {};
        fds = clazz.getDeclaredFields();
        List<String> stringList = new ArrayList<String>();
        for(Field f : fds) {
            stringList.add(f.getName());
        }
        return stringList;
    }

    /**
     * Description:根據屬性名 獲取其get/set方法
     * @param propertyName
     * @return stringList
     */
    private static String getProperty(String getOrSet,String propertyName) {
        StringBuilder sb = new StringBuilder("");
        //構造set方法:加set 屬性名首字母大寫
        //第一個字母 大寫
        char[] c = propertyName.toCharArray();
        if (c[0] >= 'a' && c[0] <= 'z') {
            c[0] = (char) (c[0] - 32);
        }else {
            throw new BusinessException("屬性名異常");
        }
        sb.append(getOrSet).append(new String(c));
        String propertySet = sb.toString();
        return propertySet;
    }
}

關於上方代碼

  • 解析MultipartFile類型,轉成File;
  • readFile方法讀取,獲取Workbook,而且對返回的數據校驗;
  • readExcel4user方法解析到了全部數據,並返回實體list;
  • 流程大概就是這個樣子,具體使用應結合校驗規則與表格中數據形式 進行重寫;
  • 最後,代碼基於jdk1.6 。
相關文章
相關標籤/搜索