提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 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);}