layui+poi-Java实现导入导出excel文件

layui+poi-Java实现导入导出excel文件,第1张

layui+poi-Java实现导入导出excel文件 目录

需求说明

一、实现思路

二、前端代码

1.引入layui

2.隐藏部分内容

1)静态页面代码:

2)js(/jquery)代码:点击【导入xx】按钮的js:d出上面隐藏的内容

3)、效果如下

3、下载模板js

4、选择文件、上传js 

 三、后端代码

1、下载模板:

2、导入文件 

1)controller层

2)处理文件工具类

3)后端校验文件格式的方法

4)校验表格标题行方法

5)将excel格子中的内容转为java的string类型的方法 

6)判断列标题头是否正确

 7)校验数据是否为空

8)校验是否为纯数字 :心机boy的方法

9)做业务逻辑处理(保存数据)

总结


需求说明

项目背景:springmvc架构下,前端jsp(引入layui框架样式)需要实现导出excel文件(模板),用户填写内容后,再上传进系统,系统解析保存excel文件中的数据。


一、实现思路

1、【模板制作】提前做好一个excel文件,可以用Excel自带的功能限制单元格的格式:例如某列只允许填写纯数字,某列不允许为空等等,以便用户填写错误。

2、【导出模板】把模板放到项目中,前端请求后,后端直接下载模板。

3、【导入】使用layui框架实现前端,java后端读取excel文件,POI框架 *** 作文件,验证数据正确性等。

二、前端代码 1.引入layui
2.隐藏部分内容

有一d窗,点击【导入xx】按钮之前不显示。点击【导入xx】按钮后d出:

1)静态页面代码:

	
			
		
		
	
2)js(/jquery)代码:点击【导入xx】按钮的js:d出上面隐藏的内容
        function upload(){
			 layer.open({
	                type: 1,
	                area: ['800px','150px'],
	                fixed: false,
	                title: '导入数据',
	                content: $("#showUploadExcelDiv"),
	                end: function () {
	                    location.reload();
	                }
	            })
		}
3)、效果如下

 

3、下载模板js
function downloadTemplate(){
    //后端下载地址
    location.href="${xxx}/xxx/yyy/downloadTemplate";
}
4、选择文件、上传js 
	

效果展示:


 三、后端代码 1、下载模板:
    
	@RequestMapping(value = "downloadTemplate")
	public void downloadTemplate(HttpServletResponse response) throws Exception {
        //获取项目中模板为输入流
		InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("templates/xxx/yyyy/DetailTemp.xlsx");
        //利用poi框架导出文件
        //org.apache.poi.xssf.usermodel.XSSFWorkbook;
		XSSFWorkbook wb0 = new XSSFWorkbook(is);
		try {
			OutputStream out = response.getOutputStream();
			response.setHeader("Content-disposition", "attachment;filename="+ new String( "导入成本明细清单模板.xlsx".getBytes("gb2312"), "ISO8859-1" ));
			response.setContentType("application/msexcel;charset=UTF-8");
			wb0.write(out);
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
2、导入文件  1)controller层
	
	@RequestMapping(value = "importExcel", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public HashMap importData(@RequestPart(value = "file") MultipartFile file,HttpServletRequest request) {
		
		//获取导入时传来的参数:可做业务处理:略
		String year = request.getParameter("year");
		String id = request.getParameter("id");
		
        //构建返回前端值,此处使用HashMap
        //其中key为code value为1代表成功,value为0代表失败
        //   key为msg,value写入具体错误信息是什么
		HashMap resultMap = null;
		try {
    		InputStream inputStream = file.getInputStream();
            //写个工具类,处理excel 的校验、保存:返回值直接是可以对接前端的
            resultMap = util.readExcel(inputStream, file.getOriginalFilename(),new XXXEntity());
            inputStream.close();
            return resultMap;
		} catch (Exception e) {
			System.out.print("[导入异常]"+e.getMessage());
			resultMap.put("code", "0");
			resultMap.put("msg", "读取文件异常!");
			return resultMap;
	    }
    }
2)处理文件工具类
@Service
public class ExcelUtilForXXXimport {
	private static final Logger logger = LoggerFactory.getLogger(ExcelUtilForXXXimport.class);

	@Autowired
	private XXXEntityService xxxEntityService;
	
	
    public HashMap readExcel(InputStream in, String fileName,XXXEntity xxxEntity) throws Exception {
        //构建返回值
    	HashMap hashMap=new HashMap();
        //创建Excel工作薄
        try {
        	//判断文件格式是否为excel,是否为空
            //详见:3)后端校验文件格式的方法
        	Workbook work = getWorkbook(in, fileName);
            if (null == work) {
                throw new Exception("创建Excel工作薄为空!");
            }

            //读第一页
            Sheet sheet = work.getSheetAt(0);

            //step1: 验证导入文件的标题头是否合法
    		String[] columnName = {"序号", "月份",...};
            //详见 : 4)校验表格标题行方法
    		String resultString=verificationExcelHeadLine(sheet, columnName);
            //有返回信息代表有错误,没有返回信息代表验证通过
    		if (!resultString.equals("")) {
    			hashMap.put("code", "0");
    			hashMap.put("msg", "请使用正确模板上传excel文件。"+resultString);
    			return hashMap;
    		}

    		//step2: 验证导入文件的标题 列 是否合法
    		String[] colName = {"第一月", "第二月",。。。};
            //详见: 6)判断列标题头是否正确
    		String resultStr = verificationExcelHeadLineTwo(sheet, colName);
            //有返回信息代表有错误,没有返回信息代表验证通过
    		if (!resultStr.equals("")) {
    			hashMap.put("code", "0");
    			hashMap.put("msg", "请使用正确模板上传excel文件。"+resultStr);
    			return hashMap;
    		}

    		//step3: 验证数据是否为空,长度是否过长,是否为纯数字。。。
            // 详见7)校验数据是否为空
    		String verificationDateResultString = verificationDate(sheet);
    		if (!verificationDateResultString.equals("")) {
    			hashMap.put("code", "0");
    			hashMap.put("msg", verificationDateResultString);
    			return hashMap;
    		}

    		//step4: 文件内容合法,做业务逻辑处理(保存)
            // 详见9)做业务逻辑处理(保存数据)
    		String saveResultString = insertData(sheet,xxxEntity);
    		if (!saveResultString.equals("")) {
    			hashMap.put("code", "0");
    			hashMap.put("msg", saveResultString);
    			return hashMap;
    		}

            //以上都顺利进行,返回前端:导入成功
    		hashMap.put("code", "1");
	        hashMap.put("msg", "导入成功!");
	        return hashMap;
		} catch (Exception e) {
			System.out.print("[读取excel异常]"+e.getMessage());
			hashMap.put("code", "0");
	        hashMap.put("msg", "读取excel异常");
	        return hashMap;
		}
        
    }

}
3)后端校验文件格式的方法
	
    public static Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
        Workbook workbook = null;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        if (".xls".equals(fileType)) {
            workbook = new HSSFWorkbook(inStr);
        } else if (".xlsx".equals(fileType)) {
            workbook = new XSSFWorkbook(inStr);
        } else {
            throw new Exception("请上传excel文件!");
        }
        return workbook;
    }
4)校验表格标题行方法
    
    public static String verificationExcelHeadLine(Sheet sheet, String[] columnName) throws Exception {
    	String result = "";
    	try {
            //获取第一行:标题行
    		Row row = sheet.getRow(0);
            
    		if (row != null && row.getLastCellNum() >= columnName.length) {
    			int lastCellNum = row.getLastCellNum();
                //循环遍历指定的数组内容与文件中内容一一对比
    			for (int idx = 0; idx < lastCellNum; idx++) {
                    //将格子中的内容转为java的string类型的方法
                    //详见5)将excel格子中的内容转为java的string类型的方法
    				String value = getStringCellValue(row.getCell(idx));
    				if (idx < 4) {
    					if (value == null || !columnName[idx].equals(value)) {
    						result = result+"标题行第" + (idx + 1) + "列名称错误!";
    					}
    				} else {
    					if (idx == 4) {
    						if (value == null) {
    							result = result+"标题标准表格表头不一致";
    						}
    					}
    				}
    			}
    		} else {
    			result = "上传文件首行不能为空或与标准表格表头不一致!";
    		}
    	} catch (Exception ex) {
    		logger.info("【导入成本】校验数据异常");
    	}
    	return result;
    }
5)将excel格子中的内容转为java的string类型的方法 
    
    private static String getStringCellValue(Cell cell) {
        String strCell = "";
        switch (cell.getCellType()) {
        case Cell.CELL_TYPE_STRING:
            strCell = cell.getStringCellValue();
            break;
        case Cell.CELL_TYPE_NUMERIC:
            strCell = String.valueOf(cell.getNumericCellValue());
            break;
        case Cell.CELL_TYPE_BOOLEAN:
            strCell = String.valueOf(cell.getBooleanCellValue());
            break;
        case Cell.CELL_TYPE_BLANK:
            strCell = "";
            break;
        default:
            strCell = "";
            break;
        }
        if (strCell.equals("") || strCell == null) {
            return "";
        }
        if (cell == null) {
            return "";
        }
        return strCell;
    }
    
6)判断列标题头是否正确
    public String verificationExcelHeadLineTwo(Sheet sheet, String[] columnName) {
    	String result = "";
    	try {
    		int allRowNum = sheet.getLastRowNum();
    		for(int i = 1; i <= allRowNum; i++) {
    			Row row = sheet.getRow(i);
    			if (row != null && row.getCell(1) != null) {
    				String value = getStringCellValue(row.getCell(1));
    				if (value == null || !columnName[i-1].equals(value)) {
						result = result+"第" +i+"行第2列名称错误!";
					}
        		} else {
        			result = "请选择正确模板!";
        		}
    		}
    	} catch (Exception ex) {
    		logger.info("【导入成本】校验数据异常");
    	}
    	return result;
    }
 7)校验数据是否为空
	
	
	private String verificationDate(Sheet sheet) {
		String result = "";
		int allRowNum = sheet.getLastRowNum();
		if(allRowNum != 12) {
			result = "数据行数不为12行,请检查模板;";
			return result;
		}
    	try {
    		//循环行
    		for(int i = 1; i <= sheet.getLastRowNum(); i++) {
    			Row row = sheet.getRow(i);
    			int allCellNum = row.getLastCellNum();
        		if (row != null &&  allCellNum == 9) {
        			//循环列
        			for (int idx = 0; idx < allCellNum; idx++) {
        				String value = getStringCellValue(row.getCell(idx));
        				if(!StringUtils.isNotEmpty(value)) {
        					result = result+"第"+i+"行"+"第"+idx+"列为空;";
        				}else {
        					//第二列以后为纯数字
        					if(idx>=2) {
                                //isNumeric为校验是否为数字的方法
                                //详见:8)校验是否为纯数字
        						if(!isNumeric(value)) {
        							result = result+"第"+i+"行"+"第"+idx+"列不是数字格式;";
        						}
        					}
        				}
        			}
        		} else {
        			result = "数据列数不为8列,请检查模板;";
        			return result;
        		}
    		}
    	} catch (Exception ex) {
    		 logger.info("【导入成本】校验数据异常");
    	}
    	return result;
	}
	 
8)校验是否为纯数字 :心机boy的方法
    
    public static boolean isNumeric(String str) {
        String bigStr;
        try {
            bigStr = new BigDecimal(str).toString();
        } catch (Exception e) {
            return false;//异常 说明包含非数字。
        }
        return true;
    }
9)做业务逻辑处理(保存数据)

    private String insertData(Sheet sheet,XXXEntity xxxEntity) {
    	String result = "";
    	
    	//构建子表数据
    	List xxxEntityList = new ArrayList();
    	Row row = null;
    	try {
    		for (int i =1; i <= sheet.getLastRowNum(); i++) {
                row = sheet.getRow(i);
                XXXEntity entity = new XXXEntity();
                
                entity.setMonth(getStringCellValue(row.getCell(0)));
                entity.setXXX(
                    new BigDecimal(
                        getStringCellValue(row.getCell(1))));
                //...
                xxxEntityList.add(entity);
            }
   
        	xxxEntityService.save(jCCostManager);
    	}catch(Exception e) {
    		result = "数据格式异常无法保存。";
    		return result;
    	}
    	
    	return result;
    }
    
总结

        以上可以实现简单导入导出excel,如有错误,请指正!

        希望广大网友有更简便的方法或框架可以提供~

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5692726.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存