Vue2+SpringBoot实现数据导出到csv文件并下载

前言

  • 该功能用于导出数据到csv文件,并且前端进行下载操作。
  • 涉及到java后端以及前端。后端获取数据并处理,前端获取返回流并进行下载操作。
  • csvexcel文件不大相同。如果对导出的数据操作没有很高要求的话,csv文件就够了。具体差异自行百度。
  • 我这里使用的数据是假数据,并没有从数据库获取。

使用csv好处:

  • 由于功能少,所以要比excel文件小,下载快。
  • 后端不需要添加apache-poi等依赖,处理好数据,返回值为字符串字节即可。

1、后端代码

1.1、搭建springBoot项目

搭建项目就不说了,最基本的要求。不会的话需要先学习springBoot(下面演示是基于springBoot的)。

1.2、创建CSV工具类

java 复制代码
package com.tcc.utils;

import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class CsvUtils {
    /**
     * CSV文件列分隔符
     */
    private static final String CSV_COLUMN_SEPARATOR = ",";

    /**
     * CSV文件行分隔符
     */
    private static final String CSV_ROW_SEPARATOR = "\r\n";

    /**
     * @param dataList 集合数据
     * @param titles   表头部数据
     * @param keys     表内容的键值
     * @param os       输出流
     */
    public static void doExport(List<Map<String, Object>> dataList, String titles, String keys, OutputStream os)
            throws Exception {

        // 保证线程安全
        StringBuffer buf = new StringBuffer();

        String[] titleArr = null;
        String[] keyArr = null;

        titleArr = titles.split(",");
        keyArr = keys.split(",");

        // 组装表头
        for (String title : titleArr) {
            buf.append(title).append(CSV_COLUMN_SEPARATOR);
        }
        buf.append(CSV_ROW_SEPARATOR);
        // 组装数据
        if (!CollectionUtils.isEmpty(dataList)) {
            for (Map<String, Object> data : dataList) {
                for (String key : keyArr) {
                    buf.append("\t" +data.get(key)).append(CSV_COLUMN_SEPARATOR);
                }
                buf.append(CSV_ROW_SEPARATOR);
            }
        }

        // 写出响应
        os.write(buf.toString().getBytes("GBK"));
        os.flush();
    }

    /**
     * 设置Header 辅助函数, 可用可不用
     *
     * @param fileName
     * @param response
     * @throws UnsupportedEncodingException
     */
    public static void responseSetProperties(String fileName, HttpServletResponse response)
            throws UnsupportedEncodingException {
        // 设置文件后缀
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fn = fileName + sdf.format(new Date()) + ".csv";
        // 读取字符编码
        String utf = "UTF-8";

        // 设置响应
        response.setContentType("application/ms-txt.numberformat:@");
        response.setCharacterEncoding(utf);
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "max-age=30");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fn, utf));
    }
}

1.3、编写接口

java 复制代码
package com.tcc.controller;

import com.tcc.utils.CsvUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@RestController
@RequestMapping("/demo")
public class DemoController {

    @RequestMapping("generateCSV")
    // 解决跨域问题
    @CrossOrigin
    public void generateCSV(HttpServletResponse response) throws Exception {
        ServletOutputStream outputStream = response.getOutputStream();

        List<Map<String, Object>> dataList = new ArrayList();
        HashMap<String, Object> map = new HashMap<>();
        // 第一条数据
        map.put("name", "张三");
        map.put("age", 20);
        map.put("sex", "男");
        map.put("brithday",  new Date());
        dataList.add(map);

        // 第二条数据
        map = new HashMap<>();
        map.put("name", "李四");
        map.put("age", 22);
        map.put("sex", "女");
        map.put("brithday",  new Date());
        dataList.add(map);

        // 辅助函数,可用可不用
//        CsvUtils.responseSetProperties("test", response);
        CsvUtils.doExport(dataList,
                "姓名,年龄,性别,生日", // 所有列名
                "name,age,sex,brithday", // 列名对应的数据列的字段
                outputStream);
    }
}

2、前端代码

2.1、搭建vue2框架

也是最基本的,就不说了。

2.2、调用接口,并进行下载

html 复制代码
<template>
  <div class="home">
    <button @click="downLoadFile">测试按钮</button>
  </div>
</template>

<script>
export default {
  name: 'HomeView',
  methods: {
    downLoadFile() {
      this.axios.post("http://localhost:8080/demo/generateCSV", {}, {
        responseType: 'blob' // 设置响应结果类型为blob类型
      }).then(res => {
         // 处理数据,并下载
        const blob = new Blob([res.data]);
        let url = window.URL.createObjectURL(blob)
        let link = document.createElement('a')
        link.href = url
        link.setAttribute('download', 'test.csv')
        document.body.appendChild(link)
        link.click()
      })
    }
  }
}
</script>

3、效果

相关推荐
凯酱2 分钟前
MyBatis-Plus分页插件的使用
java·tomcat·mybatis
程序员总部13 分钟前
如何在IDEA中高效使用Test注解进行单元测试?
java·单元测试·intellij-idea
oioihoii15 分钟前
C++23中if consteval / if not consteval (P1938R3) 详解
java·数据库·c++23
佳腾_22 分钟前
【Web应用服务器_Tomcat】一、Tomcat基础与核心功能详解
java·前端·中间件·tomcat·web应用服务器
追逐时光者26 分钟前
MongoDB从入门到实战之Docker快速安装MongoDB
后端·mongodb
猿究院_xyz38 分钟前
跟着尚硅谷学vue-day5
前端·javascript·vue.js·前端框架·html
方圆想当图灵40 分钟前
深入理解 AOP:使用 AspectJ 实现对 Maven 依赖中 Jar 包类的织入
后端·maven
豌豆花下猫1 小时前
Python 潮流周刊#99:如何在生产环境中运行 Python?(摘要)
后端·python·ai
嘻嘻嘻嘻嘻嘻ys1 小时前
《Spring Boot 3 + Java 17:响应式云原生架构深度实践与范式革新》
前端·后端
异常君1 小时前
线程池隐患解析:为何阿里巴巴拒绝 Executors
java·后端·代码规范