解析Excel文件并把数据存入数据库
前段时间做一个小项目,为了同时存储多条数据,其中有一个功能是解析Excel并把其中的数据存入对应数据库中。花了两天时间,不过一天多是因为用了"upload"关键字作为URL从而导致总报同一个错,最后在同学的帮助下顺利解决,下面我把自己用"POI"解析的方法总结出来供大家参考(我用的是SpingMVC和hibernate框架)。
1.web.xml中的配置文件
web.xml中的配置文件就按照这种方式写,只需要把"application.xml"换成你的配置文件名即可
1 <!--文件上传对应的配置文件--> 2 <listener> 3 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 4 </listener> 5 <context-param> 6 <param-name>contextConfigLocation</param-name> 7 <param-value>classpath:application.xml</param-value> 8 </context-param>
2.application.xml的配置文件(固定写发)
在这个配置文件中你还可以规定上传文件的格式以及大小等多种属性限制
1 <!-- 定义文件上传解析器 --> 2 <bean id="multipartResolver" 3 class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 4 </bean>
3.文件上传的前端HTML
注意:1.enctype="multipart/form-data" 必须写,封装表单
2.method="post",提交方式必须为"post"提交
3.action="${text}/uploadfile", "uploadfile"切记不要写成"upload",否则你找到世界末日也不会找到哪里有问题(本人因为这个折腾了一天多时间)。
1 <form name="fileupload" enctype="multipart/form-data" action="${text}/uploadfile" method="post"> 2 <p style="font-size:16px;">请选择正确的excel文件上传</p> 3 <input id="txt" class="input" type="text" disabled="disabled" value="文件域" name="txt"> 4 <input class="liulan" type="button" onclick="file.click()" size="30" value="上传文件" onmousemove="file.style.pixelLeft=event.x-60;file.style.pixelTop=this.offsetTop;"> 5 <input id="file1" class="files" type="file" hidefocus="" size="1" style="height:26px;" name="file" onchange="txt.value=this.value"> 6 <br/><input type="button" onclick="checkSuffix();" value="提交上传" style="height:26px;width:100px"> 7 <p style="color:red;">支持的excel格式为:xls、xlsx、xlsb、xlsm、xlst!</p> 8 </form>
4.验证上传文件的格式
1 //用于验证文件扩展名的正则表达式 2 function checkSuffix(){ 3 var name = document.getElementById("txt").value; 4 var strRegex = "(.xls|.xlsx|.xlsb|.xlsm|.xlst)$"; 5 var re=new RegExp(strRegex); 6 if (re.test(name.toLowerCase())){ 7 alert("上传成功"); 8 document.fileupload.submit(); 9 } else{ 10 alert("文件名不合法"); 11 } 12 }
5.dao层的接口和实现类
1 package com.gxxy.team1.yyd.dao; 2 3 public interface IFileUploadDao { 4 public void save(Object o); 5 }
1 package com.gxxy.team1.yyd.dao.impl; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.stereotype.Repository; 7 8 import com.gxxy.team1.yyd.dao.IFileUploadDao; 9 @Repository 10 public class FileUploadDaoImpl implements IFileUploadDao { 11 @Autowired 12 private SessionFactory sessionFactory; 13 private Session getSession() { 14 Session session = sessionFactory.getCurrentSession(); 15 return session; 16 } 17 @Override 18 public void save(Object o) { 19 20 getSession().save(o); 21 } 22 23 }
6.service层的接口和实现类
1 package com.gxxy.team1.yyd.service; 2 3 import java.util.List; 4 5 public interface IFileUploadService { 6 public List<String[]> readExcel(String path); 7 public void save(Object o); 8 }
1 package com.gxxy.team1.yyd.service.impl; 2 3 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.text.SimpleDateFormat; 7 import java.util.ArrayList; 8 import java.util.List; 9 10 import org.apache.poi.ss.usermodel.Cell; 11 import org.apache.poi.ss.usermodel.DateUtil; 12 import org.apache.poi.ss.usermodel.Row; 13 import org.apache.poi.ss.usermodel.Sheet; 14 import org.apache.poi.ss.usermodel.Workbook; 15 import org.apache.poi.ss.usermodel.WorkbookFactory; 16 import org.springframework.beans.factory.annotation.Autowired; 17 import org.springframework.stereotype.Service; 18 19 import com.gxxy.team1.yyd.dao.IFileUploadDao; 20 import com.gxxy.team1.yyd.service.IFileUploadService; 21 @Service 22 public class FileUploadServiceImpl implements IFileUploadService { 23 @Autowired 24 private IFileUploadDao fileDao; 25 @Override 26 public List<String[]> readExcel(String path) { 27 SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); 28 List<String[]> list = null; 29 try { 30 //同时支持Excel 2003、2007 31 File excelFile = new File(path); //创建文件对象 32 FileInputStream is = new FileInputStream(excelFile); //文件流 33 Workbook workbook = WorkbookFactory.create(is); //这种方式 Excel 2003/2007/2010 都是可以处理的 34 int sheetCount = workbook.getNumberOfSheets(); //Sheet的数量 35 //存储数据容器 36 list = new ArrayList<String[]>(); 37 //遍历每个Sheet 38 for (int s = 0; s < sheetCount; s++) { 39 Sheet sheet = workbook.getSheetAt(s); 40 int rowCount = sheet.getPhysicalNumberOfRows(); //获取总行数 41 //遍历每一行 42 for (int r = 0; r < rowCount; r++) { 43 Row row = sheet.getRow(r); 44 int cellCount = row.getPhysicalNumberOfCells(); //获取总列数 45 //用来存储每行数据的容器 46 String[] model = new String[cellCount-1]; 47 //遍历每一列 48 for (int c = 0; c < cellCount; c++) { 49 Cell cell = row.getCell(c); 50 int cellType = cell.getCellType(); 51 52 if(c == 0) continue;//第一列ID为标志列,不解析 53 54 String cellValue = null; 55 switch(cellType) { 56 case Cell.CELL_TYPE_STRING: //文本 57 cellValue = cell.getStringCellValue(); 58 //model[c-1] = cellValue; 59 break; 60 case Cell.CELL_TYPE_NUMERIC: //数字、日期 61 if(DateUtil.isCellDateFormatted(cell)) { 62 cellValue = fmt.format(cell.getDateCellValue()); //日期型 63 //model[c-1] = cellValue; 64 } 65 else { 66 67 cellValue = String.valueOf(cell.getNumericCellValue()); //数字 68 //model[c-1] = cellValue; 69 } 70 break; 71 case Cell.CELL_TYPE_BOOLEAN: //布尔型 72 cellValue = String.valueOf(cell.getBooleanCellValue()); 73 break; 74 case Cell.CELL_TYPE_BLANK: //空白 75 cellValue = cell.getStringCellValue(); 76 break; 77 case Cell.CELL_TYPE_ERROR: //错误 78 cellValue = "错误"; 79 break; 80 case Cell.CELL_TYPE_FORMULA: //公式 81 cellValue = "错误"; 82 break; 83 default: 84 cellValue = "错误"; 85 86 } 87 System.out.print(cellValue + " "); 88 89 model[c-1] = cellValue; 90 } 91 //model放入list容器中 92 list.add(model); 93 System.out.println(); 94 } 95 } 96 is.close(); 97 } 98 catch (Exception e) { 99 e.printStackTrace(); 100 } 101 102 return list; 103 } 104 @Override 105 public void save(Object o) { 106 fileDao.save(o); 107 } 108 }
7.controller层实现
1 //文件上传方法 2 @RequestMapping("/uploadfile") 3 public String upload(@RequestParam(value = "file", required = false) MultipartFile file, HttpServletRequest request, ModelMap model,Model mod) throws Exception { 4 String path = request.getSession().getServletContext().getRealPath("upload"); 5 System.out.println("文件路径:"+path); 6 String originalFilename = file.getOriginalFilename(); 7 String type = file.getContentType(); 8 //originalFilename = UUID.randomUUID().toString()+originalFilename; 9 System.out.println("目标文件名称:"+originalFilename+",目标文件类型:"+type); 10 File targetFile = new File(path,originalFilename ); 11 if (!targetFile.getParentFile().exists()) { 12 targetFile.getParentFile().mkdirs(); 13 }else if (!targetFile.exists()) { 14 targetFile.mkdirs(); 15 } 16 // 获得上传文件的文件扩展名 17 String subname = originalFilename.substring(originalFilename.lastIndexOf(".")+1); 18 System.out.println("文件的扩展名:"+subname); 19 20 try { 21 file.transferTo(targetFile); 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 FileUploadServiceImpl fileUp = new FileUploadServiceImpl(); 26 String rootpath = path + File.separator + originalFilename; 27 List<String[]> excellist = fileUp.readExcel(rootpath); 28 int len = excellist.size(); 29 System.out.println("集合的长度为:"+len); 30 for (int i = 0; i < len; i++) { 31 String[] fields = excellist.get(i); 32 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 33 String sampleNo = fields[0]; 34 35 Double valueOf = Double.valueOf(fields[1]); 36 int sampleType = valueOf.intValue(); //double转int 37 38 String createTime = fields[2]; 39 Date createTime1 = format.parse(createTime); 40 String name = fields[3]; 41 String pId = fields[4]; 42 String hospitalName = fields[5]; 43 String cellPhone = fields[6]; 44 Sample sample = new Sample(sampleNo, sampleType, createTime1, name, pId); 45 Patient patient = new Patient(hospitalName, cellPhone); 46 fileService.save(sample); 47 fileService.save(patient); 48 } 49 //model.addAttribute("fileUrl", request.getContextPath()+"/upload/"+originalFilename); 50 51 String username = (String) request.getSession().getAttribute("username"); 52 List<List<Menu>> power = powerService.power(username); 53 mod.addAttribute("list", power); 54 return "redirect:/ yyd"; 55 }
以上这7个部分就是我实现解析excel文件并存入数据库的全部代码。