spring + angular 实现导出excel
需求描述
要求批量导出数据,以excel
的格式。
选择方式
前台 + 后台
之前在别的项目中也遇到过导出的问题,解决方式是直接在前台导出将表格导出。
这次没有选择前台导出的方式,是由于需要导出所有的数据,所以考虑直接在后台获取所有的数据,然后就直接导出,最后前台触发导出API。
后台实现
导出使用的是POI
,在上一篇文章中,我已做了基本的介绍,这里就不做介绍配置了,参照:POI实现将导入Excel文件
创建表格
首先先建立一张表,这里要建立.xlsx
格式的表格,使用XSSFWorkbook
:
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("new sheet");
接着创建表格的行
和单元格
:
Row row = sheet.createRow(0);
row.createCell(0);
然后设置表头
:
row.createCell(0).setCellValue("学号");
row.createCell(1).setCellValue("姓名");
row.createCell(2).setCellValue("手机号码");
最后获取所有的数据,对应的填写
到单元格中:
int i = 1;
for (Student student : studentList) {row = sheet.createRow(i);row.createCell(0).setCellValue(student.getStudentNumber());row.createCell(1).setCellValue(student.getName());row.createCell(2).setCellValue(student.getPhoneNumber());i++;
}
输出
这部分是纠结比较久的,反复试了很多次。
一开始是直接以文件输出流的形式输出的:
FileOutputStream output = new FileOutputStream("test.xlsx");
workbook.write(output);
这样可以正确生成文件,但是问题是,它会生成在项目的根目录
下。
而我们想要的效果是,下载在本地
自己的文件夹中。
要解决这个问题,需要添加相应信息,返回给浏览器:
OutputStream fos = response.getOutputStream();
response.reset();
String fileName = "test";
fileName = URLEncoder.encode(fileName, "utf8");
response.setHeader("Content-disposition", "attachment;filename="+ fileName+".xlsx");response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
workbook.write(fos);
fos.close();
后台完成代码:
public void batchExport(HttpServletResponse response) {logger.debug("创建工作表");Workbook workbook = new XSSFWorkbook();Sheet sheet = workbook.createSheet("new sheet");logger.debug("获取所有学生");List<Student> studentList = (List<Student>) studentRepository.findAll();logger.debug("建立表头");Row row = sheet.createRow(0);row.createCell(0).setCellValue("学号");row.createCell(1).setCellValue("姓名");row.createCell(2).setCellValue("手机号码");logger.debug("将学生信息写入对应单元格");int i = 1;for (Student student : studentList) {row = sheet.createRow(i);row.createCell(0).setCellValue(student.getStudentNumber());row.createCell(1).setCellValue(student.getName());row.createCell(2).setCellValue(student.getPhoneNumber()); i++;}OutputStream fos;try {fos = response.getOutputStream();response.reset();String fileName = "test";fileName = URLEncoder.encode(fileName, "utf8");response.setHeader("Content-disposition", "attachment;filename="+ fileName+".xlsx");response.setCharacterEncoding("UTF-8");response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");// 设置contentType为excel格式workbook.write(fos);fos.close();} catch (Exception e) {e.printStackTrace();}
}
前台实现
在前台调用的时候,也经历了多次失败,google了很多篇文章,各种各样的写法都有,自己也是试了试,前台后台都对照做了很多尝试,但基本都是有问题的。这里我值给出我最后选择配套后台的方法。
// 后台导出路由
const exportUrl = '/api/student/batchExport';// 创建a标签,并点击
let a = document.createElement('a');
document.body.appendChild(a);
a.setAttribute('style', 'display:none');
a.setAttribute('href', exportUrl);
a.click();
URL.revokeObjectURL(exportUrl);
最后的实现还是一种比较简单的方法,创建了一个a标签
,然后隐式点击。
注意到这里我没有使用http
请求,主要是他并不能触发浏览器的下载,在发起请求后,并没有正确的生成文件,具体是什么还不清楚。后面弄明白后我会再更新这篇文章。
升级
上面的形式,在导出所有的数据的时候是没有问题的,但是如果我想带一些参数呢?
另外,我们的项目是建立在nginx同源
的基础上,一旦出现跨域问题,前台向后台请求,浏览器是不会默认携带Cookie
的,每次请求都将会被看作是一个新的请求。
所以上面的解决办法有所限制。
那么,还可以怎么写呢?
file-saver
这里我将借助FileSaver
来帮助我在前台生成excel文件。
this.http.get('student/batchExport', { responseType: 'blob'}).subscribe(data => {let blob = new Blob([data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'});saveAs(blob, 'test.xlsx');});
用httpClient
发起get
请求,声明:响应类型为blob
。
blob
是一个用来存储二进制文件
的对象。
然后创建一个blob
对象,类型为excel格式。
最后,利用file-saver
中的saveAs
函数,将blob
对象生成文件名为'test.xlsx'
的excel文件。
调整后台
这里后台大部分和前面的是一样的,但是明眼人会发现,前台使用后面的方法后,下面的代码就多余了:
String fileName = "test";
fileName = URLEncoder.encode(fileName, "utf8");
response.setHeader("Content-disposition", "attachment;filename="+ fileName+".xlsx");response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
是的,我们将这一部分交由前台负责,所以后台对应的这部分就可以删除了,只使用response
获取输出流就可以了:
OutputStream fos = response.getOutputStream();
workbook.write(fos);
fos.close();
好了,使用这种方法,我们就可以在发起http请求
的时候,添加我们想要的参数了。
总结
我们在google的时候,很多时候,我们并不能一下子就找到我们想要的东西,但是并不是说这在做无用功,因为我们往往会在一些类似的文章中找到灵感。
所以,当我们没有直接找到我们想要的结果的时候,不妨大胆的做一些尝试,因为我们会在一次又一次失败的尝试中,慢慢的了解问题的原理到底是怎么回事。
相关参考:
https://my.oschina.net/u/3644...https://blog.csdn.net/LUNG108...
spring + angular 实现导出excel相关推荐
- Spring Boot poi 导出Excel表格、Txt到浏览器下载
Spring Boot & poi 导出Excel表格.Txt到浏览器下载 原文链接:小回博客 文章目录 Spring Boot & poi 导出Excel表格.Txt到浏览器下载 一 ...
- Spring Boot EasyPoi导出Excel下载
Java关于excel的操作 Java Excel俗称jxl,可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件,现在基本没有更新了 Apache POI是Apache ...
- Spring Boot 导入导出Excel
原文出处:https://www.cnblogs.com/linjiqin/p/10975761.html#commentform 1.添加springBoot支持 <dependency> ...
- liferay6.2导出excel
因为liferay这个框架用起来总感觉有点怪, 用 liferay6.1 + struts2 + spring + ibatis 框架导出excel时候,采用poi方法导出excel,成功导出, 但在 ...
- 简单封装POI导出excel
简单封装POI导出excel Apache POI是一套根据Office Open XML标准(OOXML)和Microsoft OLE 2复合文档格式(OLE2)来处理各种文件格式的Java API ...
- EasyExcel 导入导出Excel文件
文章目录 写在前面 1.maven依赖 2.导入Excel文件 2.1.读取表格文件 2.2.如果有多个sheet表格 2.3.监听器封装(也可不封装) 2.4.读取数据格式化(实体类中添加注解) 3 ...
- Spring Boot使用EasyExcel导入导出Excel
一.导入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</a ...
- Spring Boot 菜鸟教程 12 EasyPoi导出Excel下载
GitHub src="//ghbtns.com/github-btn.html?user=je-ge&repo=spring-boot&type=watch&cou ...
- 如何优雅的导出 Excel
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:juejin.im/post/5c6b6b126fb9a04 ...
最新文章
- 图解深度学习(图灵出品)
- 太阳花图片_6种漂亮的花,种子已经成熟,别忘采摘种子,来年再播种
- 免安装mysql8_MySQL数据库之MYSQL-8.0.11-WINX64(免安装版)配置
- 微软算法100题26 左旋转字符串
- Android:Activity(页面)的生存周期
- 揭秘Sponge:统一Hadoop、Spark、SDS、Swift的大数据操作系统
- python url加密解密_小叮当Python进阶(二):爬虫与加密算法Part2之URL与Base64
- spring boot与spring mvc的区别是什么?
- 评分怎么读_英国留学本科中途被退学怎么申请硕士补救
- JSPServlet精华笔记
- Git安装教程(windows)
- 【转】Symstore 详细使用
- python 手机自动化操作_Python自动化办公之word操作
- dispatch_async 与 dispatch_get_global_queue 的使用方法
- Git下载安装(官网) 拉取代码的两种方法
- windows 7 桌面图标变白板的问题解决方法
- Android项目之利用手机传感器做惯性导航
- Linux中gcc的常用命令
- 阿里巴巴矢量图标库使用步骤
- 【渝粤教育】电大中专Windows操作系统 (2)_1作业 题库
热门文章
- 鸿蒙开发-从搭建todolist待办事项来学习组件与js之间的交互
- 解决pip使用异常No module named 'pip'
- Winform中设置DevExpress的RadioGroup的items从配置文件中加载
- Ecplise中配置Tomcat7服务器
- MySQL高级-索引是什么
- 图片跟着鼠标_刷完几百张网易云Banner,我发现了2个PPT图片处理的大招!
- java 采集rtsp_通过Java程序调用RTSP拉流协议视频平台EasyNVR程序接口步骤概览
- 【成都站参会指南】神策 2020 数据驱动用户大会,邀您面基!
- JavaScript:从此不再怕闭包
- [转].Net实现本地化简易教程