谨以实际开发中所学到的第一个功能来纪念我的第一篇博客,如有不足之处,万望各位大神不吝指出。

Web项目的开发过程中,通常会用到上传Excel文件的功能。将一个Excel文件从本地文件系统中获取,并将其中的数据存入数据库中以便项目使用。简单来说分为三个步骤:1、前端获取文件;2、后台解析文件;3、数据存入数据库。三个步骤之间的连接控制则由控制层进行整体把控,流程为:前端获取文件--控制层获取文件流--控制层调用文件解析工具类--控制层调用数据存入数据库方法。接下来将对以上三个步骤进行逐步说明。并将具体的控制层代码放在最后展示。

第一步:前端获取文件

最开始进行前端获取文件功能的开发时,采用了最方便的原生js进行文件获取,结果被公司前辈狠狠的吐槽了一顿,原因就是样式丑到无与伦比。因此又在原有的基础上对样式进行了进一步的修改。下面会将代码分为原生和改进两种版本。

1、原生js提供了文件上传的功能,在input元素中,类型修改为"file"即可实现从本地文件系统中获取指定文件的功能。获取到文件后,采用form表单将获取到的信息发送至后台指定路径,进行后续操作。(当然原生js的文件上传功能方便自然是方便的,只是它的样式嘛,只能说用过的都懂)

<script language="JavaScript">function tijiao(){$("#myFrom").submit();}
</script><lable style="font-size: 15px;">导入文件:</lable>
<form action="#" method="post" enctype="multipart/form-data" id="myFrom" style="padding-left: 30px;display:inline;" ><input type="file" name="file" value=""  id="file"/><input type="button" id="sub" onclick="tijiao()" VALUE="上传" class="queryBtn" style="background-color: #009688"><input type="text" value="" id="data" name="data" style="display: none;">
</form>

2、在经过前辈的吐槽后,痛定思痛,决定将样式从头到尾的进行一次修改。考虑到不同浏览器的兼容性,不得已做出一些多余的操作,来尽可能的保证不同浏览器的正常使用。为保证以下代码可以复制即用,因此将代码中涉及到框架样式的div等元素进行清除,以下为改进后的代码。

<script language="JavaScript">var type = '${type}';var url = "";var result='';$(function(){if(type == "xm"){url ="../rksqCtrl/importda?type=xm";//根据后台传入不同类型,form表单可提交到不同路径。(本文暂使用一种类型,一个路径)}$('#myFrom').attr('action',url);//将路径写入到form表单的属性中})function tijiao(){$("#subbtn").click();}function resetClick(){//关闭弹窗var _index = parent.layer.getFrameIndex(window.name);parent.layer.close(_index);}function choosefile(){//选择文件,通过新的输入框,将原有的样式进行覆盖,因此需要js调用原有样式的点击事件。$('#file').click();}function changefile(obj){var filePath = obj.value;var index = filePath.lastIndexOf("\\");var name= filePath.substring(index+1);  $('#showfilename').val(name);}</script>
<style>.queryBtn{margin: auto;width: 56px;height: 28px;color: #fff;}
</style>
</head>
<body><lable style="font-size: 15px;">导入文件:</lable><form action="#" method="post" enctype="multipart/form-data" id="myFrom" style="padding-left: 30px;display:inline;" ><input type="text" value="" onclick="choosefile()" id="showfilename" readonly style='width: 250px;border-radius: 3px;border:1px solid #d8d6d6;'/><input type="file" name="file" value="" onchange="changefile(this)"  id="file" style='position: absolute;opacity: 0;width: 1px;height: 1px;cursor: pointer;'/><input type="button" onclick="choosefile()"  VALUE="选择文件" class="queryBtn" style="width: 80px;background-color: #46b5cc;cursor: pointer;border: 1px solid #46b5cc;border-radius: 3px;"><input type="text" value="" id="data" name="data" style="display: none;"><input type="submit" id="subbtn" hidden></form><button class="search-btn cz-btn" id="sub" onclick="tijiao();" style="right:55%;background:#009688;">上传</button><button class="search-btn cz-btn" id="resetBtn" onclick="resetClick();" style="right:45%;background:#46b5cc;">关闭</button>
</body>

第二步:后台解析文件

后台解析文件可自己编写工具类来进行文件解析,在以后的开发中可直接进行调用,调用该类中的解析方法,传入文件流和对应数据库表的实体类,返回一个list集合,该集合存储了多个传入的实体类,Excel每条数据都对应着一个实体类。以下代码即为一个工具类。

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import static jxl.biff.FormatRecord.logger;public class ImportExcelUtils {// 总行数private int totalRows = 0;// 总条数private int totalCells = 0;// 错误信息接收器private String errorMsg;// 构造方法public ImportExcelUtils() {}// 获取总行数public int getTotalRows() {return totalRows;}// 获取总列数public int getTotalCells() {return totalCells;}// 获取错误信息public String getErrorInfo() {return errorMsg;}/*** @param in* @param entityClass* @List*/public static List readXmxxExcel(InputStream in, Object entityClass){List list = new ArrayList();try {Workbook wb = Workbook.getWorkbook(in);//将字符流转化为workbook类型Sheet sheet = wb.getSheet(0);//获取workbook中的sheetint rowNum = sheet.getRows();//行总数int cellNum = 0;if(rowNum>0){cellNum = sheet.getRow(0).length;//列总数}//获取指定实体类中字段数量Field[] fields = ((Class) entityClass).getDeclaredFields();for(int i = 3; i < rowNum; i++) {//i为Excel文件中实际数据的起点,排除了标题及备注所占用的行。可根据实际情况修改。//调用newInstance()方法来创建一个对象Object classBean = ((Class) entityClass).newInstance();Cell[] curRow = sheet.getRow(i);for(short j = 0; j < curRow.length; j++) {if(curRow.length == 0){//排除Excel文件中内容为空的单元格continue;}if(fields !=null) {String field = "";switch (j){//根据Excel文件内具体字段的列序号来确定数据库中对应的字段case 0:field = "xmmch";break;case 1:field = "xmfl";break;case 2:field = "dxgch";break;case 3:field = "bmbh";break;}if(!field.equals("")){String firstLetter = field.substring(0, 1).toUpperCase();//拼接set方法String methodName = "set" + firstLetter + field.substring(1);String cellVal = "";if (curRow != null) {cellVal = curRow[j].getContents().trim();}//将新创建的类、set方法名、对应字段的值循环调用invokeMethod方法invokeMethod(classBean, methodName, cellVal);}} else {// Excel字段长度与字段描述文件不匹配System.out.println("Excel字段长度与字段描述文件不匹配");break;}}list.add(classBean);}} catch (Exception e) {e.printStackTrace();}return list;}//调用的工具方法。public static Object invokeMethod(Object classInstance,String methodName,Object... obj){if (classInstance == null || methodName==null)throw new IllegalArgumentException(methodName + " doesn't exist");Method method = lookupMethod(classInstance.getClass().getMethods(), methodName);if (method == null)throw new IllegalArgumentException(methodName + " is invoked error");     try{//出现参数类型不匹配错误,原因:excel传入类型为String类型,实体类中对应字段类型不匹配//解决方法:在控制层添加判断,对指定的字段进行类型转换后作为参数写入实体类对象中return method.invoke(classInstance,obj);}catch(Exception e){throw new IllegalArgumentException(e);}}
}

第三步:数据存入数据库

通过控制层的调用,将文件解析后的list集合中的数据导入到数据库表中,本文采用了JDBCTemplate进行持久层的开发。相关业务逻辑校验的代码已经去除。以下为持久层操作代码:

//将获取到的list插入到项目信息表中public String insertXmxx(List list) throws Exception {String xmbh = "";Map<String, String> map = new HashMap<String, String>();int  a = list.size();int num = 3;//excel实际数据第一行String result = "";for (Object obj : list) {num++;//插入数据sql字符串StringBuffer sbf = new StringBuffer("");//创建实体类对象,进行list集合中对象的读取。T_xm_xmxx xm = new T_xm_xmxx();xm = (T_xm_xmxx) obj;try {//插入语句StringBuffer insert = new StringBuffer("insert into T_XM_XMXX (xmbh,xmmch) values(");insert.append("'").append(xm.getXmbh()).append("',");//通过实体类中的get方法,获取到对应实体类中的数据。insert.append("'"+xm.getXmmch()+"'");insert.append(")");if (this.jdbcTemplate.update(insert.toString()) > 0) {continue;}else{result = "文件第" + num + "行有误,请检查后上传!";return result;}}catch (Exception e) {result = "文件第" + num + "行出现错误,请检查后上传!";return result;}}result="成功导入"+(num-3)+"行数据!";return result;}

以上三个步骤为后台执行顺序,具体的执行顺序操作由控制层进行控制,控制层具体实现代码如下:

 //文件导入@RequestMapping("/importda")@ResponseBodypublic ModelAndView importda(@RequestParam("file")MultipartFile data, HttpServletRequest request) throws Exception {String type = request.getParameter("type");String result="";ModelAndView mv = new ModelAndView();if (data.getSize() > 0) {//解析Excel文件,并返回list集合if(type.equals("xm")){T_xm_xmxx t_xm_xmxx = new T_xm_xmxx();List list = ImportExcelUtils.readXmxxExcel(inputStream,t_xm_xmxx.getClass());//调用文件解析方法存入List集合result = this.jcsjService.insertXmxx(list);//调用插入数据的方法,this.jcsjService为该方法所在的类路径,可根据实际情况进行修改。mv.setViewName("rkgl/importfile");mv.addObject("result",result);}}return mv;//此方法的返回值为跳转到指定页面,并显示相关提示语,与文件导入操作无关。}

以上就是Excel文件上传功能的前端到后台所需进行的一系列操作,因本人才疏学浅,眼界及水平都有较大的局限性,文中难免存在漏洞,望各位大神多多指教。

Web项目的Excel文件上传、解析、导入相关推荐

  1. SSM项目的excel文件上传并添加到数据库

    SSM项目的excel文件上传并添加到数据库(新手,不足之处请多多指教) 基于学校的课设,要用到excel文件的上传和数据库导入,在网上找了好多demo,最后找到一篇使用poi的,经过修改后,可以正常 ...

  2. java实现excel文件上传并解析内容保存到数据库中

    基于struts框架的web项目中excel文件的上传导入到数据库中的java代码 原理:将要上传的文件已流的形式传到服务器,服务器中接收到文件数据流并生成文件到服务器指定位置,java解析服务器生成 ...

  3. java实现excel文件上传_java相关:SpringMVC下实现Excel文件上传下载

    java相关:SpringMVC下实现Excel文件上传下载 发布于 2020-6-21| 复制链接 摘记: 在实际应用中,经常会遇到上传Excel或者下载Excel的情况,比如导入数据.下载统计数据 ...

  4. Springboot+thymeleaf实现excel文件上传+后台数据搜索

    废话不多说,直接上代码 先说excel文件上传 用的是poi框架 先贴maven配置 <!-- poi导入excel文件--><dependency><groupId&g ...

  5. 记一次对DZ的渗透.(一句话木马与图片,文件上传解析漏洞)

    一.举例:St0rs Team 指剑碎星河分享 前言0X01 某日某帅正在使用着啊D 入侵百度的时候, 突然某位好友发来一条消息. "滴滴上车" 打开消息一看,说是要某帅帮忙日一个 ...

  6. java中excel文件上传

    java文件上传 excel文件上传的两种方式 1.使用ExcelsUtils上传文件 2.把文件转换成流上传(支持多sheet) 代码实现 第一种方式 ExcelsUtils.ReadMultipa ...

  7. 手动将web项目的class文件打成jar包,手动打jar包,java -cvf,IDE打包底层指令

    手动将web项目的class文件打成jar包. 我们的项目在使用IDE进行编译后,在项目的target目录下将会生成class文件.我们可以将class文件打成jar包. 使用的到命令为: 在targ ...

  8. 文本文件、Excel文件上传下传

    1.读取客户端Txt.Excel文件到内表:TEXT_CONVERT_XLS_TO_SAP TEXT_CONVERT_XLS_TO_SAP函数可以将本地的文本文件(列与列之间默认使用TAB键分开,但也 ...

  9. 7.3 MASS批量修改数据(Excel文件上传数据)

    7.3 MASS批量修改数据(Excel文件上传数据) 步骤1:输入事务码MASS进入 1处,输入需要修改的对象类型(参见对象类型清单) 2处,点击"执行"按钮 步骤2:选择需要修 ...

最新文章

  1. ArcGIS制图之Sub Points点抽稀
  2. 高颜值的神经网络可视化工具:3D、彩色、可定制,还能可视化参数重要性
  3. 【MYSQL】总结MySQL中对表内容的关联运算(join)
  4. Javascript特效:图片切换
  5. Winrunner经验
  6. VS2010专业版和旗舰版(中文版)下载
  7. NET Framework 精简版可以获得的常用功能
  8. 华为的计算机怎么没声音怎么办,笔记本电脑没有声音怎么办
  9. 计算机协同工作,计算机协同工作的几种关键技术
  10. 视频教程-【直通华为HCNA/HCNP系列R篇7】可靠性功能原理及配置与管理-华为认证
  11. python 汉字转拼音
  12. 【java校招你不知道的那些事儿】校招和社招的区别是什么?为什么不参加社招
  13. VIBE运动目标检测算法实现
  14. js中的定时器和计时器使用
  15. 学习诸如 Oculus Rift 等虚拟现实设备开发需要掌握哪些知识和技术?
  16. 堡垒机的作用与选型经验
  17. webstorm ps
  18. 解决特殊字符引起json解析错误--单引号、双引号转义
  19. Kubernetes - Kubernetes 组件
  20. safari中判断app是否安装

热门文章

  1. rhel8安装docker-ce
  2. 苹果系统安装虚拟机 Mac如何安装虚拟机教程
  3. Nexus升级、license安装和恢复密码
  4. 20189200余超 2018-2019-2 移动平台应用开发实践作项目代码分析
  5. 微信小程序新手入门教程
  6. Consider defining a bean of type ‘com.netflix.client.config.IClientConfig‘ in your configuration
  7. 网络socket编程实现并发服务器——多线程编程
  8. 驼峰命名法(CamelCase)和下划线命名法(UnderScoreCase)之间的转换
  9. react 返回上一页
  10. 新增X-Helios、X-Medusa算法研究