zoukankan      html  css  js  c++  java
  • java后台读取/解析 excel表格

    需求描述

    前台需要上传excel表格,提交到后台,后台解析并返回给前台,展示在前台页面上!

    前台部分代码与界面

    <th style="padding: 7px 1px;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 。
  • 相关阅读:
    C#与数据库访问技术总结(十一)之数据阅读器(DataReader)1
    C#与数据库访问技术总结(十)之添加&删除
    C#与数据库访问技术总结(九)之实例
    C#与数据库访问技术总结(八)之ExecuteNonQuery方法
    C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例
    C#与数据库访问技术总结(七)综合示例
    C#与数据库访问技术总结(五)之Command对象的常用方法
    OS——进程简答题(1)
    LAMP/LNMP 一键安装脚本
    运维如何延续自己的职业生涯--萧田国2017年GOPS深圳站演讲内容
  • 原文地址:https://www.cnblogs.com/kangkaii/p/8793942.html
Copyright © 2011-2022 走看看