Skip to content

Commit 9e95794

Browse files
committed
feat: 增加工具类:导入导出CSV文件的两种实现方式。
1) 直接使用IO读取csv文件的每一行数据; 2) 使用第三方jar包导入导出csv文件;
1 parent 2eaef66 commit 9e95794

File tree

3 files changed

+339
-0
lines changed

3 files changed

+339
-0
lines changed

springboot-aop/pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,17 @@
184184
<artifactId>spring-kafka-test</artifactId>
185185
<scope>test</scope>
186186
</dependency>
187+
<dependency>
188+
<groupId>commons-net</groupId>
189+
<artifactId>commons-net</artifactId>
190+
<version>3.3</version>
191+
</dependency>
192+
<!--第三方jar包,操作csv文件的导入导出-->
193+
<dependency>
194+
<groupId>net.sourceforge.javacsv</groupId>
195+
<artifactId>javacsv</artifactId>
196+
<version>2.0</version>
197+
</dependency>
187198
</dependencies>
188199

189200
<build>
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
package com.study.module.util.office;
2+
3+
import com.alibaba.fastjson.JSONObject;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
import org.springframework.util.ObjectUtils;
9+
10+
import java.io.*;
11+
import java.lang.reflect.Field;
12+
import java.text.SimpleDateFormat;
13+
import java.util.*;
14+
15+
/**
16+
* CSV 转换程 excel
17+
*
18+
* @author drew
19+
* @date 2021/2/23 10:32
20+
**/
21+
public class CsvUtil {
22+
23+
private static CsvUtil instance;
24+
25+
public CsvUtil() {
26+
}
27+
28+
public static CsvUtil getInstance() {
29+
if (instance == null) {
30+
synchronized (CsvUtil.class) {
31+
if (instance == null) {
32+
instance = new CsvUtil();
33+
}
34+
}
35+
}
36+
return instance;
37+
}
38+
39+
public static void main(String[] args) throws Exception {
40+
41+
testReadCsv();
42+
// testExportCsv();
43+
// testExportCsvPlus();
44+
}
45+
46+
private static void testReadCsv() {
47+
while (true) {
48+
System.out.println("读取csv文件的数据:(示例文件地址为:D:/csv-demo-1.csv)");
49+
Scanner scanner = new Scanner(System.in);
50+
String in = scanner.nextLine();
51+
if ("exit".equals(in)) {
52+
break;
53+
}
54+
System.out.println("文件的数据如下:\n" + JSONObject.toJSONString(readCsv(in)));
55+
}
56+
}
57+
58+
private static void testExportCsv() {
59+
String birthDay = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
60+
List<Object> head = Arrays.asList("姓名", "年龄", "成绩", "性别", "出生日期", "是否有效");
61+
List<List<Object>> dataList = Arrays.asList(
62+
Arrays.asList("Drew", 23, 99.4, birthDay, "男", true),
63+
Arrays.asList("Mark", 43, 43.5, null, "男", true),
64+
Arrays.asList("Bob", 20, 20.0, "", "男", true),
65+
Arrays.asList("King", 19, null, null, "男", true),
66+
Arrays.asList("King", null, null, null, "男", true)
67+
);
68+
String outPutPath = "D:/";
69+
String filename = UUID.randomUUID().toString().substring(0, 8);
70+
71+
exportCsv(head, dataList, outPutPath, filename);
72+
System.out.println("生成 CSV 文件成功!文件位置为:" + outPutPath + filename);
73+
}
74+
75+
public static void testExportCsvPlus() throws IOException, IllegalArgumentException, IllegalAccessException {
76+
String[] titles = new String[]{"姓名", "年龄", "成绩", "性别", "出生日期", "是否有效"};
77+
String[] propertys = new String[]{"name", "age", "grades", "sex", "birthday", "enabled"};
78+
User user = new User();
79+
user.setName("abc");
80+
user.setAge(null);
81+
user.setGrades(45.5F);
82+
user.setSex("");
83+
user.setBirthday(new Date());
84+
user.setEnabled(true);
85+
86+
List<User> dataList = Arrays.asList(user, user, user);
87+
String outputFilePath = "D:/" + UUID.randomUUID().toString().replaceAll("-", "").concat(".csv");
88+
CsvUtil.exportCsvPlus(titles, propertys, dataList, outputFilePath);
89+
System.out.println("导出成功,位置为:" + outputFilePath);
90+
}
91+
92+
@Data
93+
@Builder
94+
@NoArgsConstructor
95+
@AllArgsConstructor
96+
static class User {
97+
private String name;
98+
private Integer age;
99+
private Float grades;
100+
private String sex;
101+
private Date birthday;
102+
private Boolean enabled;
103+
}
104+
105+
106+
/**
107+
* 读取csv文件的数据
108+
*
109+
* @param csvFilePath csv文件所在位置(例如:“D:\评价数据.csv”)
110+
* @return 数据集合
111+
*/
112+
public static List<List<Object>> readCsv(String csvFilePath) {
113+
List<List<Object>> result = new ArrayList<>();
114+
try {
115+
//换成你的文件名
116+
BufferedReader reader = new BufferedReader(new FileReader(csvFilePath));
117+
reader.readLine();//第一行信息,为标题信息,不用,如果需要,注释掉
118+
String line = null;
119+
while ((line = reader.readLine()) != null) {
120+
//CSV格式文件为逗号分隔符文件,这里根据逗号切分
121+
List<Object> item = Arrays.asList(line.split(","));
122+
if (!ObjectUtils.isEmpty(item)) {
123+
// TODO 针对item集合中的每一个数据,可以进行具体类型转换(例如转称 integer类型,string类型,集合set/list类型等)
124+
result.add(item);
125+
}
126+
}
127+
} catch (IOException e) {
128+
e.printStackTrace();
129+
}
130+
return result;
131+
}
132+
133+
/**
134+
* 导出生成csv格式的文件
135+
*
136+
* @param titles csv格式头文
137+
* @param properties 需要导出的数据实体的属性,注意与title一一对应
138+
* @param list 需要导出的对象集合
139+
* @param outPutFilePath 输出文件地址(例如:D:\\test.csv)
140+
* @return
141+
* @throws IllegalAccessException
142+
* @throws IllegalArgumentException
143+
*/
144+
public static <T> String exportCsvPlus(String[] titles, String[] properties, List<T> list, String outPutFilePath) throws IOException, IllegalArgumentException, IllegalAccessException {
145+
File file = new File(outPutFilePath);
146+
//构建输出流,同时指定编码
147+
OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream(file), "gbk");
148+
149+
//csv文件是逗号分隔,除第一个外,每次写入一个单元格数据后需要输入逗号
150+
for (String title : titles) {
151+
ow.write(title);
152+
ow.write(",");
153+
}
154+
//写完文件头后换行
155+
ow.write("\r\n");
156+
//写内容
157+
for (Object obj : list) {
158+
//利用反射获取所有字段
159+
Field[] fields = obj.getClass().getDeclaredFields();
160+
for (String property : properties) {
161+
for (Field field : fields) {
162+
//设置字段可见性
163+
field.setAccessible(true);
164+
if (property.equals(field.getName())) {
165+
ow.write(String.valueOf(field.get(obj)));
166+
ow.write(",");
167+
}
168+
}
169+
}
170+
//写完一行换行
171+
ow.write("\r\n");
172+
}
173+
ow.flush();
174+
ow.close();
175+
return "0";
176+
}
177+
178+
179+
/**
180+
* CSV文件生成方法
181+
*
182+
* @param head 表头信息
183+
* @param dataList 具体数据信息
184+
* @param outPutPath 数据文件路径(例如:”D:/outCsvDir/“)
185+
* @param filename 自定义文件名(例如:”csv-out-file“)
186+
* @return
187+
*/
188+
public static File exportCsv(List<Object> head, List<List<Object>> dataList, String outPutPath, String filename) {
189+
File csvFile = null;
190+
BufferedWriter csvWriter = null;
191+
try {
192+
csvFile = new File(outPutPath + File.separator + filename + ".csv");
193+
File parent = csvFile.getParentFile();
194+
if (parent != null && !parent.exists()) {
195+
parent.mkdirs();
196+
}
197+
csvFile.createNewFile();
198+
199+
// GB2312使正确读取分隔符","
200+
csvWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvFile), "GB2312"), 1024);
201+
// 写入文件头部
202+
writeRow(head, csvWriter);
203+
204+
// 写入文件内容
205+
for (List<Object> row : dataList) {
206+
writeRow(row, csvWriter);
207+
}
208+
csvWriter.flush();
209+
} catch (Exception e) {
210+
e.printStackTrace();
211+
} finally {
212+
try {
213+
csvWriter.close();
214+
} catch (IOException e) {
215+
e.printStackTrace();
216+
}
217+
}
218+
return csvFile;
219+
}
220+
221+
/**
222+
* 写一行数据方法
223+
*
224+
* @param row
225+
* @param csvWriter
226+
* @throws IOException
227+
*/
228+
private static void writeRow(List<Object> row, BufferedWriter csvWriter) throws IOException {
229+
// 写入文件头部
230+
for (Object data : row) {
231+
String rowStr = "\"" + data + "\",";
232+
csvWriter.write(rowStr);
233+
}
234+
csvWriter.newLine();
235+
}
236+
237+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.study.module.util.office;
2+
3+
import com.alibaba.fastjson.JSONObject;
4+
import com.csvreader.CsvReader;
5+
import com.csvreader.CsvWriter;
6+
7+
import java.io.IOException;
8+
import java.nio.charset.StandardCharsets;
9+
import java.util.Arrays;
10+
import java.util.LinkedList;
11+
import java.util.List;
12+
import java.util.UUID;
13+
14+
/**
15+
* 引入第三方的jar包操作CSV文件(导入导出)
16+
*
17+
* @author drew
18+
* @date 2021/2/23 13:45
19+
**/
20+
public class CsvUtilPlus {
21+
22+
public static void main(String[] args) throws Exception {
23+
// 生成CSV文件
24+
String outputFilePath = "D:/" + UUID.randomUUID().toString().substring(0, 4) + ".csv";
25+
List<String> headers = Arrays.asList("姓名", "年龄", "性别", "成绩");
26+
List<List<String>> content = Arrays.asList(
27+
Arrays.asList("drew", "12", "男", null),
28+
Arrays.asList(),
29+
Arrays.asList(),
30+
Arrays.asList("Mark", "", null, "89.3"),
31+
Arrays.asList()
32+
);
33+
writer(headers, content, outputFilePath);
34+
System.out.println("导出CSV文件成功, 文件所在位置:" + outputFilePath);
35+
36+
// 读取上方生成的CSV文件
37+
System.out.println("读取数据成功,数据如下:\n" + JSONObject.toJSONString(read(outputFilePath)));
38+
}
39+
40+
/**
41+
* 读取 CSV 文件的数据【读物CSV文件的API:http://javacsv.sourceforge.net/com/csvreader/CsvReader.html】
42+
*
43+
* @param srcCsvPath csv文件存放的位置(例如:"F:/demo.csv")
44+
* @throws IOException
45+
*/
46+
public static List<List<String>> read(String srcCsvPath) throws IOException {
47+
List<List<String>> result = new LinkedList<>();
48+
// 第一参数:读取文件的路径 第二个参数:分隔符(不懂仔细查看引用百度百科的那段话) 第三个参数:字符集
49+
CsvReader csvReader = new CsvReader(srcCsvPath, ',', StandardCharsets.UTF_8);
50+
51+
// 如果你的文件没有表头,这行不用执行;这行不要是为了从表头的下一行读,也就是过滤表头
52+
csvReader.readHeaders();
53+
54+
// 读取每行的内容
55+
while (csvReader.readRecord()) {
56+
String lineData = csvReader.getRawRecord();
57+
String[] arr = lineData.split(",");
58+
result.add(Arrays.asList(arr));
59+
60+
// // 获取内容的两种方式
61+
// // 1. 通过下标获取
62+
// System.out.print(csvReader.get(0));
63+
// // 2. 通过表头的文字获取
64+
// System.out.println(" " + csvReader.get("年龄"));
65+
}
66+
return result;
67+
}
68+
69+
70+
/**
71+
* 导出CSV文件(写入CSV文件的API:http://javacsv.sourceforge.net/com/csvreader/CsvWriter.html)
72+
*
73+
* @param outPutFilePath csv文件输出路径(例如:"D:/demo.csv")
74+
* @param headers 表头
75+
* @param content 数据集合
76+
* @throws IOException
77+
*/
78+
public static void writer(List<String> headers, List<List<String>> content, String outPutFilePath) throws IOException {
79+
80+
// 第一参数:新生成文件的路径 第二个参数:分隔符(不懂仔细查看引用百度百科的那段话) 第三个参数:字符集
81+
CsvWriter csvWriter = new CsvWriter(outPutFilePath, ',', StandardCharsets.UTF_8);
82+
// 写表头和内容,因为csv文件中区分没有那么明确,所以都使用同一函数,写成功就行
83+
csvWriter.writeRecord(headers.toArray(new String[0]));
84+
for (List<String> line : content) {
85+
csvWriter.writeRecord(line.toArray(new String[0]));
86+
}
87+
// 关闭csvWriter
88+
csvWriter.close();
89+
}
90+
91+
}

0 commit comments

Comments
 (0)