假如当前工程有很多的画面要做CSV文件下载的功能,这时我们需要一个CSV下载的共同处理工具,这个工具能处理不同对象类型的List数据。这时我们会想到用反射来实现。具体的实现请看下记代码。当然有很多的CSV处理工具,以下只是一个菜鸟的想法。有不对的地方或者能提高性能的地方,请大佬纠正。
package com.dhc.test;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
Test test = new Test();
List<UserDto> userList = new ArrayList<UserDto>(
Arrays.asList(new UserDto(1, "wsy")
, new UserDto(2, "wx")));
List<AdminDto> adminList = new ArrayList<AdminDto>(
Arrays.asList(new AdminDto(1, "w", "男")
, new AdminDto(2, "wx", "女")));
test.csvDownload(userList);
test.csvDownload(adminList);
}
private <T> void csvDownload(List<T> csvList) {
File file = new File("C://Users/asus/Desktop/test"
+ DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss_SSS").format(LocalDateTime.now()) + ".csv");
try(BufferedWriter buff = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file)))) {
for (T t : csvList) {
StringBuilder sb = new StringBuilder();
Field[] fields = t.getClass().getFields();
int len = fields.length;
for (int i = 0; i < len; i++) {
try {
sb.append("\"");
sb.append(fields[i].get(t));
sb.append("\"");
if (0 <= i && i < len - 1) {
sb.append(",");
} else {
sb.append("\n");
}
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
buff.append(sb.toString());
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
class UserDto {
public int id;
public String name;
public UserDto(int id, String name) {
super();
this.id = id;
this.name = name;
}
}
class AdminDto {
public int id;
public String name;
public String sex;
public AdminDto(int id, String name, String sex) {
super();
this.id = id;
this.name = name;
this.sex = sex;
}
}
还有另一种方法,省去一层循环,可能效率会高一些。代价就是耦合性比较大,对与Bean来说需要提供一个将对象拼接成CSV数据格式的方法。之后使用反射调用当前对象的csvToString方法。
public <T> void csvDownloadReflectGetMethod(List<T> csvList) {
for (int i = 0; i < csvList.size(); i++) {
T t = csvList.get(i);
StringBuilder sb = new StringBuilder();
try {
Method method = t.getClass().getMethod("csvToString");
sb.append(method.invoke(t));
if (i != csvList.size() - 1) {
sb.append("\r\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class UserDto {
public int id;
public String name;
public UserDto () {
}
public UserDto(int id, String name) {
super();
this.id = id;
this.name = name;
}
public String csvToString() {
return new StringBuilder()
.append("\"")
.append(this.id)
.append("\"")
.append(",")
.append("\"")
.append(this.name)
.append("\"")
.toString();
}
public String toString() {
return "UserDto [" + this.id + ", " + this.name + "]";
}
}