十五、市场活动:excel导入

news2025/1/19 11:10:34

  功能需求

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

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

*只支持.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

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

三、ActivityController

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

		// 1 通过session获取user
		User user = (User) session.getAttribute(Contants.SESSION_USER);
		// 2 创建返回的Object
		ReturnObject 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 @ResponseBody
	Object importActivities(MultipartFile activityFile, HttpSession session) {
		// 1 通过session获取user
		User user = (User) session.getAttribute(Contants.SESSION_USER);
		// 2 创建返回的Object
		ReturnObject 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 调用service
			int 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");
                            }
                        }
                    });

                });

            });

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/422630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(只需三步)如何用chatgpt自动生成思维导图

目录 chatgpt是可以生成思维导图的&#xff01;只需三步&#xff0c;非常简单&#xff01; 第一步&#xff1a;打开chatgpt&#xff0c;告诉它主题 第二步&#xff0c;完善思维导图 第三步&#xff1a;查看思维导图的效果 chatgpt是可以生成思维导图的&#xff01;只需三步&am…

21天学会C++:Day1----C++的发展史

CSDN的uu们&#xff0c;大家好。这里是C入门的第一讲。 座右铭&#xff1a;前路坎坷&#xff0c;披荆斩棘&#xff0c;扶摇直上。 博客主页&#xff1a; 姬如祎 收录专栏&#xff1a;C专题 目录 1. 什么是C 2. C的发展史 3. C的重要性 4. 如何学好C 4.1 别人如何学C 4…

海睿思分享 | 制造业数字化转型之业务场景驱动

在开始谈业务场景驱动之前&#xff0c;我们先介绍一下流程驱动和数据驱动的概念。 首先数据和流程在现代制造业相辅相成&#xff0c;流程中有数据&#xff0c;数据往往通过流程传递&#xff0c;而“驱动”是通过建立一定的驱动机制&#xff0c;改变以往人为的业务推进模式&…

Android UI设计经验分享,掌握设计技巧,让你的应用独树一帜

Android UI渲染是指Android应用程序中的用户界面如何被绘制。Android UI渲染很重要&#xff0c;因为渲染过程直接影响应用程序的性能和用户体验。 当用户在Android应用程序中进行交互时&#xff0c;应用程序会相应地创建并更新UI元素&#xff0c;例如TextView、Button、ImageV…

速下载 | 12项网络与数据安全新国标全文公开

根据2023年3月17日国家市场监督管理总局、国家标准化管理委员会发布的中华人民共和国国家标准公告&#xff08;2023年第1号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的12项网络安全国家标准正式发布。近日标准全文正式公开&#xff0c;炼石第一时间搜集整理这…

极氪X上市,18.98万元起售,进军紧凑豪华车市场

HiEV消息&#xff08;文/Amy&#xff09;4月12日&#xff0c;纯电SUV极氪X上市&#xff0c;共发布三个版本&#xff0c;官方零售价为&#xff1a; •ME版 五座后驱 189,800元 •YOU版 五座四驱 209,800元 •YOU版 四座后驱 209,800元全系三款车型预计将于6月起开启交付。极氪X限…

【分布式技术专题】「单点登录技术架构」一文带领你好好对接对应的Okta单点登录实现接口服务的实现落地

什么是SAML协议 SAML&#xff08;Security Assertion Markup Language&#xff09;是一种基于XML的标准&#xff0c;用于在不同的安全域之间传递身份验证和授权数据。SAML2.0是SAML协议的最新版本&#xff0c;它提供了一种标准的方式来实现单点登录&#xff08;SSO&#xff09…

1.数据结构---时间复杂度+面试题:消失的数字

文章目录前言1.什么是数据结构?2.什么是算法?3.时间复杂度3.1 实例1:请计算一下Func1中count语句总共执行了多少次&#xff1f;大O的渐进表示法实例2:计算Func2的时间复杂度实例3:计算Func3的时间复杂度&#xff1f;实例4:计算Func4的时间复杂度&#xff1f;大O的渐进表示法总…

Activiti7原生整合和工作流相关概念详解

一、概述 Activiti是一个工作流引擎&#xff0c; Activiti可以将业务系统中复杂的业务流程抽取出来&#xff0c;并用专门的建模语言BPMN2.0进行定义&#xff0c;业务流程按照预先定义的流程进行执行&#xff0c;实现了系统的流程由Activiti进行管理&#xff0c;减少业务系统由…

C++ vasprintf

vasprintf 是一个 C 库函数&#xff0c;它可以通过可变参数创建一个格式化的字符串&#xff0c;并将其存储在动态分配的内存中。它的使用方法与 printf 类似&#xff0c;但它不会将结果打印到标准输出流中&#xff0c;而是将其存储在一个指向字符数组的指针中。 以下是 vasprin…

RFID技术在供应链管理中的应用

RFID是无线射频识别技术的简称&#xff0c;广泛应用于物流、制造、供应链等领域。在供应链管理中&#xff0c;RFID技术可以提供更加精确、实时的信息&#xff0c;帮助企业减少损耗和时间成本&#xff0c;提高效率和可靠性。本文将介绍RFID技术在供应链管理中的应用及其优势。 …

6.redis-集群

01-集群cluster 存在的问题 redis提供的服务OPS(operation per second)可以达到10万/秒&#xff0c;当前业务OPS如果超过10万/秒&#xff0c;怎么办&#xff1f; redis集群 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gITgqXr9-1681709270830)(n…

Nginx学习笔记 - 新

跟着 https://www.bilibili.com/video/BV1yS4y1N76R 视频学的 安装教程 nginx环境搭建 通过不同域名相同端口访问不同页面 首先添加hosts&#xff0c;映射下域名到装nginx的主机IP地址&#xff0c;我这里是虚拟机&#xff0c;且没有买域名就自己本地这样玩 进入nginx安装目…

【C语言学习3——基本的C语言语法知识1】

C语言学习3——基本的C语言语法知识主函数什么是主函数&#xff1f;写一个自己的函数主函数是整个C语言程序的入口要调用函数&#xff0c;必须先知道函数什么是变量&#xff1f;#include <stdio.h> int main() { printf("Hello World\n"); return 0; }相信你已…

科研人的R速成利器,读这两本就够了!

R 是数据科学领域的一门大热的编程语言&#xff0c;可以说它是专门为统计分析而生的。 相比起其他语言&#xff0c;R 简单易学&#xff0c;代码可读性强&#xff0c;并且不需要搭建复杂的编程环境&#xff0c;对初学者非常友好。 今天就和大家分享两本学习R的宝藏图书&#x…

【FPGA实验4】举重比赛机制

举重比赛有三名裁判&#xff0c;当运动员将杠铃举起后&#xff0c;须有两名或两名以上裁判认可&#xff0c;方可判定试举成功&#xff0c;若用A、B、C分别代表三名裁判的意见输入&#xff0c;同意为1&#xff0c;否定为0;F为裁判结果输出&#xff0c;试举成功时F1&#xff0c;试…

02-神经网络基础

一、从机器学习到神经网络 1. 两层神经网络 - 多层感知机 2. 浅层神经网络特点 (1)需要数据量小、训练速度快; (2)对复杂函数的表示能力有限,泛化能力受到制约。 Kurt Hornik 证明了理论上两层神经网络足以拟合任意函数,而且过去没有足够的数据和计算能力,因此之前的…

计算机组成原理实验1---运算器 预习报告

本实验为哈尔滨工业大学计算机组成原理实验&#xff0c;实验内容均为个人完成&#xff0c;目的是分享交流&#xff0c;如有抄袭将追究责任&#xff0c;笔者能力有限&#xff0c;若因此影响读者的分数&#xff0c;本人深表抱歉。 一、 实验目的 了解运算器的组成结构基于数据通…

ChatGPT 究竟在做什么?它为何能做到这些?(2)

机器学习和神经网络的训练 到目前为止&#xff0c;我们一直在讨论那些 “已经知道” 如何完成特定任务的神经网络。但是&#xff0c;神经网络之所以如此有用&#xff08;估计也是在大脑中&#xff09;&#xff0c;是因为它们不仅是可以完成各种任务&#xff0c;而且可以逐步 “…

数据 数据元素 数据项 数据对象

文章目录数据、数据元素、数据项和数据对象数据数据元素数据对象数据元素和数据对象数据结构数据结构包括以下三个方面的内容逻辑结构物理结构&#xff08;存储结构&#xff09;逻辑结构与存储结构的关系逻辑结构的种类集合结构线性结构树型结构图状结构或网状结构四种基本的存…