over 7 years ago
CSV常常做為資料交換的一種手段,透過第三方元件可加快開發速度與讀取速度,這邊紀錄用opencsv跟apache.commons.csv兩種不同的用法
假設我們有個CSV轉換後的目標物件
package com.sam.data;
import lombok.Data;
@Data
public class StockAlert {
private String id;
private String name;
private String url;
}
下面是我們讀取對象CSV
id,name,url
1301,台塑,https://www.google.com.tw/alerts/feeds/14500439789290604405/2609808599257676796
1303,南亞,https://www.google.com.tw/alerts/feeds/14500439789290604405/6519899982382495908
1304,台聚,https://www.google.com.tw/alerts/feeds/14500439789290604405/11900768765428460088
1305,華夏,https://www.google.com.tw/alerts/feeds/14500439789290604405/16872102119975357308
1307,三芳,https://www.google.com.tw/alerts/feeds/14500439789290604405/6519899982382493936
在opencsv部分可透過下面方法來轉換
compile 'net.sf.opencsv:opencsv:2.+'
工具
package com.sam.utils;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.bean.CsvToBean;
import au.com.bytecode.opencsv.bean.HeaderColumnNameMappingStrategy;
public class Opencsv {
public static <T> List<T> parseFileToBeans(final String filepath, final char fieldDelimiter, final Class<T> beanClass) throws IOException{
//改用NIO方式讀檔
Path file = Paths.get(filepath);
BufferedReader br = Files.newBufferedReader(file, StandardCharsets.UTF_8);
//傳統讀檔方式
//BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filepath), StandardCharsets.UTF_8));
List<T> relist = parseBufferedReaderToBeans(br, fieldDelimiter, beanClass);
br.close();
return relist;
}
public static <T> List<T> parseResourceToBeans(final String filepath, final char fieldDelimiter, final Class<T> beanClass) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(ClassLoader.class.getResourceAsStream(filepath), "UTF-8"));
List<T> relist = parseBufferedReaderToBeans(br, fieldDelimiter, beanClass);
br.close();
return relist;
}
public static <T> List<T> parseBufferedReaderToBeans(final BufferedReader br, final char fieldDelimiter, final Class<T> beanClass){
CSVReader reader = null;
List<T> relist = null;
try {
reader = new CSVReader(br, fieldDelimiter);
final HeaderColumnNameMappingStrategy<T> strategy = new HeaderColumnNameMappingStrategy<T>();
strategy.setType(beanClass);
final CsvToBean<T> csv = new CsvToBean<T>();
relist = csv.parse(strategy, reader);
} catch (Exception e) {
e.printStackTrace();
}
return relist;
}
}
使用方式
package com.sam.gettest;
import java.io.IOException;
import java.util.List;
import com.sam.data.StockAlert;
import com.sam.utils.Opencsv;
public class TestLoad {
public static void main(String[] args) {
try {
List<StockAlert> list = Opencsv.parseFileToBeans("D:/stockalert.txt", ',', StockAlert.class);
for(StockAlert alert:list){
System.out.println(String.format("id=%s , name=%s , url=%s", alert.getId(), alert.getName(), alert.getUrl()));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
在apache.commons.csv部分則要這樣使用
compile 'org.apache.commons:commons-csv:1.+'
下面是已經包裝好的工具
package com.sam.utils;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
import org.apache.commons.csv.*;
public class Apachecsv {
public static List<CSVRecord> parseFileToBeans(final String filepath) throws IOException{
Path file = Paths.get(filepath);
BufferedReader br = Files.newBufferedReader(file, StandardCharsets.UTF_8);
List<CSVRecord> relist = parseBufferedReaderToBeans(br);
br.close();
return relist;
}
public static List<CSVRecord> parseBufferedReaderToBeans(final BufferedReader br){
CSVParser parser = null;
List<CSVRecord> records = null;
try {
parser = new CSVParser(br, CSVFormat.DEFAULT.withHeader());
records = parser.getRecords();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(parser!=null)
parser.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return records;
}
}
讀檔跟寫檔的使用
package com.sam.gettest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import org.apache.commons.csv.*;
import com.sam.utils.Apachecsv;
public class TestLoad2 {
private static final Object [] FILE_HEADER = {"stockid", "stockname", "alerturl"};
private static final String NEW_LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) throws IOException {
//讀檔
List<CSVRecord> list = Apachecsv.parseFileToBeans("D:/stockalert.txt");
for (CSVRecord record : list) {
System.out.printf("%s %s %s\n", record.get("id"), record.get("name"), record.get("url"));
}
//寫檔
CSVPrinter csvFilePrinter = null;
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
Path target = Paths.get("D:/test.csv");
if(Files.notExists(target)){
Files.createFile(target);
}
BufferedWriter writer = Files.newBufferedWriter(target, StandardCharsets.UTF_8, StandardOpenOption.WRITE);
//initialize CSVPrinter object
csvFilePrinter = new CSVPrinter(writer, csvFileFormat);
//Create CSV file header
if(list.size() > 0){
CSVRecord tmp = list.get(0);
csvFilePrinter.printRecord(tmp.toMap().keySet());
}else{
csvFilePrinter.printRecord(FILE_HEADER);
}
//Write a new object list to the CSV file
for (CSVRecord record : list) {
List dataRecord = new ArrayList();
for(int i=0;i<record.size();i++){
dataRecord.add(record.get(i).trim());
}
csvFilePrinter.printRecord(dataRecord);
}
writer.flush();
writer.close();
csvFilePrinter.close();
}
}