csv格式行中每个字段之间以",“隔开,行与行以”\n"作为分隔符.
通过流的方式去生成文件弊端:前端无法得知后台下载是否成功,后台生成流异常时,前端也无法得知,因为得到的依然是200.即使Controller有返回方法也是一样,至于详细原因跟内容我就不说了.
如果想让前端知道是否成功下载了文件,可以通过后台生成文件保存本地,再通过文件下载器的方式下载.(后面有时间我会做这个方式)
controller
@ApiOperation(value="获取csv下载",notes = "")
@GetMapping(value="/getcsvfile")
public void getCSVFile(HttpServletResponse response){
try {
service.getCSVFile(response);
} catch (Exception e) {
e.printStackTrace();
}
}
service
public void getCSVFile( HttpServletResponse response) throws Exception {
StringBuffer sb = new StringBuffer();
//获取表头数据
ArrayList<String> headList = xxx.xxx;
String headStr = new String();
for (int i = 0; i < headList .size(); i++) {
headStr+=","+headList.get(i);
}
//比如: "姓名,学号,分数\n"这就是csv中的一行数据
sb.append(headStr.substring(1));
//通过dao获取数据
ArrayList<ArrayList<String>> dataList = xxx.xxx;
for (int i = 0; i < dataList.size(); i++) {
ArrayList<String> list = dataList.get(i);
String dataStr = new String();
for (int j = 0; j < list .size(); j++) {
dataStr +=","+list.get(i);
}
sb.append(dataStr.substring(1));
}
//上述中把数据拼接成类似于:姓名,学号,分数\n张三,01,100\n李四,02,80....的数据格式
//把拼接的字符串输出到浏览器
createCSV(sb,response);
}
public void createCSV(StringBuffer sb, HttpServletResponse response) throws Exception {
PrintWriter os =null;
try {
//解决文件名中文乱码问题
String fileName = "文件下载_"+System.currentTimeMillis() + ".csv";
String userAgent = request.getHeader("User-Agent");
if(userAgent.contains("MSIE")||userAgent.contains("Trident")) {
//ie浏览器
fileName=URLEncoder.encode(fileName,"UTF-8");
}else {
//其他浏览器
fileName=new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
}
//告诉浏览器要下载内容
response.setContentType("application/octet-stream;charset=utf-8");
response.setCharacterEncoding("UTF-8");
//浏览器会把输入流写入文件
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
OutputStream outputStream = response.getOutputStream();
outputStream.write(new byte []{( byte ) 0xEF ,( byte ) 0xBB ,( byte ) 0xBF });
os = new PrintWriter(new OutputStreamWriter(outputStream,"UTF-8"));
os.print(sb);
os.flush();
}finally{
try {
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}