提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
ExportUtil
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;
import javax.annotation.PostConstruct;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Component
public class ExportUtil {
private final static Logger logger = LoggerFactory.getLogger(ExportUtil.class);
/**
* 导出文件存储路径
*/
// public static String defaultRootPath = System.getProperty("user.dir") + File.separator;
/**
* set注入配置
*/
private static String folder;
@Value("${download.folder:download-file}")
public void setFolder(String folder){
ExportUtil.folder = folder;
}
/**
* 失败日志保存地址(生产环境必须使用共享盘),eg:D:\tuzhan_zhonghang_worksp\goods_media\import_error.csv
**/
private static String importFailLogDirectory;
/** CSV文件列分隔符 */
private static final String CSV_COLUMN_SEPARATOR = ",";
/** CSV文件列分隔符 */
private static final String CSV_RN = "\r\n";
/**CSV文件编码*/
private static final String CSV_CODE="gbk";
@PostConstruct
public void init() {
// 共享文件夹初始化
importFailLogDirectory = folder + File.separator + "goods_media" + File.separator;
}
/**
*
* @param fileName
* @param headerList
* @param filePath
* @param dataList
*/
public static void writeCsvFile(String fileName,List<List<Object>> headerList,String filePath, List<List<Object>> dataList) {
writeCsvFile(fileName,headerList,filePath,dataList,false);
}
public static void writeCsvFile(String fileName,List<List<Object>> headerList,String filePath, List<List<Object>> dataList,boolean append){
BufferedWriter csvWriter = null;
File file = new File(filePath);
try {
csvWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file,append), StandardCharsets.UTF_8), 1024);
//解决csv导出文件,中文乱码
//以csv方式导出的文件中默认不含BOM信息,通过给将要输出的内容设置BOM标识(以 EF BB BF 开头的字节流)即可解决该问题
csvWriter.write(new String(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}));
for (List<Object> header : headerList) {
writeRow(header, csvWriter);
}
if(CollectionUtils.isEmpty(dataList)){
writeRow(Lists.newArrayList("未查找到符合条件的数据,请修改查询条件"),csvWriter);
}else{
for (List<Object> row : dataList) {
writeRow(row, csvWriter);
}
}
csvWriter.flush();
} catch (Exception e) {
logger.error("生成csv文件错误=【{}】", e);
} finally {
try {
if (csvWriter != null) {
csvWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
logger.info("文件生成完成,文件名称:{}", file.getName());
}
public static void createCsvFile(String fileName,List<List<Object>> headerList,String rootPath, List<List<Object>> dataList){
// 声明文件路径及名称
if(rootPath==null){
rootPath = importFailLogDirectory;
}
logger.info("导出路径=【{}】",rootPath);
File folder = new File(rootPath);
if(!folder.exists() && !folder.isDirectory()){
folder.mkdirs();
}
File csvFile = new File(rootPath + fileName + ".csv");
BufferedWriter csvWriter = null;
try {
csvWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvFile), StandardCharsets.UTF_8), 1024);
//解决csv导出文件,中文乱码
//以csv方式导出的文件中默认不含BOM信息,通过给将要输出的内容设置BOM标识(以 EF BB BF 开头的字节流)即可解决该问题
csvWriter.write(new String(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}));
for (List<Object> header : headerList) {
writeRow(header, csvWriter);
}
for (List<Object> row : dataList) {
writeRow(row, csvWriter);
}
csvWriter.flush();
} catch (Exception e) {
logger.error("生成csv文件错误=【{}】", e);
} finally {
try {
if (csvWriter != null) {
csvWriter.close();
}
} catch (IOException e) {
}
}
logger.info("文件生成完成,文件名称:{}", csvFile.getName());
}
public static void createCsvFile(List<List<Object>> headerList,String fileName, List<List<Object>> dataList) {
createCsvFile(fileName,headerList,null,dataList);
}
/**
* 导出并下载
* @param fileName
* @param headerList
* @param dataList
*/
public static void exportAndDownLoadCsvFile(String fileName, List<List<Object>> headerList,
List<List<Object>> dataList, HttpServletResponse response) throws IOException {
BufferedWriter csvWriter = null;
ServletOutputStream fileOutputStream;
response.setContentType("application/vnd.ms-excel;charset=utf-8");
if(fileName!=null && fileName.endsWith(".csv")){
response.addHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
} else {
response.addHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".csv");
}
fileOutputStream = response.getOutputStream();
StopWatch stopWatch = new StopWatch();
stopWatch.start();
try {
csvWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8), 1024);
//解决csv导出文件,中文乱码
//以csv方式导出的文件中默认不含BOM信息,通过给将要输出的内容设置BOM标识(以 EF BB BF 开头的字节流)即可解决该问题
csvWriter.write(new String(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}));
for (List<Object> header : headerList) {
writeRow(header, csvWriter);
}
if(CollectionUtils.isEmpty(dataList)){
writeRow(Lists.newArrayList("未查找到符合条件的数据,请修改查询条件"),csvWriter);
}else{
for (List<Object> row : dataList) {
writeRow(row, csvWriter);
}
}
csvWriter.flush();
} catch (Exception e) {
logger.error("生成csv文件错误,文件名称:{};错误信息:【{}】", fileName,e);
} finally {
try {
if (csvWriter != null) {
csvWriter.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
stopWatch.stop();
logger.info("文件生成完成,文件名称:{} 耗时:{} ms", fileName,stopWatch.getTotalTimeMillis());
}
public static void writeRow(List<Object> row, BufferedWriter csvWriter) throws IOException {
for (Object data : row) {
if(data==null){
data="";
}
StringBuilder sb = new StringBuilder();
String rowStr = sb.append("\"").append(data).append("\",").toString();
csvWriter.write(rowStr);
}
csvWriter.newLine();
}
public static long parseLong(String s) throws NumberFormatException {
if(StringUtils.isBlank(s) || !StringUtils.isNumeric(s)){
return 0L;
}
return Long.parseLong(s);
}
/**
* 删除单个文件
*
* @return 单个文件删除成功返回true,否则返回false
*/
public static boolean deleteFile( File file) {
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public static byte[] exportCSV(List<List<Object>> dataList) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedWriter buffCvsWriter = null;
try {
buffCvsWriter = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
for (List<Object> row : dataList) {
writeRow(row, buffCvsWriter);
}
// 刷新缓冲
buffCvsWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (buffCvsWriter != null) {
try {
buffCvsWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return out.toByteArray();
}
private static void fillDataToCsv(BufferedWriter buffCvsWriter, LinkedHashMap row) throws IOException {
Map.Entry propertyEntry;
for (Iterator<Map.Entry> propertyIterator = row.entrySet().iterator(); propertyIterator.hasNext(); ) {
propertyEntry = propertyIterator.next();
buffCvsWriter.write("\"" + propertyEntry.getValue().toString() + "\"");
if (propertyIterator.hasNext()) {
buffCvsWriter.write(",");
}
}
}
public static Object escapeNullToRod(Object o){
if(o == null){
return "-";
}
return o;
}
public static Object escapeNullToZero(Object o){
if(o == null){
return "0";
}
return o;
}
}
案例: ExportUtil.writeCsvFile
@Test
public void CSVtest() throws IOException {
//标题 数据头
List<Object> titleHeader = Lists.newArrayList(new String(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF})
+ "日期范围:"
+ "2024-01-01"
+ "~"
+ "2024-06-03");
List<List<Object>> headerList = new ArrayList<>();
headerList.add(titleHeader);
headerList.add(Arrays.asList("ID", "月份", "薪水"));
//数据行
List<List<Object>> dataList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
ArrayList<String> values = Lists.newArrayList(i + "\t", (i + 1) + "月" + "\t", (1000 * i) + "\t");
dataList.add(new ArrayList<>(values));
}
String fileName = "数据报表.csv";
String path = "C:\\Users\\EDY\\Desktop\\fsdownload" + fileName;
ExportUtil.writeCsvFile(fileName, headerList, path, dataList);
}