@RequestMapping("/download")
@ResponseBody
private void publi(String fileName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
// String fileName 获取前端发送请求时多携带的参数,做匹配用
// 获取文件下载绝对路径,做后面操作
String rootPath = req.getServletContext().getRealPath("/download");
File file = new File(rootPath, fileName);
if (file.exists()) { //判断这个文件是否为空,不空存在
//获取文件输入流
FileInputStream put = new FileInputStream(file);
/*
* 要给resp设置一个响应头信息,表示这是做的下载操作
* 我们响应给前端中文信息,一般会使用URLEncode编码
*/
resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
//通过response获取文件输出流
ServletOutputStream out = resp.getOutputStream();
IOUtils.copy(put, out);
// 关流
out.close();
put.close();
}
}
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- 读取大量excel数据时使用 -->
<dependency>
<groupId>com.monitorjbl</groupId>
<artifactId>xlsx-streamer</artifactId>
<version>2.1.0</version>
</dependency>
/**
* excel 大文件读取--返回list--map--以实体类属性为key
*
* @return
* @throws Exception
*/
public List<Map<String, Object>> bigExcel2(InputStream in) throws Exception {
List<Map<String, Object>> listMap = null;
Workbook wk = null;
try {
wk = StreamingReader.builder()
.rowCacheSize(100) //缓存到内存中的行数,默认是10
.bufferSize(4096) //读取资源时,缓存到内存的字节大小,默认是1024
.open(in); //打开资源,必须,可以是InputStream或者是File,注意:只能打开XLSX格式的文件
//读取excel第一个工作簿
Sheet sheet = wk.getSheetAt(0);
if (sheet == null) {
throw new IOException("文件sheet不存在");
}
//存放类中属性名称及excel名称的集合
HashMap<String, String> filedNamesMap = new HashMap<>();
//存标题
ArrayList<String> arrayList = new ArrayList<>();
//存放所有数据的集合
listMap = new ArrayList<>();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
Excel excel = field.getAnnotation(Excel.class);
if(excel == null){
continue;
}
String excelValue = excel.name();
String fieldName = field.getName();
filedNamesMap.put(excelValue,fieldName);
}
//遍历所有的行
for (Row row : sheet) {
// System.out.println("开始遍历第" + row.getRowNum() + "行数据:");
//存放每一行数据的集合
Map<String, Object> map = new HashMap<>();
int index = 0;
//遍历每一行数据
for (Cell cell : row) {
//把每个单元格的数据一一放进每一行集合中
String stringCellValue = cell.getStringCellValue();
if (row.getRowNum() == 0) {
String fieidName = filedNamesMap.get(stringCellValue);
arrayList.add(fieidName);
} else {
if (!org.springframework.util.StringUtils.isEmpty(stringCellValue)) {
// System.out.print(cell.getStringCellValue() + "--");
map.put(arrayList.get(index), stringCellValue);
}
index++;
}
}
//把每行数据一行一行放进整个集合中
if (!map.isEmpty()) {
listMap.add(map);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
wk.close();
in.close();
}
return listMap;
}
返回一个list对象
/**
* excel 大文件读取-->返回一个list对象
*
* @return
* @throws Exception
*/
public List<T> bigExcel2(InputStream in) throws Exception {
Workbook wk = null;
T entity = null;
//存放所有数据的集合
ArrayList<T> dataList = new ArrayList<>();
try {
// 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet
wk = StreamingReader.builder()
.rowCacheSize(100) //缓存到内存中的行数,默认是10
.bufferSize(4096) //读取资源时,缓存到内存的字节大小,默认是1024
.open(in); //打开资源,必须,可以是InputStream或者是File,注意:只能打开XLSX格式的文件
//读取excel第一个工作簿
Sheet sheet = wk.getSheetAt(0);
if (sheet == null) {
throw new IOException("文件sheet不存在");
}
//存标题
ArrayList<String> arrayList = new ArrayList<>();
//存放类中属性名称及excel名称的集合
HashMap<String, String> filedNamesMap = new HashMap<>();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
Excel excel = field.getAnnotation(Excel.class);
if(excel == null){
continue;
}
String excelValue = excel.name();
String fieldName = field.getName();
filedNamesMap.put(excelValue,fieldName);
}
//遍历所有的行
for (Row row : sheet) {
// System.out.println("开始遍历第" + row.getRowNum() + "行数据:");
//存放每一行数据的集合
int index = 0;
String value = null;
//遍历每一行数据
entity = clazz.newInstance();
for (Cell cell : row) {
//把每个单元格的数据一一放进每一行集合中
String stringCellValue = cell.getStringCellValue();
if (row.getRowNum() == 0) {
arrayList.add(filedNamesMap.get(stringCellValue));
} else {
if (!org.springframework.util.StringUtils.isEmpty(stringCellValue)) {
// System.out.print(cell.getStringCellValue() + "--");
value = stringCellValue;
ReflectUtils.invokeSetter(entity, arrayList.get(index), stringCellValue);
}
index++;
}
}
//把每行数据一行一行放进整个集合中
if (!org.springframework.util.StringUtils.isEmpty(value)) {
dataList.add(entity);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
wk.close();
in.close();
}
return dataList;
}
文章介绍了如何在Spring框架中使用@RequestMapping和@ResponseBody处理文件下载,通过HttpServletRequest和HttpServletResponse设置响应头进行文件传输。同时,文章展示了使用ApachePOI和xlsx-streamer库高效读取大量Excel数据,通过StreamingReader减少内存消耗,将数据转换为List<Map<String,Object>>或List<T>对象。
862





