文章目录
1. 文件导出
1.1 导出实现方式
文件导出功能, 简单来说有两种实现方式:
- 生成文件并直接下载文件, 导出一步实现;
- 先生成文件, 再下载文件, 导出分两步实现;
1.2 导出实现场景
实现场景无非是, 用户触发导出动作, 后端接收请求, 处理业务数据, 引入poi 依赖, 生成Excel 文件;通过IO 流将文件写出, 可上传到服务器备份; 通过读取文件转换为字节流输出实现导出功能;
如果考虑需要文件存档, 或者重要文件导出权限等功能时, 可以考虑设计导出任务和文件下载中心; 将导出与下载拆分为两个功能, 且可单独设置权限, 下载次数限制, 备份, 导出统计等功能.
你可以根据具体场景适当的确定是否异步实现, 还是同步实现.
2. 浏览器导出Excel
2.1 废话
导出功能网上资源其实挺多的, 功能设计, 实现什么的代码也很全. 这里是找一个场景时没有找到合适的. 导致走了弯路, 这就很气.
上面也说了, Excel 文件通过POI 去生成, 需求比较简单, 浏览器这边直接导出文件即可. 说明一下, 该场景下导出功能的实现和前端请求携带信息与资源请求方式有关.
2.2 导出Excel 接口
此处以Spring Boot 的前后端分离接口为例
2.2.1 启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2.2.2 导出文件Controller 层
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
/**
* @ClassName: ExcelDownController
* @Description: 文件下载服务端演示
* @author: niaonao
* @date: 2019/4/15
*/
@RestController
@RequestMapping("/excel")
public class ExcelDownController {
@PostMapping(value = "/download")
public void downloadExcelFile(HttpServletResponse response) throws IOException {
// 获取到服务器要下载文件的文件名和全路径, 此处模拟演示
String fileName = "表格文件";
String fileUrl = "D:\\表格文件.xlsx";
// 清空buffer
response.reset();
response.setContentType("application/msexcel;charset=utf-8");
// 客户使用目标另存为对话框保存指定文件
response.setHeader("Content-disposition", "attachment;filename= " + URLEncoder.encode(fileName + "_EXCEL.xlsx", "UTF-8"));
response.addHeader("Cache-Control", "no-cache");
response.getOutputStream().write(getBytesByFile(fileUrl));
response.getOutputStream().close();
// 各种可能出现异常的请自行判断
}
// 将文件转换成Byte数组
public byte[] getBytesByFile(String pathStr) {
File file = new File(pathStr);
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
byte[] data = bos.toByteArray();
bos.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
启动项目即可访问接口.
图2-2-1:
2.3 Form 表单请求导出Excel
此处以Form 表单的multipart/form-data 请求为例. 这个实现较为简单.
页面简单写个Html 即可如下
<form
action="http://127.0.0.1:8080/excel/download"
enctype="multipart/form-data"
method="post">
<input type="submit" value="ExcelDown">
</form>
通过浏览器打开html 文件, 点击导出按钮, 导出模拟服务器端的Excel 文件, 效果如下:
图2-3-1:
2.4 Vue 导出Excel
Vue 导出文件, 使用Blob 接收, 请求响应数据类型不同于Form 表单的multipart/form-data; 此处调用同样的导出接口, 模拟浏览器导出Excel 文件; Vue 使用Blob 和FileReader 接收文件流, 使用a 超链接处理导出Excel , 效果同图2-3-1
2.4.1 导出调用接口
// 创建导出任务
createExportTask: {
url: 'http://127.0.0.1:8080/excel/download',
method: 'post',
responseType: 'blob',
callback: function (res, resolve, reject) {
/* 请求成功 */
if (res.status === 200) {
resolve(res)
} else {
/* 请求失败 */
reject(res)
}
}
}
2.4.2 导出js 代码
export default {,
data: function () {
return {
}
},
props: {
createExportTaskApi: {
type: Object,
default: function () {
return this.$api.core.common.createExportTask
}
}
},
methods: {
/**
* 确定更新自定义文件名
*/
onSave: function () {
this.$http.fetch(this.createExportTaskApi)
.then((res) => {
let blob = new Blob([res.data])
let reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = (e) => {
let a = document.createElement('a')
/* 默认文件名 */
a.download = `表格文件.xlsx`
a.href = e.target.result
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
}).catch((resp) => {
this.$notify.error(resp.msg || '导出文件失败')
})
}
}
}
</script>