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);
}