提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- ExportUtil
- 案例: ExportUtil.writeCsvFile
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";@PostConstructpublic 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
@Testpublic 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);}