1.导出市场活动:
1)给”批量导出”按钮添加单击事件,发送导出请求
2)查询所有的市场活动
3)创建一个excel文件,并且把市场活动写到excel文件中
4)把生成的excel文件输出到浏览器(文件下载)

技术准备:
1)使用java生成excel文件:iText,apache-poi

  1. 关于办公文档插件使用的基本思想:把办公文档的所有元素封装成普通的Java类,<br /> 程序员通过操作这些类达到操作办公文档目的。<br /> 文件---------HSSFWorkbook<br /> 页-----------HSSFSheet<br /> 行-----------HSSFRow<br /> 列-----------HSSFCell<br /> 样式---------HSSFCellStyle
  2. 使用apache-poi生成excel:<br /> a)添加依赖:<br /> <dependency><br /> <groupId>org.apache.poi</groupId><br /> <artifactId>poi</artifactId><br /> <version>3.15</version><br /> </dependency><br /> b)使用封装类生成excel文件:<br /> <br /> 2.文件下载:<br /> filedownloadtest.jsp<br /> ActivityController<br /> |->fileDownload()
  3. *所有文件下载的请求只能发送同步请求。

一、导出市场活动流程图

导出市场活动.png

1.mapper层

image.png

  1. /**
  2. * 查询所有的市场活动
  3. * @return
  4. */
  5. List<Activity> selectAllActivitys();
  1. <select id="selectAllActivitys" resultMap="BaseResultMap">
  2. select a.id,u1.name as owner,a.name,a.start_date,a.end_date,a.cost,a.description,a.create_time,
  3. u2.name as create_by,a.edit_time,u3.name as edit_by
  4. from tbl_activity a
  5. join tbl_user u1 on a.owner=u1.id
  6. join tbl_user u2 on a.create_by=u2.id
  7. left join tbl_user u3 on a.edit_by=u3.id
  8. order by a.create_time desc
  9. </select>

2.service层

image.png

  1. List<Activity> queryAllActivitys();
  1. public List<Activity> queryAllActivitys() {
  2. return activityMapper.selectAllActivitys();
  3. }

3.controller层

  1. @RequestMapping("/workbench/activity/exportAllActivitys.do")
  2. public void exportAllActivitys(HttpServletResponse response) throws Exception{
  3. //调用service层方法,查询所有的市场活动
  4. List<Activity> activityList=activityService.queryAllActivitys();
  5. //创建exel文件,并且把activityList写入到excel文件中
  6. HSSFWorkbook wb=new HSSFWorkbook();
  7. HSSFSheet sheet=wb.createSheet("市场活动列表");
  8. HSSFRow row=sheet.createRow(0);
  9. HSSFCell cell=row.createCell(0);
  10. cell.setCellValue("ID");
  11. cell=row.createCell(1);
  12. cell.setCellValue("所有者");
  13. cell=row.createCell(2);
  14. cell.setCellValue("名称");
  15. cell=row.createCell(3);
  16. cell.setCellValue("开始日期");
  17. cell=row.createCell(4);
  18. cell.setCellValue("结束日期");
  19. cell=row.createCell(5);
  20. cell.setCellValue("成本");
  21. cell=row.createCell(6);
  22. cell.setCellValue("描述");
  23. cell=row.createCell(7);
  24. cell.setCellValue("创建时间");
  25. cell=row.createCell(8);
  26. cell.setCellValue("创建者");
  27. cell=row.createCell(9);
  28. cell.setCellValue("修改时间");
  29. cell=row.createCell(10);
  30. cell.setCellValue("修改者");
  31. //遍历activityList,创建HSSFRow对象,生成所有的数据行
  32. if(activityList!=null && activityList.size()>0){
  33. Activity activity=null;
  34. for(int i=0;i<activityList.size();i++){
  35. activity=activityList.get(i);
  36. //每遍历出一个activity,生成一行
  37. row=sheet.createRow(i+1);
  38. //每一行创建11列,每一列的数据从activity中获取
  39. cell=row.createCell(0);
  40. cell.setCellValue(activity.getId());
  41. cell=row.createCell(1);
  42. cell.setCellValue(activity.getOwner());
  43. cell=row.createCell(2);
  44. cell.setCellValue(activity.getName());
  45. cell=row.createCell(3);
  46. cell.setCellValue(activity.getStartDate());
  47. cell=row.createCell(4);
  48. cell.setCellValue(activity.getEndDate());
  49. cell=row.createCell(5);
  50. cell.setCellValue(activity.getCost());
  51. cell=row.createCell(6);
  52. cell.setCellValue(activity.getDescription());
  53. cell=row.createCell(7);
  54. cell.setCellValue(activity.getCreateTime());
  55. cell=row.createCell(8);
  56. cell.setCellValue(activity.getCreateBy());
  57. cell=row.createCell(9);
  58. cell.setCellValue(activity.getEditTime());
  59. cell=row.createCell(10);
  60. cell.setCellValue(activity.getEditBy());
  61. }
  62. }
  63. //根据wb对象生成excel文件
  64. /* OutputStream os=new FileOutputStream("D:\\course\\18-CRM\\阶段资料\\serverDir\\activityList.xls");
  65. wb.write(os);*/
  66. //关闭资源
  67. /*os.close();
  68. wb.close();*/
  69. //把生成的excel文件下载到客户端
  70. response.setContentType("application/octet-stream;charset=UTF-8");
  71. response.addHeader("Content-Disposition","attachment;filename=activityList.xls");
  72. OutputStream out=response.getOutputStream();
  73. /*InputStream is=new FileInputStream("D:\\course\\18-CRM\\阶段资料\\serverDir\\activityList.xls");
  74. byte[] buff=new byte[256];
  75. int len=0;
  76. while((len=is.read(buff))!=-1){
  77. out.write(buff,0,len);
  78. }
  79. is.close();*/
  80. wb.write(out);
  81. wb.close();
  82. out.flush();
  83. }

4.前端页面

image.png

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <%
  4. String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
  5. %>
  6. <html>
  7. <head>
  8. <base href="<%=basePath%>">
  9. <meta charset="UTF-8">
  10. <link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
  11. <link rel="stylesheet" type="text/css" href="jquery/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.min.css">
  12. <link rel="stylesheet" type="text/css" href="jquery/bs_pagination-master/css/jquery.bs_pagination.min.css">
  13. <script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
  14. <script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
  15. <script type="text/javascript" src="jquery/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.js"></script>
  16. <script type="text/javascript" src="jquery/bootstrap-datetimepicker-master/locale/bootstrap-datetimepicker.zh-CN.js"></script>
  17. <script type="text/javascript" src="jquery/bs_pagination-master/js/jquery.bs_pagination.min.js"></script>
  18. <script type="text/javascript" src="jquery/bs_pagination-master/localization/en.js"></script>
  19. <script type="text/javascript">
  20. $(function(){
  21. //给"创建"按钮添加单击事件
  22. $("#createActivityBtn").click(function () {
  23. //初始化工作
  24. //重置表单
  25. $("#createActivityForm").get(0).reset();
  26. //弹出创建市场活动的模态窗口
  27. $("#createActivityModal").modal("show");
  28. });
  29. //给"保存"按钮添加单击事件
  30. $("#saveCreateActivityBtn").click(function () {
  31. //收集参数
  32. var owner=$("#create-marketActivityOwner").val();
  33. var name=$.trim($("#create-marketActivityName").val());
  34. var startDate=$("#create-startDate").val();
  35. var endDate=$("#create-endDate").val();
  36. var cost=$.trim($("#create-cost").val());
  37. var description=$.trim($("#create-description").val());
  38. //表单验证
  39. if(owner==""){
  40. alert("所有者不能为空");
  41. return;
  42. }
  43. if(name==""){
  44. alert("名称不能为空");
  45. return;
  46. }
  47. if(startDate!=""&&endDate!=""){
  48. //使用字符串的大小代替日期的大小
  49. if(endDate<startDate){
  50. alert("结束日期不能比开始日期小");
  51. return;
  52. }
  53. }
  54. /*
  55. 正则表达式:
  56. 1,语言,语法:定义字符串的匹配模式,可以用来判断指定的具体字符串是否符合匹配模式。
  57. 2,语法通则:
  58. 1)//:在js中定义一个正则表达式. var regExp=/...../;
  59. 2)^:匹配字符串的开头位置
  60. $: 匹配字符串的结尾
  61. 3)[]:匹配指定字符集中的一位字符。 var regExp=/^[abc]$/;
  62. var regExp=/^[a-z0-9]$/;
  63. 4){}:匹配次数.var regExp=/^[abc]{5}$/;
  64. {m}:匹配m此
  65. {m,n}:匹配m次到n次
  66. {m,}:匹配m次或者更多次
  67. 5)特殊符号:
  68. \d:匹配一位数字,相当于[0-9]
  69. \D:匹配一位非数字
  70. \w:匹配所有字符,包括字母、数字、下划线。
  71. \W:匹配非字符,除了字母、数字、下划线之外的字符。
  72. *:匹配0次或者多次,相当于{0,}
  73. +:匹配1次或者多次,相当于{1,}
  74. ?:匹配0次或者1次,相当于{0,1}
  75. */
  76. var regExp=/^(([1-9]\d*)|0)$/;
  77. if(!regExp.test(cost)){
  78. alert("成本只能为非负整数");
  79. return;
  80. }
  81. //发送请求
  82. $.ajax({
  83. url:'workbench/activity/saveCreateActivity.do',
  84. data:{
  85. owner:owner,
  86. name:name,
  87. startDate:startDate,
  88. endDate:endDate,
  89. cost:cost,
  90. description:description
  91. },
  92. type:'post',
  93. dataType:'json',
  94. success:function (data) {
  95. if(data.code=="1"){
  96. //关闭模态窗口
  97. $("#createActivityModal").modal("hide");
  98. //刷新市场活动列,显示第一页数据,保持每页显示条数不变
  99. queryActivityByConditionForPage(1,$("#demo_pag1").bs_pagination('getOption', 'rowsPerPage'));
  100. }else{
  101. //提示信息
  102. alert(data.message);
  103. //模态窗口不关闭
  104. $("#createActivityModal").modal("show");//可以不写。
  105. }
  106. }
  107. });
  108. });
  109. //当容器加载完成之后,对容器调用工具函数
  110. //$("input[name='mydate']").datetimepicker({
  111. $(".mydate").datetimepicker({
  112. language:'zh-CN', //语言
  113. format:'yyyy-mm-dd',//日期的格式
  114. minView:'month', //可以选择的最小视图
  115. initialDate:new Date(),//初始化显示的日期
  116. autoclose:true,//设置选择完日期或者时间之后,日否自动关闭日历
  117. todayBtn:true,//设置是否显示"今天"按钮,默认是false
  118. clearBtn:true//设置是否显示"清空"按钮,默认是false
  119. });
  120. //当市场活动主页面加载完成,查询所有数据的第一页以及所有数据的总条数,默认每页显示10条
  121. queryActivityByConditionForPage(1,10);
  122. //给"查询"按钮添加单击事件
  123. $("#queryActivityBtn").click(function () {
  124. //查询所有符合条件数据的第一页以及所有符合条件数据的总条数;
  125. queryActivityByConditionForPage(1,$("#demo_pag1").bs_pagination('getOption', 'rowsPerPage'));
  126. });
  127. //给"全选"按钮添加单击事件
  128. $("#chckAll").click(function () {
  129. //如果"全选"按钮是选中状态,则列表中所有checkbox都选中
  130. /*if(this.checked==true){
  131. $("#tBody input[type='checkbox']").prop("checked",true);
  132. }else{
  133. $("#tBody input[type='checkbox']").prop("checked",false);
  134. }*/
  135. $("#tBody input[type='checkbox']").prop("checked",this.checked);
  136. });
  137. /*$("#tBody input[type='checkbox']").click(function () {
  138. //如果列表中的所有checkbox都选中,则"全选"按钮也选中
  139. if($("#tBody input[type='checkbox']").size()==$("#tBody input[type='checkbox']:checked").size()){
  140. $("#chckAll").prop("checked",true);
  141. }else{//如果列表中的所有checkbox至少有一个没选中,则"全选"按钮也取消
  142. $("#chckAll").prop("checked",false);
  143. }
  144. });*/
  145. $("#tBody").on("click","input[type='checkbox']",function () {
  146. //如果列表中的所有checkbox都选中,则"全选"按钮也选中
  147. if($("#tBody input[type='checkbox']").size()==$("#tBody input[type='checkbox']:checked").size()){
  148. $("#chckAll").prop("checked",true);
  149. }else{//如果列表中的所有checkbox至少有一个没选中,则"全选"按钮也取消
  150. $("#chckAll").prop("checked",false);
  151. }
  152. });
  153. //给"删除"按钮添加单击事件
  154. $("#deleteActivityBtn").click(function () {
  155. //收集参数
  156. //获取列表中所有被选中的checkbox
  157. var chekkedIds=$("#tBody input[type='checkbox']:checked");
  158. if(chekkedIds.size()==0){
  159. alert("请选择要删除的市场活动");
  160. return;
  161. }
  162. if(window.confirm("确定删除吗?")){
  163. var ids="";
  164. $.each(chekkedIds,function () {//id=xxxx&id=xxx&.....&id=xxx&
  165. ids+="id="+this.value+"&";
  166. });
  167. ids=ids.substr(0,ids.length-1);//id=xxxx&id=xxx&.....&id=xxx
  168. //发送请求
  169. $.ajax({
  170. url:'workbench/activity/deleteActivityIds.do',
  171. data:ids,
  172. type:'post',
  173. dataType:'json',
  174. success:function (data) {
  175. if(data.code=="1"){
  176. //刷新市场活动列表,显示第一页数据,保持每页显示条数不变
  177. queryActivityByConditionForPage(1,$("#demo_pag1").bs_pagination('getOption', 'rowsPerPage'));
  178. }else{
  179. //提示信息
  180. alert(data.message);
  181. }
  182. }
  183. });
  184. }
  185. });
  186. //给"修改"按钮添加单击事件
  187. $("#editActivityBtn").click(function () {
  188. //收集参数
  189. //获取列表中被选中的checkbox
  190. var chkedIds=$("#tBody input[type='checkbox']:checked");
  191. if(chkedIds.size()==0){
  192. alert("请选择要修改的市场活动");
  193. return;
  194. }
  195. if(chkedIds.size()>1){
  196. alert("每次只能修改一条市场活动");
  197. return;
  198. }
  199. //var id=chkedIds.val();
  200. //var id=chkedIds.get(0).value;
  201. var id=chkedIds[0].value;
  202. //发送请求
  203. $.ajax({
  204. url:'workbench/activity/queryActivityById.do',
  205. data:{
  206. id:id
  207. },
  208. type:'post',
  209. dataType:'json',
  210. success:function (data) {
  211. //把市场活动的信息显示在修改的模态窗口上
  212. $("#edit-id").val(data.id);
  213. $("#edit-marketActivityOwner").val(data.owner);
  214. $("#edit-marketActivityName").val(data.name);
  215. $("#edit-startTime").val(data.startDate);
  216. $("#edit-endTime").val(data.endDate);
  217. $("#edit-cost").val(data.cost);
  218. $("#edit-description").val(data.description);
  219. //弹出模态窗口
  220. $("#editActivityModal").modal("show");
  221. }
  222. });
  223. });
  224. //给"更新"按钮添加单击事件
  225. $("#saveEditActivityBtn").click(function () {
  226. //收集参数
  227. var id=$("#edit-id").val();
  228. var owner=$("#edit-marketActivityOwner").val();
  229. var name=$.trim($("#edit-marketActivityName").val());
  230. var startDate=$("#edit-startTime").val();
  231. var endDate=$("#edit-endTime").val();
  232. var cost=$.trim($("#edit-cost").val());
  233. var description=$.trim($("#edit-description").val());
  234. //表单验证(作业)
  235. //发送请求
  236. $.ajax({
  237. url:'workbench/activity/saveEditActivity.do',
  238. data:{
  239. id:id,
  240. owner:owner,
  241. name:name,
  242. startDate:startDate,
  243. endDate:endDate,
  244. cost:cost,
  245. description:description
  246. },
  247. type:'post',
  248. dataType:'json',
  249. success:function (data) {
  250. if(data.code=="1"){
  251. //关闭模态窗口
  252. $("#editActivityModal").modal("hide");
  253. //刷新市场活动列表,保持页号和每页显示条数都不变
  254. queryActivityByConditionForPage($("#demo_pag1").bs_pagination('getOption', 'currentPage'),$("#demo_pag1").bs_pagination('getOption', 'rowsPerPage'));
  255. }else{
  256. //提示信息
  257. alert(data.message);
  258. //模态窗口不关闭
  259. $("#editActivityModal").modal("show");
  260. }
  261. }
  262. });
  263. });
  264. //给"批量导出"按钮添加单击事件
  265. $("#exportActivityAllBtn").click(function () {
  266. //发送同步请求
  267. window.location.href="workbench/activity/exportAllActivitys.do";
  268. });
  269. //给"导入"按钮添加单击事件
  270. $("#importActivityBtn").click(function () {
  271. //收集参数
  272. var activityFileName=$("#activityFile").val();
  273. var suffix=activityFileName.substr(activityFileName.lastIndexOf(".")+1).toLocaleLowerCase();//xls,XLS,Xls,xLs,....
  274. if(suffix!="xls"){
  275. alert("只支持xls文件");
  276. return;
  277. }
  278. var activityFile=$("#activityFile")[0].files[0];
  279. if(activityFile.size>5*1024*1024){
  280. alert("文件大小不超过5MB");
  281. return;
  282. }
  283. //FormData是ajax提供的接口,可以模拟键值对向后台提交参数;
  284. //FormData最大的优势是不但能提交文本数据,还能提交二进制数据
  285. var formData=new FormData();
  286. formData.append("activityFile",activityFile);
  287. formData.append("userName","张三");
  288. //发送请求
  289. $.ajax({
  290. url:'workbench/activity/importActivity.do',
  291. data:formData,
  292. processData:false,//设置ajax向后台提交参数之前,是否把参数统一转换成字符串:true--是,false--不是,默认是true
  293. contentType:false,//设置ajax向后台提交参数之前,是否把所有的参数统一按urlencoded编码:true--是,false--不是,默认是true
  294. type:'post',
  295. dataType:'json',
  296. success:function (data) {
  297. if(data.code=="1"){
  298. //提示成功导入记录条数
  299. alert("成功导入"+data.retData+"条记录");
  300. //关闭模态窗口
  301. $("#importActivityModal").modal("hide");
  302. //刷新市场活动列表,显示第一页数据,保持每页显示条数不变
  303. queryActivityByConditionForPage(1,$("#demo_pag1").bs_pagination('getOption', 'rowsPerPage'));
  304. }else{
  305. //提示信息
  306. alert(data.message);
  307. //模态窗口不关闭
  308. $("#importActivityModal").modal("show");
  309. }
  310. }
  311. });
  312. });
  313. });
  314. function queryActivityByConditionForPage(pageNo,pageSize) {
  315. //收集参数
  316. var name=$("#query-name").val();
  317. var owner=$("#query-owner").val();
  318. var startDate=$("#query-startDate").val();
  319. var endDate=$("#query-endDate").val();
  320. //var pageNo=1;
  321. //var pageSize=10;
  322. //发送请求
  323. $.ajax({
  324. url:'workbench/activity/queryActivityByConditionForPage.do',
  325. data:{
  326. name:name,
  327. owner:owner,
  328. startDate:startDate,
  329. endDate:endDate,
  330. pageNo:pageNo,
  331. pageSize:pageSize
  332. },
  333. type:'post',
  334. dataType:'json',
  335. success:function (data) {
  336. //显示总条数
  337. //$("#totalRowsB").text(data.totalRows);
  338. //显示市场活动的列表
  339. //遍历activityList,拼接所有行数据
  340. var htmlStr="";
  341. $.each(data.activityList,function (index,obj) {
  342. htmlStr+="<tr class=\"active\">";
  343. htmlStr+="<td><input type=\"checkbox\" value=\""+obj.id+"\"/></td>";
  344. htmlStr+="<td><a style=\"text-decoration: none; cursor: pointer;\" onclick=\"window.location.href='detail.html';\">"+obj.name+"</a></td>";
  345. htmlStr+="<td>"+obj.owner+"</td>";
  346. htmlStr+="<td>"+obj.startDate+"</td>";
  347. htmlStr+="<td>"+obj.endDate+"</td>";
  348. htmlStr+="</tr>";
  349. });
  350. $("#tBody").html(htmlStr);
  351. //取消"全选"按钮
  352. $("#chckAll").prop("checked",false);
  353. //计算总页数
  354. var totalPages=1;
  355. if(data.totalRows%pageSize==0){
  356. totalPages=data.totalRows/pageSize;
  357. }else{
  358. totalPages=parseInt(data.totalRows/pageSize)+1;
  359. }
  360. //对容器调用bs_pagination工具函数,显示翻页信息
  361. $("#demo_pag1").bs_pagination({
  362. currentPage:pageNo,//当前页号,相当于pageNo
  363. rowsPerPage:pageSize,//每页显示条数,相当于pageSize
  364. totalRows:data.totalRows,//总条数
  365. totalPages: totalPages, //总页数,必填参数.
  366. visiblePageLinks:5,//最多可以显示的卡片数
  367. showGoToPage:true,//是否显示"跳转到"部分,默认true--显示
  368. showRowsPerPage:true,//是否显示"每页显示条数"部分。默认true--显示
  369. showRowsInfo:true,//是否显示记录的信息,默认true--显示
  370. //用户每次切换页号,都自动触发本函数;
  371. //每次返回切换页号之后的pageNo和pageSize
  372. onChangePage: function(event,pageObj) { // returns page_num and rows_per_page after a link has clicked
  373. //js代码
  374. //alert(pageObj.currentPage);
  375. //alert(pageObj.rowsPerPage);
  376. queryActivityByConditionForPage(pageObj.currentPage,pageObj.rowsPerPage);
  377. }
  378. });
  379. }
  380. });
  381. }
  382. </script>
  383. </head>
  384. <body>
  385. <!-- 创建市场活动的模态窗口 -->
  386. <div class="modal fade" id="createActivityModal" role="dialog">
  387. <div class="modal-dialog" role="document" style="width: 85%;">
  388. <div class="modal-content">
  389. <div class="modal-header">
  390. <button type="button" class="close" data-dismiss="modal">
  391. <span aria-hidden="true">×</span>
  392. </button>
  393. <h4 class="modal-title" id="myModalLabel1">创建市场活动</h4>
  394. </div>
  395. <div class="modal-body">
  396. <form id="createActivityForm" class="form-horizontal" role="form">
  397. <div class="form-group">
  398. <label for="create-marketActivityOwner" class="col-sm-2 control-label">所有者<span style="font-size: 15px; color: red;">*</span></label>
  399. <div class="col-sm-10" style="width: 300px;">
  400. <select class="form-control" id="create-marketActivityOwner">
  401. <c:forEach items="${userList}" var="u">
  402. <option value="${u.id}">${u.name}</option>
  403. </c:forEach>
  404. </select>
  405. </div>
  406. <label for="create-marketActivityName" class="col-sm-2 control-label">名称<span style="font-size: 15px; color: red;">*</span></label>
  407. <div class="col-sm-10" style="width: 300px;">
  408. <input type="text" class="form-control" id="create-marketActivityName">
  409. </div>
  410. </div>
  411. <div class="form-group">
  412. <label for="create-startDate" class="col-sm-2 control-label">开始日期</label>
  413. <div class="col-sm-10" style="width: 300px;">
  414. <input type="text" class="form-control mydate" name="mydate" id="create-startDate" readonly>
  415. </div>
  416. <label for="create-endDate" class="col-sm-2 control-label">结束日期</label>
  417. <div class="col-sm-10" style="width: 300px;">
  418. <input type="text" class="form-control mydate" name="mydate" id="create-endDate" readonly>
  419. </div>
  420. </div>
  421. <div class="form-group">
  422. <label for="create-cost" class="col-sm-2 control-label">成本</label>
  423. <div class="col-sm-10" style="width: 300px;">
  424. <input type="text" class="form-control" id="create-cost">
  425. </div>
  426. </div>
  427. <div class="form-group">
  428. <label for="create-description" class="col-sm-2 control-label">描述</label>
  429. <div class="col-sm-10" style="width: 81%;">
  430. <textarea class="form-control" rows="3" id="create-description"></textarea>
  431. </div>
  432. </div>
  433. </form>
  434. </div>
  435. <div class="modal-footer">
  436. <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
  437. <button type="button" class="btn btn-primary" id="saveCreateActivityBtn">保存</button>
  438. </div>
  439. </div>
  440. </div>
  441. </div>
  442. <!-- 修改市场活动的模态窗口 -->
  443. <div class="modal fade" id="editActivityModal" role="dialog">
  444. <div class="modal-dialog" role="document" style="width: 85%;">
  445. <div class="modal-content">
  446. <div class="modal-header">
  447. <button type="button" class="close" data-dismiss="modal">
  448. <span aria-hidden="true">×</span>
  449. </button>
  450. <h4 class="modal-title" id="myModalLabel2">修改市场活动</h4>
  451. </div>
  452. <div class="modal-body">
  453. <form class="form-horizontal" role="form">
  454. <input type="hidden" id="edit-id">
  455. <div class="form-group">
  456. <label for="edit-marketActivityOwner" class="col-sm-2 control-label">所有者<span style="font-size: 15px; color: red;">*</span></label>
  457. <div class="col-sm-10" style="width: 300px;">
  458. <select class="form-control" id="edit-marketActivityOwner">
  459. <c:forEach items="${userList}" var="u">
  460. <option value="${u.id}">${u.name}</option>
  461. </c:forEach>
  462. </select>
  463. </div>
  464. <label for="edit-marketActivityName" class="col-sm-2 control-label">名称<span style="font-size: 15px; color: red;">*</span></label>
  465. <div class="col-sm-10" style="width: 300px;">
  466. <input type="text" class="form-control" id="edit-marketActivityName" value="发传单">
  467. </div>
  468. </div>
  469. <div class="form-group">
  470. <label for="edit-startTime" class="col-sm-2 control-label">开始日期</label>
  471. <div class="col-sm-10" style="width: 300px;">
  472. <input type="text" class="form-control" id="edit-startTime" value="2020-10-10">
  473. </div>
  474. <label for="edit-endTime" class="col-sm-2 control-label">结束日期</label>
  475. <div class="col-sm-10" style="width: 300px;">
  476. <input type="text" class="form-control" id="edit-endTime" value="2020-10-20">
  477. </div>
  478. </div>
  479. <div class="form-group">
  480. <label for="edit-cost" class="col-sm-2 control-label">成本</label>
  481. <div class="col-sm-10" style="width: 300px;">
  482. <input type="text" class="form-control" id="edit-cost" value="5,000">
  483. </div>
  484. </div>
  485. <div class="form-group">
  486. <label for="edit-description" class="col-sm-2 control-label">描述</label>
  487. <div class="col-sm-10" style="width: 81%;">
  488. <textarea class="form-control" rows="3" id="edit-description">市场活动Marketing,是指品牌主办或参与的展览会议与公关市场活动,包括自行主办的各类研讨会、客户交流会、演示会、新产品发布会、体验会、答谢会、年会和出席参加并布展或演讲的展览会、研讨会、行业交流会、颁奖典礼等</textarea>
  489. </div>
  490. </div>
  491. </form>
  492. </div>
  493. <div class="modal-footer">
  494. <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
  495. <button type="button" class="btn btn-primary" id="saveEditActivityBtn">更新</button>
  496. </div>
  497. </div>
  498. </div>
  499. </div>
  500. <!-- 导入市场活动的模态窗口 -->
  501. <div class="modal fade" id="importActivityModal" role="dialog">
  502. <div class="modal-dialog" role="document" style="width: 85%;">
  503. <div class="modal-content">
  504. <div class="modal-header">
  505. <button type="button" class="close" data-dismiss="modal">
  506. <span aria-hidden="true">×</span>
  507. </button>
  508. <h4 class="modal-title" id="myModalLabel">导入市场活动</h4>
  509. </div>
  510. <div class="modal-body" style="height: 350px;">
  511. <div style="position: relative;top: 20px; left: 50px;">
  512. 请选择要上传的文件:<small style="color: gray;">[仅支持.xls]</small>
  513. </div>
  514. <div style="position: relative;top: 40px; left: 50px;">
  515. <input type="file" id="activityFile">
  516. </div>
  517. <div style="position: relative; width: 400px; height: 320px; left: 45% ; top: -40px;" >
  518. <h3>重要提示</h3>
  519. <ul>
  520. <li>操作仅针对Excel,仅支持后缀名为XLS的文件。</li>
  521. <li>给定文件的第一行将视为字段名。</li>
  522. <li>请确认您的文件大小不超过5MB。</li>
  523. <li>日期值以文本形式保存,必须符合yyyy-MM-dd格式。</li>
  524. <li>日期时间以文本形式保存,必须符合yyyy-MM-dd HH:mm:ss的格式。</li>
  525. <li>默认情况下,字符编码是UTF-8 (统一码),请确保您导入的文件使用的是正确的字符编码方式。</li>
  526. <li>建议您在导入真实数据之前用测试文件测试文件导入功能。</li>
  527. </ul>
  528. </div>
  529. </div>
  530. <div class="modal-footer">
  531. <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
  532. <button id="importActivityBtn" type="button" class="btn btn-primary">导入</button>
  533. </div>
  534. </div>
  535. </div>
  536. </div>
  537. <div>
  538. <div style="position: relative; left: 10px; top: -10px;">
  539. <div class="page-header">
  540. <h3>市场活动列表</h3>
  541. </div>
  542. </div>
  543. </div>
  544. <div style="position: relative; top: -20px; left: 0px; width: 100%; height: 100%;">
  545. <div style="width: 100%; position: absolute;top: 5px; left: 10px;">
  546. <div class="btn-toolbar" role="toolbar" style="height: 80px;">
  547. <form class="form-inline" role="form" style="position: relative;top: 8%; left: 5px;">
  548. <div class="form-group">
  549. <div class="input-group">
  550. <div class="input-group-addon">名称</div>
  551. <input class="form-control" type="text" id="query-name">
  552. </div>
  553. </div>
  554. <div class="form-group">
  555. <div class="input-group">
  556. <div class="input-group-addon">所有者</div>
  557. <input class="form-control" type="text" id="query-owner">
  558. </div>
  559. </div>
  560. <div class="form-group">
  561. <div class="input-group">
  562. <div class="input-group-addon">开始日期</div>
  563. <input class="form-control" type="text" id="query-startDate" />
  564. </div>
  565. </div>
  566. <div class="form-group">
  567. <div class="input-group">
  568. <div class="input-group-addon">结束日期</div>
  569. <input class="form-control" type="text" id="query-endDate">
  570. </div>
  571. </div>
  572. <button type="button" class="btn btn-default" id="queryActivityBtn">查询</button>
  573. </form>
  574. </div>
  575. <div class="btn-toolbar" role="toolbar" style="background-color: #F7F7F7; height: 50px; position: relative;top: 5px;">
  576. <div class="btn-group" style="position: relative; top: 18%;">
  577. <button type="button" class="btn btn-primary" id="createActivityBtn"><span class="glyphicon glyphicon-plus"></span> 创建</button>
  578. <button type="button" class="btn btn-default" id="editActivityBtn"><span class="glyphicon glyphicon-pencil"></span> 修改</button>
  579. <button type="button" class="btn btn-danger" id="deleteActivityBtn"><span class="glyphicon glyphicon-minus"></span> 删除</button>
  580. </div>
  581. <div class="btn-group" style="position: relative; top: 18%;">
  582. <button type="button" class="btn btn-default" data-toggle="modal" data-target="#importActivityModal" ><span class="glyphicon glyphicon-import"></span> 上传列表数据(导入)</button>
  583. <button id="exportActivityAllBtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-export"></span> 下载列表数据(批量导出)</button>
  584. <button id="exportActivityXzBtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-export"></span> 下载列表数据(选择导出)</button>
  585. </div>
  586. </div>
  587. <div style="position: relative;top: 10px;">
  588. <table class="table table-hover">
  589. <thead>
  590. <tr style="color: #B3B3B3;">
  591. <td><input type="checkbox" id="chckAll"/></td>
  592. <td>名称</td>
  593. <td>所有者</td>
  594. <td>开始日期</td>
  595. <td>结束日期</td>
  596. </tr>
  597. </thead>
  598. <tbody id="tBody">
  599. <%--<tr class="active">
  600. <td><input type="checkbox" /></td>
  601. <td><a style="text-decoration: none; cursor: pointer;" onclick="window.location.href='detail.html';">发传单</a></td>
  602. <td>zhangsan</td>
  603. <td>2020-10-10</td>
  604. <td>2020-10-20</td>
  605. </tr>
  606. <tr class="active">
  607. <td><input type="checkbox" /></td>
  608. <td><a style="text-decoration: none; cursor: pointer;" onclick="window.location.href='detail.html';">发传单</a></td>
  609. <td>zhangsan</td>
  610. <td>2020-10-10</td>
  611. <td>2020-10-20</td>
  612. </tr>--%>
  613. </tbody>
  614. </table>
  615. <div id="demo_pag1"></div>
  616. </div>
  617. <%--<div style="height: 50px; position: relative;top: 30px;">
  618. <div>
  619. <button type="button" class="btn btn-default" style="cursor: default;">共<b id="totalRowsB">50</b>条记录</button>
  620. </div>
  621. <div class="btn-group" style="position: relative;top: -34px; left: 110px;">
  622. <button type="button" class="btn btn-default" style="cursor: default;">显示</button>
  623. <div class="btn-group">
  624. <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
  625. 10
  626. <span class="caret"></span>
  627. </button>
  628. <ul class="dropdown-menu" role="menu">
  629. <li><a href="#">20</a></li>
  630. <li><a href="#">30</a></li>
  631. </ul>
  632. </div>
  633. <button type="button" class="btn btn-default" style="cursor: default;">条/页</button>
  634. </div>
  635. <div style="position: relative;top: -88px; left: 285px;">
  636. <nav>
  637. <ul class="pagination">
  638. <li class="disabled"><a href="#">首页</a></li>
  639. <li class="disabled"><a href="#">上一页</a></li>
  640. <li class="active"><a href="#">1</a></li>
  641. <li><a href="#">2</a></li>
  642. <li><a href="#">3</a></li>
  643. <li><a href="#">4</a></li>
  644. <li><a href="#">5</a></li>
  645. <li><a href="#">下一页</a></li>
  646. <li class="disabled"><a href="#">末页</a></li>
  647. </ul>
  648. </nav>
  649. </div>
  650. </div>--%>
  651. </div>
  652. </div>
  653. </body>
  654. </html>

image.png

二、导入市场活动

1.文件上传演示

1,导入市场活动:

1)把用户计算机上的excel文件上传到服务器(文件上传)
2)使用java解析excel文件,获取excel文件中的数据
3)把解析出来的数据添加数据库中
4)返回响应信息

技术准备:
1)文件上传:
fileuploadtest.jsp
ActivityController
|->fileUpload()
2)使用java解析excel文件:iText,apache-poi

关于办公文档插件使用的基本思想:把办公文档的所有元素封装成普通的Java类,
程序员通过操作这些类达到操作办公文档目的。
文件————-HSSFWorkbook
页—————-HSSFSheet
行—————-HSSFRow
列—————-HSSFCell

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <%
  3. String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
  4. %>
  5. <html>
  6. <head>
  7. <base href="<%=basePath%>">
  8. <title>演示文件上传</title>
  9. </head>
  10. <body>
  11. <!--
  12. 文件上传的表单三个条件:
  13. 1.表单组件标签必须用:<input type="file">
  14. <input type="text|password|radio|checkbox|hidden|button|submit|reset|file">
  15. <select>,<textarea>等
  16. 2.请求方式只能用:post
  17. get:参数通过请求头提交到后台,参数放在URL后边;只能向后台提交文本数据;对参数长度有限制;数据不安全;效率高
  18. post:参数通过请求体提交到后台;既能能提交文件数据,又能够提交二进制数据;理论上对参数长度没有限制;相对安全;效率相对较低
  19. 3.表单的编码格式只能用:multipart/form-data
  20. 根据HTTP协议的规定,浏览器每次向后台提交参数,都会对参数进行统一编码;默认采用的编码格式是urlencoded,这种编码格式只能对文本数据进行编码;
  21. 浏览器每次向后台提交参数,都会首先把所有的参数转换成字符串,然后对这些数据统一进行urlencoded编码;
  22. 文件上传的表单编码格式只能用multipart/form-data:enctype="multipart/form-data"
  23. -->
  24. <form action="workbench/activity/fileUpload.do" method="post" enctype="multipart/form-data">
  25. <input type="file" name="myFile"><br>
  26. <input type="text" name="userName"><br>
  27. <input type="submit" value="提交">
  28. </form>
  29. </body>
  30. </html>
  1. /**
  2. * 配置springmvc的文件上传解析器
  3. *
  4. */
  5. @RequestMapping("/workbench/activity/fileUpload.do")
  6. public @ResponseBody Object fileUpload(String userName, MultipartFile myFile) throws Exception{
  7. //把文本数据打印到控制台
  8. System.out.println("userName="+userName);
  9. //把文件在服务指定的目录中生成一个同样的文件
  10. String originalFilename=myFile.getOriginalFilename();
  11. File file=new File("D:\\course\\18-CRM\\阶段资料\\serverDir\\",originalFilename);//路径必须手动创建好,文件如果不存在,会自动创建
  12. myFile.transferTo(file);
  13. //返回响应信息
  14. ReturnObject returnObject=new ReturnObject();
  15. returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS);
  16. returnObject.setMessage("上传成功");
  17. return returnObject;
  18. }
  1. <!-- 配置文件上传解析器 id:必须是multipartResolver-->
  2. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  3. <property name="maxUploadSize" value="#{1024*1024*5}"/>
  4. <property name="defaultEncoding" value="utf-8"/>
  5. </bean>