> 文章列表 > 十五、市场活动:excel导入

十五、市场活动:excel导入

十五、市场活动:excel导入

  功能需求

①用户在市场活动主页面,点击"导入"按钮,弹出导入市场活动的模态窗口;

②用户在导入市场活动的模态窗口选择要上传文件,点击"导入"按钮,完成导入市场活动的功能.

*只支持.xls

*文件大小不超过5MB

③导入成功之后,提示成功导入记录条数,关闭模态窗口,刷新市场活动列表,显示第一页数据,保持每页显示条数不变

④*导入失败,提示信息,模态窗口不关闭,列表也不刷新

功能分析

①把计算机的excel文件上传到服务器

②使用java解析excel文件,获取excel文件的数据

③解析出来的数据添加到数据库中

④返回响应信息

技术准备

①文件上传表单的三个条件

  • 表单组件标签使用<input type="file">
  • 请求方式是post:参数通过请求体提交后台,能提交文本数据和二进制数据,长度没限制。安全,效率低。
  • HTTP协议规定,浏览器向后台提交参数的时候,都会对参数进行统一编码。默认采用urlencoded,对文本数据进行编码成字符串。表单编码只能是multipart/form-data
<form action="url" method="post" enctype="multipart/form-data"><input type="file" name="myFile"><br><input type="text" name="username"><br><input type="submit" name="提交"><br>
</form>

②使用java解析excel文件

在mvc配置文件,MultipartFile activityFile。配置文件上传解析器 id:必须是multipartResolver

    <!-- 配置文件上传解析器 id:必须是multipartResolver--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="#{1024*1024*80}"/><property name="defaultEncoding" value="utf-8"/></bean>

poi插件

流程图

代码实现

一、ActivityMapper

1.在ActivityMapper的接口中,添加批量插入的按钮

    /***批量插入*/int insertActivityByList(List<Activity> activityList);

2.配置映射文件的sql语句

  • 插入的字段是id, owner, name, start_date, end_date, cost, description, create_time, create_by
  • 通过<foreach>标签进行遍历
  • 返回值是添加的条数
 <insert id="insertActivityByList">insert into tbl_activity (id, owner, name, start_date,end_date, cost, description,create_time, create_by)values<foreach collection="list" item="obj" separator=",">(#{obj.id},#{obj.owner},#{obj.name},#{obj.startDate},#{obj.endDate},#{obj.cost},#{obj.description},#{obj.createTime},#{obj.createBy})</foreach></insert>

二、ActivityService

	@Overridepublic int saveCreateActivityByList(List<Activity> activityList) {return activityMapper.insertActivityByList(activityList);}

三、ActivityController

1.通过session获取user,并且创建返回的Object

		// 1 通过session获取userUser user = (User) session.getAttribute(Contants.SESSION_USER);// 2 创建返回的ObjectReturnObject returnObject = new ReturnObject();

2.读取文件准备工作

			// 3.1 获取文件输入流InputStream is = activityFile.getInputStream();// 3.1 创建文件HSSFWorkbook wb = new HSSFWorkbook(is);// 3.2 获取excel表第一页的信息HSSFSheet sheet = wb.getSheetAt(0);// 3.3 创建行、列、接收的对象、接收的集合HSSFRow row = null;HSSFCell cell = null;Activity activity = null;List<Activity> activityList = new ArrayList<>();

3.通过循环读取文件内容--先获取行数--然后根据这个行,读取列

  • 获取行数是sheet.getLastRowNum(),获取这个行的内容sheet.getRow(i)
  • 通过Session的user,给发起者,创建者赋值user.id
  • 通过UUISUtils.getUUID()给活动的id赋值
  • 通过DateUtils.formateDateTime(new Date())创建时间
  • 通过表格设置的列,给activity实体类赋值。
  • 循环完一行后,activityList.add(activity)
	/*** 批量导入*/@RequestMapping("/workbench/activity/importActivities.do")public @ResponseBodyObject importActivities(MultipartFile activityFile, HttpSession session) {// 1 通过session获取userUser user = (User) session.getAttribute(Contants.SESSION_USER);// 2 创建返回的ObjectReturnObject returnObject = new ReturnObject();// 3 读取文件try {// 3.1 获取文件输入流InputStream is = activityFile.getInputStream();// 3.1 创建文件HSSFWorkbook wb = new HSSFWorkbook(is);// 3.2 获取excel表第一页的信息HSSFSheet sheet = wb.getSheetAt(0);// 3.3 创建行、列、接收的对象、接收的集合HSSFRow row = null;HSSFCell cell = null;Activity activity = null;List<Activity> activityList = new ArrayList<>();// 3.4 通过循环读取文件内容// 3.4.1 行数for (int i = 1; i < sheet.getLastRowNum(); i++) {// 3.4.2 读取此行row = sheet.getRow(i);// 3.4.3 创建activity对象activity = new Activity();activity.setId(UUIDUtils.getUUID());activity.setOwner(user.getId());activity.setCreateTime(DateUtils.formateDateTime(new Date()));activity.setCreateBy(user.getId());// 3.4.3 读取此行的所有列for (int j = 0; j < row.getLastCellNum(); j++) {// 3.4.4 读取此行的列的值cell = row.getCell(j);String cellValue = HSSFUtils.getCellValueForStr(cell);if (j == 0) {activity.setName(cellValue);} else if (j == 1) {activity.setStartDate(cellValue);} else if (j == 2) {activity.setEndDate(cellValue);} else if (j == 3) {activity.setCost(cellValue);} else {activity.setDescription(cellValue);}}activityList.add(activity);}// 4 调用serviceint ret = activityService.saveCreateActivityByList(activityList);if (ret > 0) {// 插入成功returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS);returnObject.setRetDate(ret);} else {// 插入失败returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);returnObject.setMessage("系统繁忙,稍后再试");}} catch (IOException e) {e.printStackTrace();// 插入失败returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);returnObject.setMessage("系统繁忙,稍后再试");}return returnObject;}

四、index.jsp

<input type="file" id="activityFile">

①、在js中,获取上传的文件名      var activityFileName = $("#activityFile").val();

②、获取上传的文件--$("#activityFile").get(0)获取DOM对象,然后可以上传多个文件,选取第一个文件files[0]----       var activityFile = $("#activityFile").get(0).files[0];

③、FormData上传文件,通过模拟K-V对向后台提交参数。FormData最大的优势是不但能提交文本数据,还能提交二进制数据

     var formData = new FormData();formData.append("activityFile", activityFile);

完整的js代码

$("#importOpenActivityBtn").click(function () {// 6.1 点击导入弹出导入框$("#importActivityModal").modal("show");// 6.2 点击导入按钮$("#importActivityBtn").click(function () {// 收集参数var activityFileName = $("#activityFile").val();// 截取文件类型var suffix = activityFileName.substr(activityFileName.lastIndexOf(".") + 1).toLocaleLowerCase();if (suffix != "xls") {alert("只支持xls文件");return;}// 获取文件--$("#activityFile").get(0)获取DOM对象,然后可以上传多个文件,选取第一个文件files[0]var activityFile = $("#activityFile").get(0).files[0];if (activityFile.size > 5 * 1024 * 1024) {alert("文件不能大于5MB");return;}// FormData是ajax提供的接口,可以模拟K-V对向后台提交参数;// FormData最大的优势是不但能提交文本数据,还能提交二进制数据var formData = new FormData();formData.append("activityFile", activityFile);// 发送请求$.ajax({url: 'workbench/activity/importActivities.do',data:formData,processData:false,// 不转换为字符串contentType:false,// 不编码type: 'post',dataType: 'json',success: function (data) {if (data.code == "1") {// 成功导入$("#importActivityModal").modal("hide");queryActivityByConditionForPage(1, $("#pagDiv").bs_pagination('getOption', 'rowsPerPage'));alert("成功导入" + data.retDate + "条数据");} else {alert(data.message);$("#importActivityModal").modal("show");}}});});});