大家好呀,最近工作中遇到的问题,给大家做一个分享和记录。截止到九月开学,我还是一个大三的学生,所以呢,我目前还是一个练习时长一个月的开发实习生。很幸运,我到的项目组是使用开源框架开发的,就是vue + Spring Boot,我其他实习生同事被分到了老项目,还是jsp、servlet哪些东西,还会在页面里面写Java代码,确实有点……
虽然用到了 vue + Spring Boot ,但是呢全是用的公司的框架,就像vue,平时查看用法去vue.js官网看就行,我们公司呢,也有一个官网,上面是前端框架用法,当然呢,这个网站没有发布,得连公司内网才能访问。跟vue用法一样,有vue基础几乎都能看懂“大致意思”,看懂归看懂,自己想写还得多努力几天的哈;还有那个Spring Boot也是不常规的,就是跟我们平时在学校和在网课上看的不一样,也是公司框架┭┮﹏┭┮,有基础的话,多努力努力,做个增删改查还是上手很快的O(∩_∩)O,希望让一些还没有去工作的牛牛有一定的了解。多学习一下:SQL 、VUE 、Spring Boot ,当然为了过面试那关,还得多学习一些其他知识的。
(注:我是一个学后端的,但是来公司了,前后端都得写,毕竟是个搞web开发的,Html和css不可能一点不会,但是……懂得都懂┭┮﹏┭┮)
好的,正文开始(源码在最后):
目的是要用vue和后台做一个下载功能,我们平时前端调用后端一般都是使用axios,但是axios无法实现下载功能,所以我想到了,原生js,当然axios也有解决方法,大家可以自行百度了解。
下载Excel表格,后端呢,我知道两种方法:阿里的EasyExcel ,和阿帕奇的poi
easyExcel官网:https://www.yuque.com/easyexcel/doc/easyexcel (汉化,易懂)
里面有文件下载的例子,我就不粘过来了
poi : https://poi.apache.org/components/spreadsheet/quick-guide.html#ReadWriteWorkbook
其实下载功能我们都是用的:esponse中的OutputStream进行文件下载
一个下载小例子:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用response获得字节输出流
ServletOutputStream out=response.getOutputStream();
//获得服务器上面的图片
String realpath=this.getServletContext().getRealPath("456.png");
InputStream in=new FileInputStream(realpath);
int len=0;
byte[] buffer=new byte[1024];
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
下面就是我的源码,两种都有,注解详细:
easyexcel不要忘记,实体类哟,根据实体类上注解生成表格列名:
public class User extends BaseRowModel {
// 主键id
@ExcelIgnore // 生成报表时忽略,不生成次字段
private Integer id;
@ExcelProperty(value = "姓名", index = 0) // 定义表头名称和位置,0代表第一列
private String name;
@ExcelProperty(value = "年龄", index = 1)
private Integer age;
@ColumnWidth(20) // 定义列宽
@DateTimeFormat(value = "yyyy/MM/dd")
@ExcelProperty(value = "出生日期", index = 2)
private Date birthday;
}
/*easyExcel导出*/
@RequestMapping(value = "/exportExcel")
public void exportExcel(HttpServletResponse response) throws IOException {
//设置编码与文件类型
response.setContentType("mutipart/form-data");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition","attachment;filename=test.xlsx");
ServletOutputStream out=response.getOutputStream();
//导出的数据
List<User> users = userService.findAll();
//导出并下载
EasyExcel.write(out,User.class).sheet("test").doWrite(users);
out.flush();
out.close();
}
poi:
//poi生成xls文件并下载
@GetMapping("/download")
public void download(HttpServletResponse response){
response.setContentType("application/binary;charset=UTF-8");
try{
ServletOutputStream out=response.getOutputStream();
//文件名
String name = "扫描榜单下载";
try {
//设置文件头:最后一个参数是设置下载文件名
response.setHeader("Content-Disposition", "attachment;fileName=" +
URLEncoder.encode(name+".xls", "UTF-8"));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
//表格的列的标题
String[] titles = { "姓名","年龄","出生日期" };
//表格的数据,这里是查询,因为是例子,我做的查询全部,可自定义
List<User> tops = userService.findAll();
export(tops,titles, out);
} catch(Exception e){
e.printStackTrace();
}
}
//转成.xls文件
public void export(List<User> tops,String[] titles, ServletOutputStream out) throws Exception{
try{
// 第一步,创建一个workbook,对应一个Excel文件
HSSFWorkbook workbook = new HSSFWorkbook();
//表名
String sheetName="扫描榜单";
// 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet hssfSheet = workbook.createSheet(sheetName);
// 第三步,在sheet中添加表头第0行(表头),注意老版本poi对Excel的行数列数有限制short
HSSFRow row = hssfSheet.createRow(0);
// 第四步,创建单元格,并设置值表头 设置表头居中
HSSFCellStyle hssfCellStyle = workbook.createCellStyle();
//居中样式
hssfCellStyle.setAlignment(HorizontalAlignment.CENTER);
//创建列
HSSFCell hssfCell = null;
for (int i = 0; i < titles.length; i++) {
hssfCell = row.createCell(i);//列索引从0开始
hssfCell.setCellValue(titles[i]);//列名1
hssfCell.setCellStyle(hssfCellStyle);//列居中显示
}
/*把要导入的值放到一个二维数组中,表格正好对应二维数组*/
String[][] dataList =new String[tops.size()][3];
//将日期类型转换成字符串类型
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
for(int i=0;i<tops.size();i++){
dataList[i][0]=tops.get(i).getName();
dataList[i][1]=String.valueOf(tops.get(i).getAge());
//日期类型格式化成字符型
dataList[i][2]=sdf.format(tops.get(i).getBirthday());
}
//把表格内容加入,从第二行开始
for(int i=0;i<dataList.length;i++){
row=hssfSheet.createRow(i+1);
for(int j=0;j<3;j++){
row.createCell(j).setCellValue(dataList[i][j]);
}
}
// 第七步,将文件输出到客户端浏览器
try {
workbook.write(out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
throw new Exception("导出信息失败!");
}
}
当然第一步都是先导依赖哈
<!--导出导入easyexcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.4</version>
</dependency>
<!-- org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
然后就是原生js发送post请求:
<button onclick="send()">测试</button>
<script>
function post(url, params) {
var temp = document.createElement("form");
temp.action = url;
temp.method = "post";
temp.style.display = "none";
for ( var x in params) {
var opt = document.createElement("input");
opt.name = x;
opt.value = params[x];
temp.appendChild(opt);
}
document.body.appendChild(temp);
temp.submit();
return temp;
}
//调用post方法,发送请求,只是例子,age写死了
function send() {
post(
"http://127.0.0.1:8080/user/download",
{
age : 23
});
}
</script>
AJAX无法下载文件的原因
下载其实是浏览器的内置事件,浏览器的 GET请求(frame、a)、 POST请求(form)具有如下特点:
response会交由浏览器处理
response内容可以为二进制文件、字符串等
但是AJAX请求不一样:
response会交由 Javascript 处理
response内容只能接收字符串才能继续处理
因此,AJAX本身无法触发浏览器的下载功能。
最后在vue中整合:
//下载,调用post请求
download() {
this.post({
pageNumber: this.pageNumber,
pageSize: this.pageSize,
sonarState: this.appState,
appName: this.searchContent,
roleName: this.roleName
});
},
//发送post请求
post( params){
var form = document.createElement("form");
form.style.display = "none";
form.action = 'http://localhost:8090/download';
form.method = "post";
document.body.appendChild(form);
for (var key in params) {
var input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = params[key];
form.appendChild(input);
}
form.submit();
form.remove();
return form;
},
后台demo下载:
链接:https://pan.baidu.com/s/1lGlE1qrN7oFSlbDsfCtBRQ
提取码:o0ud




最近浏览
