突然想记录一下这段代码,自己便写了个简单的demo及压缩工具类(一般不会说工具类我是在网上拷贝后重新修改了一下,哈哈哈),使用起来比较方便,以后导出csv或zip格式文件都可用,先写如何导出csv , 后边则是csv+图片导出zip
package com.hutool.test;
import cn.hutool.core.io.FileUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
/**
* @author xqli7@iflytek.com
* @date 2019/1/25 17:25
* @description:
*/
@RestController
@RequestMapping("/test")
public class DataExportTest {
/**
* CSV导出表头信息
*/
private static final List<String> HEADS = Arrays.asList("测试名称", "测试数", "测试内容");
@GetMapping("/exportcsv")
public String export(HttpServletResponse response) {
List<List<Object>> dataMaps = new ArrayList<>();
List<Object> dataMap = new ArrayList<>();
dataMap.add("testName");
dataMap.add("1");
dataMap.add("这是一条测试数据");
dataMaps.add(dataMap);
//设置临时路径
String localTempPath = "D:\\iflytek\\hiseeJK\\temp";
String filePath = localTempPath + File.separator + "testTemplate" + ".csv";
try {
CsvUtils.exportCsv(filePath, HEADS, dataMaps);
CsvUtils.responseCsv(response, "导出测试" + ".csv", filePath);
return "导出成功";
} catch (Exception e) {
return "导出失败";
}
}
单独导出csv文件工具类,里面有注释就单独解释了
package com.hutool.test;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author xqli7
** @date 2019/1/25 17:25
*/
public class CsvUtils {
private CsvUtils() {
}
private static final Logger LOG = LoggerFactory.getLogger(CsvUtils.class);
/**
* 读取CSV文件内容
*
* @param file 传入的CSV文件
* @return 读取的数据集合
*/
public static List<String[]> readCsv(File file, boolean isNoRepeatData) {
try (
DataInputStream in = new DataInputStream(new FileInputStream(file));
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "GBK"))
) {
//将第一行表头先读出,后面line读入的全部为数据内容
String firstLine = reader.readLine();
LOG.info("head:{}", firstLine);
String line;
List<String[]> data = new ArrayList<>();
Set<String> lines = new HashSet<>();
while ((line = reader.readLine()) != null) {
//未设置重复过滤 或者 设置重复过滤且未重复
//limit -1 防止无数据读取报角标越界异常
String[] item = line.split(",", -1);
if (isNoRepeatData) {
if (!lines.contains(line)) {
data.add(item);
lines.add(line);
}
} else {
data.add(item);
}
}
return data;
} catch (Exception e) {
LOG.error("读取csv文件出错", e);
return null;
}
}
/**
* 将CSV格式数据写入指定CSV文件
*
* @param filePath CSV文件写入的全路径
* @param heads 要导入的数据表头
* @param dataList 要导入的数据内容
* @Param fileName 导出时浏览器中展示的文件名
* @Param response HttpServlet响应
*/
public static void exportCsv(String filePath, List<String> heads, List<List<Object>> dataList) {
if (StringUtils.isEmpty(filePath) || heads.isEmpty()) {
return;
}
LOG.debug("开始生成本地csv,filePath:{}", filePath);
long start = System.currentTimeMillis();
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), "GBK"))) {
StringBuilder stringBuilder = new StringBuilder();
heads.forEach(value ->
stringBuilder.append(value).append(',')
);
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
writer.write(stringBuilder.toString());
writer.flush();
for (List<Object> data : dataList) {
writer.newLine();
stringBuilder.delete(0, stringBuilder.length());
data.forEach(value -> stringBuilder.append(value).append(','));
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
writer.write(stringBuilder.toString());
writer.flush();
}
} catch (Exception e) {
LOG.error("写文件异常", e);
}
LOG.debug("完成csv,filePath:{}, time:{}", filePath, System.currentTimeMillis() - start);
}
/**
* 将本地文件写入响应流
*
* @param response
* @param fileName
* @param filePath
* @return
*/
public static boolean responseCsv(HttpServletResponse response, String fileName, String filePath) {
File file = new File(filePath);
if (!file.exists()) {
LOG.error("导出文件不存在, filePath:{}", filePath);
return false;
}
try (InputStream in = new FileInputStream(file);
OutputStream out = response.getOutputStream()
) {
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
IOUtils.copy(in, out);
} catch (IOException e) {
LOG.error("导出文件出错", e);
} finally {
delByPath(filePath);
}
return true;
}
public static boolean delByPath(String path) {
File file = new File(path);
return deleteDir(file);
}
public static boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
if (children == null) {
return true;
}
for (String aChildren : children) {
boolean success = deleteDir(new File(dir, aChildren));
if (!success) {
return false;
}
}
}
// 目录此时为空,可以删除
//设置可执行权限 设置可执行权限 设置可写权限
if (dir.setExecutable(true) && dir.setReadable(true) && dir.setWritable(true)) {
LOG.info("设置目录权限成功");
} else {
LOG.error("设置目录权限失败");
}
LOG.info("--deleteById file : {}", dir.getPath());
try {
Files.delete(dir.toPath());
} catch (Exception e) {
LOG.error("删除失败", e);
return false;
}
return true;
}
}
以下代码是导出zip格式的,我是csv+图片,如果有其他需要的可以将图片更改为其他文件即可;
package com.hutool.test;
import cn.hutool.core.io.FileUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
/**
* @author xqli7@iflytek.com
* @date 2019/1/23 16:14
* @description:
*/
@RestController
@RequestMapping("/test")
public class DataExportTest {
/**
* CSV导出表头信息
*/
private static final String HEAD = "测试名称" + "," + "测试数" + "," + "测试内容" + ",";
/**
* 导出zip包名称
*/
private static final String DESCRIBE = "导出测试";
@GetMapping("/exportZip")
public String writeFileToZip(HttpServletResponse response) {
//获取数据(数据库数据)
List<Map<String, Object>> dataMaps = new ArrayList<>();
Map<String, Object> dataMap = new HashMap<>(3);
dataMap.put("testName", "testName");
dataMap.put("testNum", 1);
dataMap.put("testContent", "这是一条测试数据");
dataMaps.add(dataMap);
//设置临时路径
String localTempPath = "D:\\iflytek\\hiseeJK\\temp";
String csvTempPath = localTempPath + File.separator + "testTemplate" + File.separator;
File file = new File(csvTempPath);
File newFile;
try {
File dir = new File(csvTempPath);
// 判断目录是否存在
if (!dir.exists()) {
dir.mkdirs();
}
newFile = File.createTempFile(UUID.randomUUID().toString(), ".csv", file);
} catch (Exception e) {
System.out.println("----导出文件创建异常");
return null;
}
try (
OutputStream outputStreamData = response.getOutputStream();
OutputStream outputStream = new FileOutputStream(newFile);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "GBK"))
) {
//CSV文件表头信息
StringBuilder header = new StringBuilder(HEAD);
String tableHeader = header.deleteCharAt(header.length() - 1).toString();
writer.write(tableHeader);
writer.newLine();
writer.flush();
//读取数据写入CSV文件中
for (Map<String, Object> map : dataMaps) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(map.get("testName").toString()).append(",").append(map.get("testNum").toString()).append(",").append(map.get("testContent").toString()).append(",");
String dataLine = stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString();
writer.write(dataLine);
writer.newLine();
writer.flush();
//若图片放在服务器中直接下载(服务器中保存文件的路径->下载后的存储路径)
// hdfsClient.download(map.get(PATH).toString(), csvTempPath + map.get(FILE_NAME).toString());
//无服务器,测本地的d盘中存在的图片
String localPath = "D:\\iflytek\\hiseeJK\\temp\\0823dd54564e92581460604f9082d158ccbf4e3f.jpg";
File localFile = new File(localPath);
//将图片复制到要压缩的临时文件中(暂测一条数据,此方法图片在文件夹中存在则报错)
FileUtil.copyFile(localFile, file);
}
//待压缩的文件路径+压缩后的文件+压缩后的文件名
ZipUtils.fileToZip(csvTempPath, csvTempPath, DESCRIBE);
byte[] dataByteArr = getBytes(csvTempPath + DESCRIBE + ".zip");
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(DESCRIBE + ".zip", "UTF-8"));
outputStreamData.write(dataByteArr);
} catch (IOException e) {
return "导出失败";
} finally {
//一般这里写临时文件删除方法
}
return "导出成功";
}
/**
* 获得指定文件的byte数组
*/
public static byte[] getBytes(String filePath) {
byte[] buffer = null;
File file = new File(filePath);
try (FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000)) {
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
buffer = bos.toByteArray();
} catch (Exception e) {
}
return buffer;
}
}
以下是压缩zip及解压zip的工具类,可直接使用,不过建议还是需要看看的,不然像我一样第一次写找错还得找半天。。哈哈哈
package com.hutool.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* @author xqli7
* @date 2019/1/23 16:14
*/
public final class ZipUtils {
private static final Logger LOG = LoggerFactory.getLogger(ZipUtils.class);
private static final int BUFFER = 2048;
private static final int TRANS_BUFFER = 10240;
private ZipUtils() {
throw new IllegalStateException("Utility class");
}
/**
* 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件并存放到zipFilePath路径下
*
* @param sourceFilePath 待压缩的文件路径
* @param zipFilePath 压缩后存放路径
* @param fileName 压缩后文件的名称
* @return
*/
public static boolean fileToZip(String sourceFilePath, String zipFilePath, String fileName) {
boolean flag = false;
File sourceFile = new File(sourceFilePath);
if (!sourceFile.exists()) {
LOG.info("待压缩的文件目录:{}不存在.", sourceFilePath);
sourceFile.mkdir();
}
File zipFile = new File(zipFilePath + File.separator + fileName + ".zip");
if (zipFile.exists()) {
LOG.info("{}目录下存在名字为:{}.zip打包文件", zipFilePath, fileName);
} else {
File[] sourceFiles = sourceFile.listFiles();
if (null == sourceFiles || sourceFiles.length < 1) {
LOG.info("待压缩的文件目录:{}里面不存在文件,无需压缩.", sourceFilePath);
} else {
try (
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos))
) {
byte[] bytes = new byte[TRANS_BUFFER];
loopCreateZip(sourceFiles, zos, bytes);
flag = true;
} catch (Exception e) {
LOG.error("", e);
}
}
}
return flag;
}
private static void loopCreateZip(File[] sourceFiles, ZipOutputStream zos, byte[] bytes) throws IOException {
for (int i = 0; i < sourceFiles.length; i++) {
// 创建ZIP实体,并添加进压缩包
ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
zos.putNextEntry(zipEntry);
// 读取待压缩的文件并写进压缩包里
try (
FileInputStream fis = new FileInputStream(sourceFiles[i]);
BufferedInputStream bis = new BufferedInputStream(fis, TRANS_BUFFER)
) {
int read = 0;
while ((read = bis.read(bytes, 0, TRANS_BUFFER)) != -1) {
zos.write(bytes, 0, read);
}
} catch (IOException e) {
LOG.error("", e);
}
}
}
/**
* 读取zip包中的文本文件以及文件内容
*
* @param filePath
* @return
* @throws IOException
*/
public static boolean readZipFile(String filePath) {
File sourceFile = new File(filePath);
if (!sourceFile.exists()) {
LOG.info("待读取的文件:{}不存在.", filePath);
return false;
}
try (
FileInputStream fis = new FileInputStream(sourceFile);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
LOG.info("Extracting:{} ", entry);
// write the files to the disk
write(entry, zis);
}
} catch (Exception e) {
LOG.error("", e);
}
return true;
}
private static void write(ZipEntry entry, ZipInputStream zis) {
int count;
byte[] data = new byte[BUFFER];
try (
BufferedOutputStream dest = new BufferedOutputStream(new FileOutputStream(entry.getName()), BUFFER)
) {
while ((count = zis.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
} catch (Exception e) {
LOG.error("", e);
}
}
/**
* 对zip文件进行解压
*
* @param sourcePath 解压文件路径
* @param targetDir 解压目标地址
* @return
*/
@SuppressWarnings("unchecked")
public static List<File> unzip(String sourcePath, String targetDir) {
List<File> files = new ArrayList<>();
File targetDirFile = new File(targetDir);
if (!Files.exists(targetDirFile.toPath())) {
targetDirFile.mkdir();
}
File file = new File(sourcePath);
ZipFile zipFile = null;
try {
zipFile = new ZipFile(file, Charset.forName("GBK"));
ZipEntry entry;
File entryFile;
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zipFile.entries();
while (entries.hasMoreElements()) {
entry = entries.nextElement();
if (entry.isDirectory()) {
return null;
}
entryFile = new File(targetDir + File.separator + entry.getName());
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(entryFile));
BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry))
) {
int length;
while ((length = bis.read(buffer, 0, bufferSize)) != -1) {
bos.write(buffer, 0, length);
}
bos.flush();
files.add(entryFile);
} catch (Exception e) {
LOG.error("文件读取出错", e);
return null;
}
}
return files;
} catch (IOException e) {
LOG.error("zip文件读取错误", e);
return null;
} finally {
try {
if (zipFile != null) {
zipFile.close();
}
} catch (IOException e) {
LOG.error("流关闭异常", e);
}
}
}
}
启动后直接访问浏览器访问:
http://localhost:8080/test/exportcsv
http://localhost:8080/test/exportZip
ok 导出成功