1. 程式人生 > >Java匯出CSV檔案

Java匯出CSV檔案

使用Java匯出CSV格式檔案

整理一波CSV匯出的方法,希望可以幫到有需要的朋友

什麼是CSV

CSV是一種通用的、相對簡單的檔案格式,其檔案以純文字形式儲存表格資料(數字和文字)。

組號,組名,時間,電話0,時間0,電話1,時間1,電話2,時間2,
策四,name,random,null,18993897778,13,18993897709,13,null,null,
策2,name2,random,null,18993897776,13,18993897775,13,null,null,

CSV格式的特點

由於CSV是一種純文字的檔案,因此其具有以下幾個特點

  • 支援追加模式寫入,節省記憶體。
  • CSV的檔案行數沒有限制。
  • CSV是純文字檔案,可以使用任何文字編輯器進行編輯。

匯出實現

工具類

public class CsvExportUtil {

    /**
     * CSV檔案列分隔符
     */
    private static final String CSV_COLUMN_SEPARATOR = ",";

    /**
     * CSV檔案行分隔符
     */
    private static final String CSV_ROW_SEPARATOR = "\r\n";

    /**
     * @param dataList 集合資料
     * @param titles   表頭部資料
     * @param keys     表內容的鍵值
     * @param os       輸出流
     */
    public static void doExport(List<Map<String, Object>> dataList, String titles, String keys, OutputStream os) throws Exception {

        // 保證執行緒安全
        StringBuffer buf = new StringBuffer();

        String[] titleArr = null;
        String[] keyArr = null;

        titleArr = titles.split(",");
        keyArr = keys.split(",");
        
        // 組裝表頭
        for (String title : titleArr) {
            buf.append(title).append(CSV_COLUMN_SEPARATOR);
        }
        buf.append(CSV_ROW_SEPARATOR);

        // 組裝資料
        if (CollectionUtils.isNotEmpty(dataList)) { 
            for (Map<String, Object> data : dataList) {
                for (String key : keyArr) {
                    buf.append(data.get(key)).append(CSV_COLUMN_SEPARATOR);
                }
                buf.append(CSV_ROW_SEPARATOR);
            }
        }

        // 寫出響應
        os.write(buf.toString().getBytes("GBK"));
        os.flush();
    }

    /**
     * 設定Header
     *
     * @param fileName
     * @param response
     * @throws UnsupportedEncodingException
     */
    public static void responseSetProperties(String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
        // 設定檔案字尾
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fn = fileName + sdf.format(new Date()) + ".csv";
        // 讀取字元編碼
        String utf = "UTF-8";

        // 設定響應
        response.setContentType("application/ms-txt.numberformat:@");
        response.setCharacterEncoding(utf);
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "max-age=30");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fn, utf));
    }

}

Controller

@GetMapping("/export")
public R export(HttpServletResponse response) {

        // 查詢需要匯出的資料
        List<Data> dataList = DataApi.listAll();

        if (CollectionUtils.isEmpty(dataList)) {
            return new R(HttpStatus.OK, "無可用資料");
        }

        // 構造匯出資料結構
        String titles = "組號,組名,時間";  // 設定表頭
        String keys = "no,name,time";  // 設定每列欄位
        
        // 構造匯出資料
        List<Map<String, Object>> datas = new ArrayList<>();
        Map<String, Object> map = null;
        for (Data data : dataList) {
            map = new HashMap<>();
            map.put("no", data.getNo());
            map.put("name", data.getName());
            map.put("time", data.getTime());
            datas.add(map);
        }

        // 設定匯出檔案字首
        String fName = "data_";

        // 檔案匯出
        try {
            OutputStream os = response.getOutputStream();
            CsvExportUtil.responseSetProperties(fName, response);
            CsvExportUtil.doExport(dataList, titles, keys, os);
            os.close();
        } catch (Exception e) {
            logger.error("匯出失敗", e.getMessage());
            return new R(HttpStatus.BAD_REQUEST, "匯出失敗");
        }
        return new R(HttpStatus.OK);
    }