CSV读写、追加操作
概述
-
在现在的项目中,财务人员反馈,我要把6万条数据导出来生成excel直接报60s超时异常。这时候苦逼的程序猿就要开始查询问题了,发现我们数据放入excel的时候特别的慢,于是我们改用csv格式导出.
直接上代码
package com.eam.util;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.jxstar.util.MapUtil;
import org.jxstar.util.StringFormat;
import org.jxstar.util.StringUtil;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* csv文件 操作工具类(写,追加)
* @author lzt
* editUser:楼梯间的男孩
* editdate:2021/11/23
*
*/
public class CsvFilePrinterTest {
public static void main(String[] args) {
//字段名
List<String> titleList = new ArrayList<>();
titleList.add("姓名");
titleList.add("性别");
titleList.add("语文");
titleList.add("数学");
//数据
List<Map<String,String>> contextList = new ArrayList<>();
Map<String,String> contextMap = new HashMap<>();
contextMap.put("name","张三");
contextMap.put("sex","女");
contextMap.put("chinese","83");
contextMap.put("math","95");
contextList.add(contextMap);
//绝对路径
String absFilePath = "E:/test.csv";
//创建scv文件并插入一行数据
doExportCsv(titleList,contextList,absFilePath);
//在往里面追加一条数据
doAppendCsv(titleList,contextList,absFilePath);
}
/** ===========================================================
*
* Purpose : 往csv格式文件写内容
* @params: titleList csv格式头
* @params: contextList 需要导出的对象集合
* @params: absFilePath 文件绝对路径
* @return
* Author : lzt
* Created Date : 2021-11-23
* Update History
* Version Date Name Description
* -------- --------------- -------------- --------------------
* V1.0 2021-11-23 lzt Creation
* ===========================================================*/
public static void doExportCsv(List<String> titleList, List<Map<String,String>> contextList, String absFilePath){
FileOutputStream fileOutputStream = null;
OutputStreamWriter outputStreamWriter = null;
try{
//获取文件流
fileOutputStream = new FileOutputStream(absFilePath);
outputStreamWriter = new OutputStreamWriter(fileOutputStream,"UTF-8");
outputStreamWriter.write(getBOM());
//第一行 头字段 姓名、性别、语文、数学
String[] header = new String[titleList.size()];
for(int i = 0;i<titleList.size();i++){
String title = titleList.get(i);
header[i] = title;
}
//默认头字段
CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader(header);
CSVPrinter csvPrinter = new CSVPrinter(outputStreamWriter,csvFormat);
for(Map<String,String> contextMap:contextList){
List<String> context = new ArrayList<>();
for(String title:titleList){
String fileKey = "";
switch (title){
case "姓名" :
fileKey = "name";
break;
case "性别" :
fileKey = "sex";
break;
case "语文" :
fileKey = "chinese";
break;
case "数学" :
fileKey = "math";
break;
}
context.add(contextMap.get(fileKey));
}
//插入一行
csvPrinter.printRecord(context);
}
csvPrinter.flush();
csvPrinter.close();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(outputStreamWriter!=null){
outputStreamWriter.close();
}
if(fileOutputStream!=null){
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/** ===========================================================
*
* Purpose : 往csv格式文件追加内容
* @params: titleList csv格式头
* @params: contextList 需要导出的对象集合
* @params: absFilePath 文件绝对路径
* @return
* Author : lzt
* Created Date : 2021-11-23
* Update History
* Version Date Name Description
* -------- --------------- -------------- --------------------
* V1.0 2021-11-23 lzt Creation
* ===========================================================*/
public static void doAppendCsv(List<String> titleList, List<Map<String,String>> contextList, String absFilePath){
FileWriter writer = null;
try{
//允许追加
writer = new FileWriter(absFilePath, true);
String[] header = new String[titleList.size()];
for(int i = 0;i<titleList.size();i++){
String title = titleList.get(i);
header[i] = title;
}
//默认第一行是头字段
CSVFormat csvFormat = CSVFormat.DEFAULT.withFirstRecordAsHeader();
CSVPrinter csvPrinter = new CSVPrinter(writer,csvFormat);
for(Map<String,String> contextMap:contextList){
List<String> context = new ArrayList<>();
for(String title:titleList){
String fileKey = "";
switch (title){
case "姓名" :
fileKey = "name";
break;
case "性别" :
fileKey = "sex";
break;
case "语文" :
fileKey = "chinese";
break;
case "数学" :
fileKey = "math";
break;
}
context.add(contextMap.get(fileKey));
}
//插入一行
csvPrinter.printRecord(context);
}
csvPrinter.flush();
csvPrinter.close();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(writer!=null){
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 功能说明:获取UTF-8编码文本文件开头的BOM签名。
* BOM(Byte Order Mark),是UTF编码方案里用于标识编码的标准标记。例:接收者收到以EF BB BF开头的字节流,就知道是UTF-8编码。
* @return UTF-8编码文本文件开头的BOM签名
*/
public static String getBOM() {
byte b[] = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
return new String(b);
}
}
效果

结论
-
相对于excel导入来说 csv真的是大数据量下载的福音 -
csv生成非常容易,消耗的内存比excel少 -
注意生成csv的时候需要写入前段字节流,防止乱码getBOM(),因为我这边有客户反应,用完整版的excel打开会乱码,而用wps简易版不会 -
操作简单,消耗内存少,速度快,对于编程人员来讲,真香! -
最后,关注下无名的公众号吧【楼梯间的男孩】!
原文始发于微信公众号(楼梯间的男孩):CSV读写、追加操作
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/197449.html