需求说明
一、实现思路
二、前端代码
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 HashMap2)处理文件工具类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; } }
@Service public class ExcelUtilForXXXimport { private static final Logger logger = LoggerFactory.getLogger(ExcelUtilForXXXimport.class); @Autowired private XXXEntityService xxxEntityService; public HashMap3)后端校验文件格式的方法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; } } }
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,如有错误,请指正!
希望广大网友有更简便的方法或框架可以提供~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)