在 Java 開發中,Apache POI 是操作 Excel 的主流選擇,但其對記憶體消耗極大,尤其在大數據量導出場景下容易導致 OOM。CSV(Comma-Separated Values)本質上是純文本文件,以逗號分隔字段,可直接用 Excel 打開,卻擁有極高的寫入效率和極低的記憶體佔用,是大數據導出的理想替代方案。


以下封裝了一個泛型方法 exportCsv,支持任意實體列表導出,只需傳入表頭、對應屬性名及數據列表即可:
/**
* 導出生成 CSV 格式文件
* @param titles CSV 表頭
* @param propertys 實體屬性名,需與 titles 一一對應
* @param list 待導出的對象集合
* @return 成功返回 "0"
* @throws IOException / IllegalAccessException / IllegalArgumentException
*/
public static <T> String exportCsv(String[] titles, String[] propertys, List<T> list)
throws IOException, IllegalArgumentException, IllegalAccessException {
File file = new File("d:\\test.csv");
// 指定 GBK 編碼避免中文亂碼
try (OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream(file), "GBK")) {
// 寫入表頭
for (String title : titles) {
ow.write(title);
ow.write(",");
}
ow.write("\r\n");
// 遍歷數據列表,反射獲取屬性值
for (Object obj : list) {
Field[] fields = obj.getClass().getDeclaredFields();
for (String property : propertys) {
for (Field field : fields) {
field.setAccessible(true);
if (property.equals(field.getName())) {
Object val = field.get(obj);
ow.write(val != null ? val.toString() : "");
ow.write(",");
break;
}
}
}
ow.write("\r\n");
}
ow.flush();
}
return "0";
}
public void test() throws Exception {
String[] titles = {"ID", "姓名"};
String[] propertys = {"id", "name"};
List<User> list = new ArrayList<>();
list.add(new User(1L, "張三"));
list.add(new User(2L, "李四"));
CsvUtil.getInstance().exportCsv(titles, propertys, list);
}
titles 與 propertys 須嚴格一一對應,順序不一致會導致列錯位。BufferedWriter 或引入成熟庫(如 OpenCSV)處理轉義、換行等邊界情況。CSV 導出以其輕量、高效的特性,成為大數據量報表導出的首選方案。結合反射機制,可快速構建通用導出組件,顯著降低記憶體壓力,提升系統吞吐能力。