前言
- 该功能用于导出数据到
csv
文件,并且前端进行下载操作。- 涉及到java后端以及前端。后端获取数据并处理,前端获取返回流并进行下载操作。
csv
与excel
文件不大相同。如果对导出的数据操作没有很高要求的话,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>