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);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章