前端及后端实现csv文件下载功能

方法一、

前端内容:

javascript 复制代码
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
const fileNameDateTime = getFormattedDateTime();
const filename = "用户提现列表"+fileNameDateTime+'.csv';
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);

后端:

java 复制代码
@GetMapping("/downloadCsv")
    @PreAuthorize("hasAuthority('system')")
    public ResponseEntity<byte[]> downloadCsv() {
        // 查询数据库获取数据
        List<SysUsdt> sysUsdtList = sysUsdtService.list(new QueryWrapper<SysUsdt>().orderByDesc("joinTime"));
        for (SysUsdt sysUsdt : sysUsdtList) {
            QueryWrapper<SysUser> queryuserWrapper = new QueryWrapper<>();
            queryuserWrapper.eq("id",sysUsdt.getUserid());
            SysUser sysUser = sysUserService.getOne(queryuserWrapper);
            if(sysUser==null){
                sysUsdt.setUsername("用户已删除");

            }else {
                sysUsdt.setUsername(sysUser.getUsername());
            }
        }
        // 创建字节数组输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream));
        // 写入 CSV 表头
        writer.println("ID,用户名,充值金额(人民币),充值金额(USDT),是否到账,到账时间");
        // 填充数据
        for (SysUsdt sysUsdt : sysUsdtList) {
            writer.println(
                    sysUsdt.getId() + "," +
                            sysUsdt.getUsername() + "," +
                            sysUsdt.getMoney().doubleValue() + "," +
                            sysUsdt.getUsdt().doubleValue() + "," +
                            sysUsdt.getStatus() + "," +
                            sysUsdt.getConfirmtime()
            );
        }
        writer.flush();
        byte[] csvBytes = outputStream.toByteArray();
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("text/csv"));
        headers.setContentDispositionFormData("attachment", "充值明细.csv");
        return new ResponseEntity<>(csvBytes, headers, HttpStatus.OK);
    }

方法二、

直接纯前端实现:

javascript 复制代码
const { fileName, fileData, fileType } = res.data;
        // 将 Base64 数据转换为二进制数据
        const byteCharacters = atob(fileData); // 解码 Base64
        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        // 创建 Blob 对象
        const blob = new Blob([byteArray], { type: fileType });
        // 创建下载链接
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', fileName);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        window.URL.revokeObjectURL(url);
        urlsVisable.value = false;
相关推荐
bearpping7 小时前
Nginx 配置:alias 和 root 的区别
前端·javascript·nginx
@大迁世界8 小时前
07.React 中的 createRoot 方法是什么?它具体如何运作?
前端·javascript·react.js·前端框架·ecmascript
January12078 小时前
VBen Admin Select 选择框选中后仍然显示校验错误提示的解决方案
前端·vben
. . . . .8 小时前
前端测试框架:Vitest
前端
xiaotao1318 小时前
什么是 Tailwind CSS
前端·css·css3
战南诚9 小时前
VUE中,keep-alive组件与钩子函数的生命周期
前端·vue.js
发现一只大呆瓜9 小时前
React-彻底搞懂 Redux:从单向数据流到 useReducer 的终极抉择
前端·react.js·面试
霍理迪9 小时前
Vue的响应式和生命周期
前端·javascript·vue.js
李剑一9 小时前
别再瞎写了!Cesium 模型 360° 环绕,4 套源码全公开,项目直接用
前端