你在工作中是否遇到这样的问题?数据一般存放在Excel表中,逐条迁移到数据库中太麻烦,而且很多时候企业的数据量都是以万起步,单条导入显然不现实。那么该如何解决呢?

我们今天就给大家介绍一个用途非常广泛的功能:批量导入,在很多系统中,这也是必须实现的功能。而且当Excel表结构越复杂时,实现的难度就越高。

不管项目如何复杂,原理却基本相同,一般是前台页面选择Excel文件,后台获取后进行数据转化,然后循环执行Sql语句即可,了解这些原理后,一切也就变得简单。

下面为了重点演示,项目进行简化,只有批量导入功能,将Excel数据导入到Mysql数据库中。

Mysql数据库user表结构

Excel中数据


如果Excel中必填项数据为空,提示导入失败,报告错误信息及位置,项目演示图:


如果数据正确,提示导入数据库成功:

具体实现过程

首先是JSP页面,name的名称是重点:

<form action="${pageContext.request.contextPath }/excelsave.action" method="post" enctype="multipart/form-data"><input type="file" name="fileinput" multiple="multiple"/><button type="submit" name="subimit">上传</button>
</form>

前台点击上传后跳转到action处理,action中首先定义:

//这里特别注意获取fileinput要和页面的导入时name属性一致。
private File fileinput;
//文件名用得到就获取,一般用不到。
private String fileinputFileName;
//下面是get和set方法,省略
然后在方法体中直接调用://参数为获取到的文件
ExcelUtil(fileinput);

ExcelUtil是处理Excel工具类,直接使用,代码如下:

/**解析excel 工具类*/
@SuppressWarnings("rawtypes")
public class ExcelUtil {public FileInputStream fis ;public HSSFWorkbook workBook;public HSSFSheet sheet;public XMLUtil parseXmlUtil;public StringBuffer errorString;/**当前实体类的code**/public String curEntityCode;/**表头map对象:key:entityCode, value:headMap(index,headTitle)**/public Map curEntityHeadMap ;/**字段的必填:key:entityCode+headTitle, value:true(必填),false(不必填)**/public Map curEntityColRequired;/**存放每一行的数据**/public  List listDatas ;public ExcelUtil(File excelFile){try {if(excelFile == null){throw new FileNotFoundException();}fis = new FileInputStream(excelFile);           workBook = new HSSFWorkbook(fis);parseXmlUtil = new XMLUtil();errorString = new StringBuffer();readExcelData();} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}   }/**开始从excel读取数据**/ public void readExcelData(){int sheetSize = workBook.getNumberOfSheets();for(int i=0;i<sheetSize;i++){sheet = workBook.getSheetAt(i);String entityName = workBook.getSheetName(i);readSheetData(sheet,entityName);}}/**读每个sheet页的数据**/public void readSheetData(HSSFSheet sheet,String entityName){int rowNumbers = sheet.getPhysicalNumberOfRows();Map ent = (Map) parseXmlUtil.getEntityMap().get(entityName);this.setCurEntityCode((String) ent.get("code"));if(rowNumbers == 0){System.out.println("excel中数据为空!");errorString.append(Constans.ERROR_EXCEL_NULL);}         List colList = (List) parseXmlUtil.getColumnListMap().get(entityName);int xmlRowNum = colList.size();HSSFRow excelRow = sheet.getRow(0);int excelFirstRow = excelRow.getFirstCellNum();int excelLastRow = excelRow.getLastCellNum();if(xmlRowNum  != (excelLastRow-excelFirstRow)){System.out.println("xml列数与excel列数不相符,请检查");errorString.append(Constans.ERROR_EXCEL_COLUMN_NOT_EQUAL);}readSheetHeadData(sheet);readSheetColumnData(sheet,entityName);}/**读取sheet页中的表头信息**/@SuppressWarnings({ "unchecked", "static-access"})public void readSheetHeadData(HSSFSheet sheet){Map headMap = new HashMap();curEntityHeadMap = new HashMap();curEntityColRequired = new HashMap();HSSFRow excelheadRow = sheet.getRow(0);int excelLastRow = excelheadRow.getLastCellNum();String headTitle = "";for(int i=0;i<excelLastRow;i++){HSSFCell cell = excelheadRow.getCell(i);headTitle = this.getStringCellValue(cell).trim();if(headTitle.endsWith("*")){curEntityColRequired.put(this.getCurEntityCode()+"_"+headTitle,true);}else{curEntityColRequired.put(this.getCurEntityCode()+"_"+headTitle,false);}headMap.put(i, headTitle);}curEntityHeadMap.put(this.getCurEntityCode(), headMap);}/**读取sheet页里面的数据**/@SuppressWarnings({ "unchecked", "static-access" })public void readSheetColumnData(HSSFSheet sheet,String entityName){HSSFRow excelheadRow = sheet.getRow(0);int excelLastcell = excelheadRow.getLastCellNum();   //excel总列数int excelRowNum = sheet.getLastRowNum();  //excel总行数Map headMap = (Map) this.getCurEntityHeadMap().get(this.getCurEntityCode());       Map colMap = parseXmlUtil.getColumnMap();listDatas =new ArrayList();for(int i=1;i<excelRowNum+1;i++){//行循环                 HSSFRow columnRow = sheet.getRow(i);    if(columnRow != null){Map curRowCellMap = new HashMap();for(int j =0; j<excelLastcell;j++){ //列循环int cout =  headMap.get(j).toString().indexOf("*");String headTitle ="";if(cout == -1){headTitle = headMap.get(j).toString();}else{headTitle =  headMap.get(j).toString().substring(0, cout);}                       Map curColMap =  (Map) colMap.get(entityName+"_"+headTitle);String curColCode = (String) curColMap.get("code");String curColType = (String) curColMap.get("type");HSSFCell colCell = columnRow.getCell(j);String value =this.getStringCellValue(colCell);if(value != null){value = value.trim();}              String xmlColType = (String) curColMap.get("type");int intVal = 0;if(xmlColType.equals("int")){if(value != null) {intVal = Integer.valueOf(value);}curRowCellMap.put(curColCode, intVal);  //将这一行的数据以code-value的形式存入map}else{curRowCellMap.put(curColCode, value); }/**验证cell数据**/validateCellData(i+1,j+1,colCell,entityName,headTitle,curColType,listDatas);}listDatas.add(curRowCellMap);} }if(this.getErrorString().length() ==0){//如果没有任何错误,就保存saveExcelData(entityName);System.out.println("导入数据库成功");}else{//清理所有的缓存clearMap();现在暂时未清理String[] strArr = errorString.toString().split("<br>");for(String s: strArr){System.out.println(s);}}}/**验证单元格数据**/@SuppressWarnings("static-access")public void validateCellData(int curRow,int curCol,HSSFCell colCell,String entityName,String headName,String curColType,List listDatas){List rulList = (List) parseXmlUtil.getColumnRulesMap().get(entityName+"_"+headName);if(rulList != null && rulList.size()>0){for(int i=0 ; i<rulList.size() ; i++){Map rulM = (Map) rulList.get(i);String rulName = (String) rulM.get("name");String rulMsg = (String) rulM.get("message");String cellValue = "";if(this.getStringCellValue(colCell)==null) {//System.out.println("第"+curRow+"行,第"+curCol+"列:"+rulMsg);}else {cellValue = this.getStringCellValue(colCell).trim();}if(rulName.equals(Constans.RULE_NAME_NULLABLE)){         if(cellValue.equals("")||cellValue == null){errorString.append("导入失败,错误信息:第"+curRow+"行,第"+curCol+"列:"+rulMsg+"<br>");}}//这里写其他的验证规则。。。}}}/**保存excel里面的数据**/@SuppressWarnings("unchecked")public void saveExcelData(String entityName){List<User> users= new ArrayList();for(int i = 0 ; i<this.getListDatas().size();i++){Map excelCol = (Map) this.getListDatas().get(i);  //得到第 i 行的数据     User user = new User();try {User obj = (User) BeanToMapUtil.convertMap(user.getClass(), excelCol);users.add(obj);   } catch (IntrospectionException e) {           e.printStackTrace();} catch (IllegalAccessException e) {        e.printStackTrace();} catch (InstantiationException e) {        e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}/**批量保存数据**/Dao dao = new Dao();for(int i = 0;i<users.size();i++){try{dao.saveUser(users.get(i));}catch(Exception e){e.printStackTrace();}}}/*** 获得单元格字符串* @throws UnSupportedCellTypeException */public static String getStringCellValue(HSSFCell cell) {if (cell == null){return null;}String result = "";switch (cell.getCellType()) {case HSSFCell.CELL_TYPE_BOOLEAN:result = String.valueOf(cell.getBooleanCellValue());break;case HSSFCell.CELL_TYPE_NUMERIC:if (HSSFDateUtil.isCellDateFormatted(cell)) {java.text.SimpleDateFormat TIME_FORMATTER = new java.text.SimpleDateFormat("yyyy-MM-dd");result = TIME_FORMATTER.format(cell.getDateCellValue());}else{double doubleValue = cell.getNumericCellValue();result = "" + doubleValue;}break;case HSSFCell.CELL_TYPE_STRING:if (cell.getRichStringCellValue() == null){result = null;}else{result = cell.getRichStringCellValue().getString();}break;case HSSFCell.CELL_TYPE_BLANK:result = null;break;case HSSFCell.CELL_TYPE_FORMULA:try{result = String.valueOf(cell.getNumericCellValue());   }catch(Exception e){result = cell.getRichStringCellValue().getString();}break;default:result = "";}return result;}public String getCurEntityCode() {return curEntityCode;}public void setCurEntityCode(String curEntityCode) {this.curEntityCode = curEntityCode;}public Map getCurEntityHeadMap() {return curEntityHeadMap;}public void setCurEntityHeadMap(Map curEntityHeadMap) {this.curEntityHeadMap = curEntityHeadMap;}public XMLUtil getParseXmlUtil() {return parseXmlUtil;}public void setParseXmlUtil(XMLUtil parseXmlUtil) {this.parseXmlUtil = parseXmlUtil;}public Map getCurEntityColRequired() {return curEntityColRequired;}public void setCurEntityColRequired(Map curEntityColRequired) {this.curEntityColRequired = curEntityColRequired;}public List getListDatas() {return listDatas;}public void setListDatas(List listDatas) {this.listDatas = listDatas;}public StringBuffer getErrorString() {return errorString;}public void setErrorString(StringBuffer errorString) {this.errorString = errorString;}}

项目中定义一个XML文件,主要做一些条件限制,比如用户名不能为空,email不能重复等,所以就有一个XML解析类:

/**解析xml工具类*/
@SuppressWarnings("rawtypes")
public class XMLUtil {/**entity map对象,key:name ,value:entity的属性map集**/public Map entityMap ;/**column map 对象,key:entityName_colName , value:column的属性map集 **/public Map columnMap;/**rule map 对象,key:entityName_colName_ruleName, value: rule 的map集:找到一行rule**/public Map ruleMap ;/**rules map 对象, key:entityName_colName, value: rules 的map集:找到该column下所有的rule**/public Map  columnRulesMap ;/**entity--column map: key:entityName, value: column list:根据实体类名得到所有的列**/public Map columnListMap ;/**column list**/public List columnList ;/**开始解析xml文件**/public XMLUtil(){SAXReader reader = new SAXReader();InputStream in = getClass().getClassLoader().getResourceAsStream("user.xml");//读取文件流,Url为controller.xml文件try {Document doc = reader.read(in);//获得文件实例Element root = doc.getRootElement();    Iterator itEntity = root.elements("entity").iterator();while(itEntity.hasNext()){Element entity = (Element) itEntity.next();parseEntity(entity);}/**测试entityMap 是否正确**/Map enMap = (Map) this.getEntityMap().get("用户表");Set<?> set = enMap.keySet();Iterator it = set.iterator();while(it.hasNext()){String uu = (String) it.next();}}catch(Exception e){e.printStackTrace();}}/**开始解析entity**/@SuppressWarnings("unchecked")public void parseEntity(Element entity){if(entity != null){/**对数据进行初始化设置**/columnListMap = new HashMap();columnMap = new HashMap();entityMap = new HashMap();ruleMap = new HashMap();columnRulesMap = new HashMap();columnList = new ArrayList();setEntityMap(entity);           String entityName = entity.attributeValue("name");Iterator itColumn = entity.elements("column").iterator();while(itColumn.hasNext()){Element column = (Element) itColumn.next();setColumnMap(entityName,column);}columnListMap.put(entityName, columnList);}}/**将entity放入entityMap中**/@SuppressWarnings("unchecked")public void setEntityMap(Element entity){     Map ent = new HashMap();String name = entity.attributeValue("name");String code = entity.attributeValue("code");ent.put("name", name);ent.put("code", code);entityMap.put(name, ent);            }/**将column放入columnMap中**/@SuppressWarnings("unchecked")public void setColumnMap(String entityName,Element column){if(column != null){      Map col = new HashMap();String name = column.attributeValue("name");String code = column.attributeValue("code");String type = column.attributeValue("type");col.put("name", name);col.put("code", code);col.put("type", type);String columnMapKey = entityName+"_"+name;    //eg:  用户表_用户名columnMap.put(columnMapKey, col);        columnList.add(col);Iterator ruleIt = column.elements("rules").iterator();  //获得ruleswhile(ruleIt.hasNext()){Element rules = (Element)ruleIt.next(); Iterator rule  = rules.elements("rule").iterator();   //获得 rulewhile(rule.hasNext()){Element ruleValid = (Element) rule.next();     //获得每一行rulesetRuleMap(entityName,name,ruleValid);                  }}}}/**将 rule 验证规则放入ruleMap中**/@SuppressWarnings("unchecked")public void setRuleMap(String entityName,String columnName,Element ruleValid){if(ruleValid != null){           String ruleName = ruleValid.attributeValue("name");String ruleMsg = ruleValid.attributeValue("message");Map ruleValidMap = new HashMap();ruleValidMap.put("name", ruleName);ruleValidMap.put("message", ruleMsg);String ruleStrKey = entityName+"_"+columnName+"_"+ruleName;String colStrKey = entityName+"_"+columnName;if(this.getColumnRulesMap().containsKey(colStrKey)){List valids = (List) this.getColumnRulesMap().get(colStrKey);valids.add(ruleValidMap);}else{List valids = new ArrayList();valids.add(ruleValidMap);this.columnRulesMap.put(colStrKey, valids);  //将每个column下的所有rules存入该map中}ruleMap.put(ruleStrKey, ruleValidMap); //将每个column下的一条rule存入该map中}}/**所有的get set 方法**/public Map getEntityMap() {return entityMap;}public void setEntityMap(Map entityMap) {this.entityMap = entityMap;}public Map getColumnMap() {return columnMap;}public void setColumnMap(Map columnMap) {this.columnMap = columnMap;}public Map getRuleMap() {return ruleMap;}public void setRuleMap(Map ruleMap) {this.ruleMap = ruleMap;}public Map getColumnRulesMap() {return columnRulesMap;}public void setColumnRulesMap(Map columnRulesMap) {this.columnRulesMap = columnRulesMap;}public Map getColumnListMap() {return columnListMap;}public void setColumnListMap(Map columnListMap) {this.columnListMap = columnListMap;}
}

XML解析类定义完成后,ExcelUtil会调用处理,处理完成后返回,导入结束。

至于数据库连接,任何方式都行,这里不做要求,另外需要定义一个实体User,属性根据自己的业务设置。

以上就是具体实现过程,如果有任何问题,私信,我们共同交流讨论。

将Excel数据批量导入到数据库(项目案例)相关推荐

  1. Excel数据批量导入到数据库

    1.今天做批量导入网上找了个例子,改了改,运行起来了.用POI实现Excel的读取,需要jar包. 2.ReadExcel.java读取数据 /*** */ package com.b510.exce ...

  2. dataset中的数据批量导入oracle数据库,c#如何将dataset中的数据批量导入oracle数据库...

    c#如何将dataset中的数据批量导入oracle数据库以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! c#如何将da ...

  3. java excel批量导入数据库数据_Java实现Excel数据批量导入数据库

    Java实现Excel数据批量导入数据库 概述: 这个小工具类是工作中的一个小插曲哦,因为提数的时候需要跨数据库导数... 有的是需要从oracle导入mysql ,有的是从mysql导入oracle ...

  4. POI和EasyExcel实现Excel数据批量读取到数据库

    POI和easyExcel讲解 目的:这一部分我主要是为了实现excel数据批量插入到数据库. 参考:狂神说java的上课笔记 视屏教学网址 常用信息 1,将用户信息导出为excel表格 2,讲Exc ...

  5. 【Springboot+mybatis】 解析Excel并批量导入到数据库

    [Springboot+mybatis] 解析Excel并批量导入到数据库 置顶 2018年01月16日 20:05:52 冉野丶 阅读数:4060 标签: excel导入数据库 文件上传 excel ...

  6. 多个excel文件批量导入到数据库

    多个excel文件批量导入到数据库 摘要:我们可以用navicate等数据库编辑器的excel导入功能将一个excel导入到数据库,但是我们有多个excel甚至成百上千怎么办?这个时候用navicat ...

  7. PHP将excel文件中的数据批量导入到数据库中

    2019独角兽企业重金招聘Python工程师标准>>> 这几天在做项目时,遇到了需要批量导入数据的情况,用户将excel表格提交后,需要我们后台这边将excel表格信息中的内容全部插 ...

  8. php excel批量导入,PHP将excel文件中的数据批量导入到数据库中

    这几天在做项目时,遇到了需要批量导入数据的情况,用户将excel表格提交后,需要我们后台这边将excel表格信息中的内容全部插入到数据表中.当然,前提是用户给我们的excel表格中的信息必须和我们表中 ...

  9. 将Excel表格数据批量导入MySQL数据库表中

    在实际的生产开发需求中很多时候生产数据不一定是通过数据库进行导入,而是通过Excel表格的形式传入形式,这时候需要程序员进行自动化的导入. 手动导入数据库,效率相对来说太慢,因此需要使用技巧,实现批量 ...

  10. php批量导入多个excel,php的excel数据批量导入

    工作中常常有批量导入数据的需求,方法太多,掌握一个简单实用的足够了.下面为大家介绍一个好用的方法. 数据导入必须按照指定的格式系统方能识别,因此可两个大的步骤:一.导入模板下载  二.数据导入 一.模 ...

最新文章

  1. axure9中继器添加一列序号自增_中继器如何做简单穿梭框
  2. 2015年个人年度目标总结-产品狗版
  3. matlab中基本函数的用法
  4. exe解包和重新打包_pyinstaller打包的exe太大?你需要嵌入式python玄学 前提篇
  5. C++ STL : 模拟实现STL中的vector类
  6. 发现以前的一些记录 shutdown AP CPU
  7. 使用Apache Zookeeper进行协调和服务发现
  8. CharSequence类
  9. 有时候,996确实会让你麻木
  10. PHP判断PHP版本是否及格
  11. JAVA面试要点009---TimeUnit用法
  12. 怎样给Spark传递函数—怎样让你的Spark应用更高效更健壮
  13. 深蓝词库转换1.6发布
  14. 重置Winsock失败,在NSHHTTP.DLL中初始化函数InitHelperDll启动失败,错误代码为10107的解决方法
  15. Java编程中常见异常有哪些?
  16. MapReduce自定义排序、自定义分组、自定义分区
  17. Pytorch实现多层lstm
  18. LSTM和GRU的对比和分析
  19. 网络传输介质 通信中的有线介质:双绞线、同轴电缆、光纤 引导性传输介质
  20. IPV6----升级点,地址分类及部分协议配置

热门文章

  1. nrf51822微信开发入门学习笔记1:开始前的准备
  2. HDU4812 D tree 【点分治 + 乘法逆元】
  3. Django折腾日记(django2.0)
  4. 使用LoadRunner进行性能测试的简单步骤
  5. [Erlang危机](5.1.0)VM检测概述
  6. 【转】安卓开发经验分享:资源、UI、函数库、测试、构建一个都不能少
  7. java给方法参数赋值_java方法参数的赋值问题实例源码介绍
  8. 拓端tecdat|R语言单变量和多变量(多元)动态条件相关系数DCC-GARCH模型分析股票收益率金融时间序列数据波动率
  9. 拓端tecdat|python爬虫进行Web抓取LDA主题语义数据分析报告
  10. 戴尔服务器t330可以用无线网卡吗,DELL T330服务器安装windows2008R2系统