需求:页面需要实现点击按扭下载与展示报表相关的数据的.csv文件(页面展示其中一个报表)
环境:springboot + mybatisplus + mysql + easyui
maven依赖:
<dependency> <groupId>net.sourceforge.javacsv</groupId> <artifactId>javacsv</artifactId> <version>2.0</version> </dependency>
具体实现代码:(以其中一个报表为例)
1、主体代码
private static String SAVEPATH = "xxxxxxxxx"; // 文件保存路径,也可通过配置,@Value注解获取。
/**
* @Description: 导出报表
* @Author: admin
*/
@RequestMapping(value = "/all", method = RequestMethod.GET)
public void exportAll(HttpServletRequest request, HttpServletResponse response) throws Exception{
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String downloadName = sdf.format(new Date()) + ".zip";
// 设置响应头消息
setReponse(downloadName, response);
// 存文件路径
List<String> fileNameList = new ArrayList<>();
OutputStream outputStream = null;
ZipOutputStream zos = null;
try{
outputStream = response.getOutputStream();
zos = new ZipOutputStream(outputStream);
// 查询map数据列表
List<Map<String,Object>> list = list = fluService.selectMaps(new EntityWrapper<>());
createFlu(request, response, list, fileNameList);
// 文件压缩处理
if (!fileNameList.isEmpty()){
for (String fn : fileNameList){
FileInputStream fis = null;
byte[] buffer = new byte[10240];
int len;
//创建zip实体(一个文件对应一个ZipEntry)
ZipEntry entry = new ZipEntry(fn);
try {
fis = new FileInputStream(fn);
zos.putNextEntry(entry);
while ((len = fis.read(buffer)) != -1) {
//每次写入out1024字节
zos.write(buffer,0, len);
}
}catch (Exception e){
log.error("下载压缩文件出错:",e);
}finally {
if (entry != null){
try {
zos.closeEntry();
}catch (Exception e){
log.error("zip实体关闭失败:",e);
}
}
if (fis != null){
try {
fis.close();
}catch (Exception e){
log.error("关闭FileInputStream失败:",e);
}
}
}
}
}
// 删除路径下的文件
delFile(SAVEPATH);
}catch (Exception e){
log.error("文件导出错误:",e);
}finally {
// 关闭所有的流
if(zos != null) {
try {
zos.close();
} catch (Exception e) {
log.info("关闭zip时出现错误",e);
}
}
if(outputStream != null) {
try {
outputStream.close();
} catch (Exception e) {
log.info("关闭输出流时出现错误",e);
}
}
}
}
2、设置响应头
private void setReponse(String fName, HttpServletResponse response) throws IOException { try { byte[] fileNameByte = (fName).getBytes("UTF-8"); String filename = new String(fileNameByte, "ISO8859-1"); response.setHeader("Content-Disposition", "attachment;filename=" + filename); response.setContentType("application/zip;charset=UTF-8"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); }catch (Exception e){ throw e; } }
3、
/**
* @Description: 生成方法
* @Author: admin
* @Date: 2020/6/5 0005
*/
private void createFlu(HttpServletRequest request, HttpServletResponse response, List<Map<String, Object>> fluList, List<String> fileNameList) {
String fName = "flu_xx_";
String[] headers = {
"P900", "P6891", "P686","P800", "P7501", "P7502",
"P4", "P5", "P6","P7", "P7503", "P13","P7504"
};
try {
writFile(fName, headers, fluList,fileNameList);
log.info("### 已生成-xx.csv文件");
}catch (Exception e){
log.error("xxx.csv文件错误:",e);
}
}
4、具体生成代码
/**
* @Description: 生成文件方法
* @Author: admin
* @Date: 2020/6/5
*/
private void writFile(String fName, String[] headers, List<Map<String, Object>> list, List<String> fileNameList) throws Exception{
try {
String filename = "";
// 生成文件名以及文件保存路径
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String fn = fName + sdf.format(new Date()) + ".csv";
byte[] fileNameByte = (fn).getBytes("UTF-8");
filename = new String(fileNameByte, "UTF-8");
String fr = SAVEPATH + filename;
// 开始生成文件
CsvWriter csvWriter = new CsvWriter(fr,',', Charset.forName("UTF-8"));
// 写入表头
csvWriter.writeRecord(headers);
// 写入内容信息
for (Map<String,Object> m : list){
for (String k : headers){
csvWriter.write(m.get(k.toUpperCase()).toString());
}
csvWriter.endRecord();
}
// 关闭流
csvWriter.close();
// 写入文件保存路径
File fileLoad = new File(fr);
// 将文件具体路径放入列表
fileNameList.add(fr);
}catch (Exception e){
log.error("生成文件方法错误:",e);
throw e;
}
}
5、删除生成在服务器的文件
/** * @Description: 删除文件 * @Param: 文件夹路径 savepath * @return: void * @Author: admin * @Date: 2020/6/8 */ private void delFile(String savepath) { File file = new File(savepath); // 判断是否是文件夹 if (!file.isDirectory()){ return; }else { // 获取文件列表 File[] files = file.listFiles(); if (files != null && files.length > 0){ for (int i = 0; i < files.length; i++) { files[i].delete(); } } } }