前端根据 api 请求后端返回数据,并把数据导出成 csv 。现在的问题在后端返回的数据很多,会导致传输时间久,并且有可能会导致浏览器崩溃,实践中有没有什么好的办法去实现这种大数量的导出。
1
lemonada 2021-02-23 14:19:48 +08:00
为啥不是后端生成 csv,给个地址前端让浏览器获取下载链接然后下载呢
|
2
waiaan 2021-02-23 14:19:55 +08:00
后端直接生成文件
|
3
howells OP @lemonada 因为最开始数据量少的时候,就直接去拿了,然后前端根据组件去导出了,所以现在量大了之后,就还是在沿用这个思路。直接生成文件,我试试
|
4
fucUup 2021-02-23 15:17:41 +08:00 via Android
Indexeddb 就是这个
|
5
azcvcza 2021-02-23 15:18:14 +08:00
1,分页去获取喽,一次拿一点,拿到最后自己拼起来 2,直接下 csv 文件
|
6
nbhaohao 2021-02-23 15:20:28 +08:00 2
新增一个 “下载中心” 模块,每次生成文件就是发请求到后端,后端负责创建一个生成文件的内容。
然后前端可以去“下载中心”去下载已经生成好的文件。 |
7
jydeng 2021-02-23 15:24:38 +08:00
赞同 6L,加一个下载模块,后端生成完了,通过聊天工具通知。
|
8
admin7785 2021-02-23 15:39:17 +08:00 via iPhone
后端生成文件,可以参考 Easyexcel 工具,导出很方便
|
10
Python77 2021-02-23 16:10:34 +08:00
后端生成文件
|
11
NikoXu 2021-02-23 16:12:32 +08:00
返回文件流不就行了 ,没必要保存成文件吧
|
13
NikoXu 2021-02-23 16:17:59 +08:00
文件流直接可以下载了
|
14
howells OP @NikoXu 不矛盾,能快速生成文件流,它就可以直接在点下载的,我根据的 6L 的方案 =》“每次生成文件就是发请求到后端,后端负责创建一个生成文件的内容” 我说这个是不是要保存下来,然后在去下载中心点下载,
|
15
676529483 2021-02-23 16:25:36 +08:00
其实只要后端实现个接口,设置请求头,返回文件流,前端标记为 download,浏览器就自动流下载流
|
16
nbhaohao 2021-02-23 16:26:28 +08:00
@howells 是的,比如后端还可以做别的需求,例如文件只保留 7 天,然后前端去点击下载,下载的时候只要能拿到文件地址就可以了,比如一个 oss 地址。
同时第一次点击“生成文件”的时候,后端的接口可以快速返回 response,即告诉用户,这个导出任务已经在执行了,然后接口慢慢去生成就可以了。 |
17
nbhaohao 2021-02-23 16:28:49 +08:00 1
@howells 总结下来就是,“文件生成”的逻辑不要放在前端。
其他答主的说法也都是对的, 文件小的话,后端直接返回文件流,或者返回一个 url,然后前端下载就好了, 文件大的话,最好考虑“下载中心”,就是先让这个请求快速结束,而不是强迫用户一定要开着浏览器慢慢等那个文件生成完毕。 |
18
someonedeng 2021-02-23 17:05:02 +08:00
还不如让后端做个导出,分分钟的事,返回文件流或对象储存连接都行
|
19
w504391883 2021-02-23 17:08:42 +08:00
直接前台下载文件流,不要在代码中打开
|
20
ivanshaoaz 2021-02-23 17:09:54 +08:00
做成异步任务也行 后端生成文件 前端轮训文件生成结果 后端生成文件成功返回个下载链接
|
21
xiangyuecn 2021-02-23 17:12:59 +08:00
参考 #15 楼,后端什么都不用干,响应头都不用动,前端把接口的调用改成浏览器自己去下载处理就目测 ok 了。
最简单的办法: 把原有的 api 地址 直接粗暴的扔给 a[download] 标签手动 click 一下去触发浏览器去下载这个 url 的数据 |
22
4771314 2021-02-23 17:15:19 +08:00
肯定后端生成文件啊
数据量大一点,前端就会卡住,很不友好 后端可以异步生成文件,生成后通知前端去下载就可以了 |
23
iikebug 2021-02-23 17:23:36 +08:00
webworker 或者 wasm 也可以考虑下
|
24
Hilong 2021-02-23 17:28:00 +08:00
起一个 worker 来处理这个
|
25
fengbjhqs 2021-02-23 18:14:08 +08:00
kpi 怎么能让, 起个 worker 多线程来搞哇,除非内存泄露,请求超时可以让后端分批给数据
|
26
Justin13 2021-02-23 18:41:18 +08:00 via Android
后端上 worker 导出 csv,成功后前端获取下载的 url 。点击下载。
|
27
jones2000 2021-02-23 20:37:44 +08:00
生成文件同步到 CND 或云盘,然后下载就可以了。
|
28
xieranmaya 2021-02-23 21:05:13 +08:00
流式处理。前端现在是可以实现的。
|
29
golangLover 2021-02-23 21:22:42 +08:00
返回文件流+1
|
30
golangLover 2021-02-23 21:23:14 +08:00
然后 header 是 attachment
|
31
hantsy 2021-02-23 21:33:40 +08:00
生成临时文件(用 Redis 之类的,或者缓存工具,定时删除),数据源就稳定了。直接 Expose 这个文件给 Client 就可以了。
|
32
tokyo2020 2021-02-23 21:34:32 +08:00
我的想法是 前端肯定有些参数列表,调 api 请求数据 getData 呢,后端可以先返回一个 queryId 。 大约 10s 后,前端带着 queryId 调用 api 再问询下, 后端服务器如果处理好了后,还可以把 queryId 的内容缓存下来呢。
|
33
hantsy 2021-02-23 21:35:10 +08:00
另外写文件到 FTP 目录,客户端用 FTP 协议获取。
银行支付行业,对账很多用 FTP 协议,定时处理。 |
34
xuanbg 2021-02-24 08:59:58 +08:00
后端导出文件并上传 oss,前端轮询结果,或者刷列表(需要实现一个导出文件管理功能)。
|
35
wakzz 2021-02-24 11:49:00 +08:00
一般是两个方案
1. 文件流:后端给前端传文件流,前端只要把流存成文件就可以了 2. 异步文件: 后端异步生成文件,直接给前端一个最终文件的下载地址 |
36
rodrick 2021-02-24 11:57:29 +08:00
文件流下载学到了
|
37
zhuweiyou 2021-02-24 16:36:12 +08:00
后端异步生成, 存到 OSS.
前端轮询状态, 完成后 出现下载按钮. |