使用的依赖
poi,文件下载插件,commons-fileupload文件上传插件
<!--poi-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
文件下载
注意:这里在bootstrap中批量下载,只能使用传统请求
前台请求
<script>
$("#exportActivityAllBtn").click(function () {
if (confirm("确定导出所有记录吗?")) {
window.location.href = "workbench/activity/exportActivityAll.do";
}
})
</script>
<body>
<button id="exportActivityAllBtn" type="button" class="btn btn-default"><span
class="glyphicon glyphicon-export"></span> 下载列表数据(批量导出)
</button>
</body>
后台响应
- 查询所有的数据信息,放到list中
- 创建Excel文件HSSFWork,在用文件对象创建sheet页对象,再用页对象创建行对象rows,用行对象创建单元格对象(列对象)。createRow(index)与createCell(index),这里的index都是从0开始的。0表示第一条。cell.setCellValue(“字段名/字段值”);使用循环遍历list,设置值。使用response对象为客户浏览器提供下载框:response.setContentType(“octets/stream”);
response.setHeader(“Content-Disposition”, “attachment;filename=Activity-” + DateTimeUtil.getSysTime() + “.xls”);//将文件头信息放在响应头中,使用OutputStream对象返回数据,workbook.write(out);
controller
//全部导出
@RequestMapping("/exportActivityAll.do")
public void exportActivityAll(HttpServletResponse response) throws AjaxRequestException {
List<Activity> activityList = service.getActivityList();
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue("id");
cell = row.createCell(1);
cell.setCellValue("owner");
cell = row.createCell(2);
cell.setCellValue("name");
cell = row.createCell(3);
cell.setCellValue("startDate");
cell = row.createCell(4);
cell.setCellValue("endDate");
cell = row.createCell(5);
cell.setCellValue("cost");
cell = row.createCell(6);
cell.setCellValue("description");
cell = row.createCell(7);
cell.setCellValue("createBy");
cell = row.createCell(8);
cell.setCellValue("createTime");
for (int i = 0; i < activityList.size(); i++) {
Activity a = activityList.get(i);
row = sheet.createRow(i + 1);
cell = row.createCell(0);
cell.setCellValue(a.getId());
cell = row.createCell(1);
cell.setCellValue(a.getOwner());
cell = row.createCell(2);
cell.setCellValue(a.getName());
cell = row.createCell(3);
cell.setCellValue(a.getStartDate());
cell = row.createCell(4);
cell.setCellValue(a.getEndDate());
cell = row.createCell(5);
cell.setCellValue(a.getCost());
cell = row.createCell(6);
cell.setCellValue(a.getDescription());
cell = row.createCell(7);
cell.setCellValue(a.getCreateBy());
cell = row.createCell(8);
cell.setCellValue(a.getCreateTime());
}
//为客户浏览器提供下载框
response.setContentType("octets/stream");
response.setHeader("Content-Disposition", "attachment;filename=Activity-" + DateTimeUtil.getSysTime() + ".xls");
try {
OutputStream out = response.getOutputStream();
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
}
}
service
@Override
public List<Activity> getActivityList() {
List<Activity> list =activityDao.getActivityList();
return list;
}
dao:mapper.xml
<select id="getActivityList" resultType="Activity">
select * from tbl_activity
</select>
文件上传
首先需要在dispatcherServlet.xml文件中配置文件上传解析器
dispatcherServlet.xml
<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="#{1024*1024*5}" /><!-- 文件最大上传5M -->
<property name="defaultEncoding" value="utf-8"/>
</bean>
前台请求
html(使用的是bootstrap)
<script>
//导入文件
$("#importActivityBtn").click(function () {
var fileName = $("#activityFile").val();
var suffix = fileName.substr(fileName.lastIndexOf(".")+1);
if (!(suffix == 'xls' || suffix == 'xlsx')) {
alert("仅支持.xls或.xlsx格式的文件");
return;
}
//取得文件对象
//jquery不提供获取文件的方法,因此还是要使用js原生的files方法
var activityFile = $("#activityFile")[0].files[0];
if (activityFile.size > 1024 * 1024 * 5) {
alert("文件大小不超过5MB");
return ;
}
//发送请求
//FormData 是ajax定义的接口,可以模拟键值对向服务器提交数据
//FormData类型的作用是可以体检文本数据,还可以提交二进制数据
var formData = new FormData();
//myFile是给后台接收参数使用,真正的内容还是第二个参数
formData.append("myFile",$("#activityFile")[0].files[0]);
$.ajax({
url:"workbench/activity/importActivity.do",
data:formData,
type:"post",
processData:false,//主要是配合contentType使用,默认情况下,ajax吧所有数据进行application/x-www-form-urlencoded编码之前,会把所有数据统一转化为字符串,设为false可以阻止这种行为
contentType:false,//默认情况下,ajax向服务器发送数据之前,吧所有数据同于按照application/x-www-form-urlencoded编码格式进行编码,把contentType设置为false,能阻止这种行为
success:function (data) {
if (data.success) {
//提示成功导入的记录条数
alert("导入数据成功");
//清空导入显示的文件名
$("#activityFile").val("");
//关闭模态窗口
$("#importActivityModal").modal("hide");
//刷新列表
pageList(1, $("#activityPage").bs_pagination('getOption', 'rowsPerPage'));
} else {
alert("导入数据失败");
}
}
})
})
</script>
<body>
<!-- 导入市场活动的模态窗口 -->
<div class="modal fade" id="importActivityModal" role="dialog">
<div class="modal-dialog" role="document" style="width: 85%;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">导入市场活动</h4>
</div>
<div class="modal-body" style="height: 350px;">
<div style="position: relative;top: 20px; left: 50px;">
请选择要上传的文件:
<small style="color: gray;">[仅支持.xls或.xlsx格式]</small>
</div>
<div style="position: relative;top: 40px; left: 50px;">
<input type="file" id="activityFile">
</div>
<div style="position: relative; width: 400px; height: 320px; left: 45% ; top: -40px;">
<h3>重要提示</h3>
<ul>
<li>操作仅针对Excel,仅支持后缀名为XLS/XLSX的文件。</li>
<li>给定文件的第一行将视为字段名。</li>
<li>请确认您的文件大小不超过5MB。</li>
<li>日期值以文本形式保存,必须符合yyyy-MM-dd格式。</li>
<li>日期时间以文本形式保存,必须符合yyyy-MM-dd HH:mm:ss的格式。</li>
<li>默认情况下,字符编码是UTF-8 (统一码),请确保您导入的文件使用的是正确的字符编码方式。</li>
<li>建议您在导入真实数据之前用测试文件测试文件导入功能。</li>
</ul>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button id="importActivityBtn" type="button" class="btn btn-primary">导入</button>
</div>
</div>
</div>
</div>
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#importActivityModal">
<span class="glyphicon glyphicon-import"></span> 上传列表数据(导入)
</button>
</body>
后台响应
- 文件上传时使用虚拟路径,因为真实路径的盘符可能不存在。可以使用全局作用域下的realPath方法获得虚拟路径下的真实路径。这里的虚拟路径有我们自己设置,这里是设置在webApp下根目录tmpDir文件夹,专门存放上传的文件(这里可能会出现找不到路径的错误,原因是执行编译时,文件夹中没有需要编译的文件,所以不会生成,找不到路径。解决办法,在这个文件夹下建一个jsp文件就OK了,要知道jsp本身就是个java文件)
- 将file对象解析的文件放到临时文件中,在从临时文件中读取到输入流中
- HSSFWorkbook有一个加载输入流的构造方法,依次创建Excel文件对象,页对象,行对象,list集合(这里使用集合,不使用数组是因为集合是变长,数组是定长,对于未知文件的行数使用集合更合适),单元格(列)对象
- 这里需要通过对行,列进行遍历,行遍历:sheet.getLastRowNum()+1,行遍历这个方法取出的是行的索引值,所以在遍历时需要加一;列遍历:row.getLastCellNum(),这个方法取出的是列的真实个数。利用循环给对象属性赋值。
- 每赋值完成一个对象,将它放到list中,通过将list传到dao层存值
controller
//处理导入请求
/*
1. @RequestParam("myFile"),设置根据前台传过来的myFile标志来识别,接收参数
2. 这里使用MultipartFile 对象来接收参数,这个类型封装了解析文件内容的方法transferTo(File对象);它将前台的二进制文件解析成Excel文件放到临时文件File对象中。
*/
@RequestMapping("/importActivity.do")
@ResponseBody
public Map<String,Object> importActivity(@RequestParam("myFile")MultipartFile file, HttpServletRequest request) throws AjaxRequestException {
String filename = DateTimeUtil.getSysTimeForUpload()+".xls";
String path = request.getServletContext().getRealPath("/tmpDir");
System.out.println("====================="+path);
try {
file.transferTo(new File(path+"/"+filename));
InputStream input = new FileInputStream(path+"/"+filename);
HSSFWorkbook workbook = new HSSFWorkbook(input);
HSSFSheet sheet = workbook.getSheetAt(0);
HSSFRow row = null;
List<Activity> aList = new ArrayList<>();
//getLastRowNum获取的是索引值,使用时需要加一
for (int i = 1; i < sheet.getLastRowNum() + 1; i++) {
Activity activity = new Activity();
row = sheet.getRow(i);
HSSFCell cell = null;
for (int j = 0; j < row.getLastCellNum(); j++) {
cell = row.getCell(j);
if (j == 0) {
activity.setId(cell.getStringCellValue());
}else if (j == 1) {
activity.setOwner(cell.getStringCellValue());
}else if (j == 2) {
activity.setName(cell.getStringCellValue());
}else if (j == 3) {
activity.setStartDate(cell.getStringCellValue());
}else if (j == 4) {
activity.setEndDate(cell.getStringCellValue());
}else if (j == 5) {
activity.setCost(cell.getStringCellValue());
}else if (j == 6) {
activity.setDescription(cell.getStringCellValue());
}
}
aList.add(activity);
}
service.saveActivityList(aList);
} catch (Exception e) {
e.printStackTrace();
throw new AjaxRequestException();
}
return HandleFlag.successTrue();
}
service
@Override
public void saveActivityList(List<Activity> aList) {
activityDao.saveActivityList(aList);
}
dao:mapper.xml
collection属性只有两个值:array/数组;list/集合。
<insert id="saveActivityList">
insert into tbl_activity (
id,
owner,
name,
startDate,
endDate,
cost,
description,
createTime,
createBy
)
value
<foreach collection="list" item="a" separator=",">
(
#{a.id},
#{a.owner},
#{a.name},
#{a.startDate},
#{a.endDate},
#{a.cost},
#{a.description},
#{a.createTime},
#{a.createBy}
)
</foreach>
</insert>