I searched for and used the Java CSV library in my business, so I will summarize it as a memorandum.
The CSV libraries in Java are as follows.
This time I used opencsv.
opencsv 4 is compatible with java7 or later. Also, please note that the usage is different between opencs v3.x and opencs v4.x.
Read and output the CSV file (item.csv) with the following contents.
item.csv
"Product ID","Product name","unit price","quantity"
001,"Potato chips",150,50
002,"chocolate",100,30
003,"ice",120,10
There are 3 points.
Add opencsv to Gradle's dependency. If you exclude commons-logging, comment it out. I get an exception at run time.
build.gradle
//Comment out is required if there is the following description
configurations {
//all*.exclude module: 'commons-logging'
}
dependencies {
compileOnly group:'org.projectlombok', name:'lombok', version:'1.16.20'
//csv library
implementation group:'com.opencsv', name:'opencsv', version:'4.1'
implementation group:'commons-logging', name: 'commons-logging', version:'1.2'
}
Also, prepare an Entity class that matches the items in the CSV file. By adding annotations to the fields of the Entity class, the Entity class and the columns of the CSV file are linked.
Annotation can be selected from two types according to the capture pattern.
@CsvBindByName
Associate header column and field@CsvBindByPosition
Associate the input order with the field (exclude this time because it has a header)When using @CsvBindByName
ItemEntity.java
package entity;
import com.opencsv.bean.CsvBindByName;
import lombok.Data;
/**
*Entity class that manages products.
*/
@Data
public class ItemEntity {
@CsvBindByName(column = "Product ID", required = true)
private String id;
@CsvBindByName(column = "Product name", required = true)
private String name;
@CsvBindByName(column = "unit price", required = true)
private int price;
@CsvBindByName(column = "quantity", required = true)
private int amount;
}
When using @CsvBindByPosition
ItemEntity2.java
package entity;
import com.opencsv.bean.CsvBindByPosition;
import lombok.Data;
/**
*Entity class that manages products.
*/
@Data
public class ItemEntity2 {
@CsvBindByPosition(position = 0, required = true)
private String id;
@CsvBindByPosition(position = 1, required = true)
private String name;
@CsvBindByPosition(position = 2, required = true)
private int price;
@CsvBindByPosition(position = 3, required = true)
private int amount;
}
This is a code sample for reading CSV.
ItemFileDao.java
CsvToBean<ItemEntity> csvToBean = new CsvToBeanBuilder<ItemEntity>(reader).withType(ItemEntity.class).build();
List<ItemEntity> items = csvToBean.parse();
Use the CsvToBeanBuilder (http://opencsv.sourceforge.net/apidocs/com/opencsv/bean/CsvToBeanBuilder.html) class.
Be sure to call the CsvToBeanBuilder # withType
method or the CsvToBeanBuilder # withMappingStrategy
method.
Use the CsvToBeanBuilder # withSeparator
method to specify a separator.
The code sample uses the Entity class with @ CsvBindByName
.
For Entity classes using @ CsvBindByPosition
, similar results would be obtained without the header.
This is a code sample for CSV output.
ItemFileDao.java
StatefulBeanToCsv<ItemEntity> beanToCsv = new StatefulBeanToCsvBuilder<ItemEntity>(writer).build();
beanToCsv.write(beans);
Use the StatefulBeanToCsvBuilder (http://opencsv.sourceforge.net/apidocs/com/opencsv/bean/StatefulBeanToCsvBuilder.html) class.
Use the CsvToBeanBuilder # withSeparator
method to specify a separator.
When using the Entity class using @ CsvBindByName
, the header is added automatically, but the column order seems to be the character code order (?) Of the header.
If you use the Entity class with @CsvBindByPosition
, the header will not be added automatically.
ItemFileDao.java
import java.io.Reader;
import java.io.Writer;
import java.util.List;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.opencsv.exceptions.CsvException;
/**
*Dao class that exchanges with CSV files.
*/
public class ItemFileDao {
public void write(Writer writer, List<ItemEntity> beans) throws CsvException {
StatefulBeanToCsv<ItemEntity> beanToCsv = new StatefulBeanToCsvBuilder<ItemEntity>(writer).build();
beanToCsv.write(beans);
}
public List<ItemEntity> read(Reader reader) throws CsvException {
CsvToBean<ItemEntity> csvToBean = new CsvToBeanBuilder<ItemEntity>(reader).withType(ItemEntity.class).build();
return csvToBean.parse();
}
}
Main.java
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import com.opencsv.exceptions.CsvException;
public class Main {
public static void main(String[] args) {
ItemFileDao csvFileDao = new ItemFileDao();
try (Reader reader = Files.newBufferedReader(Paths.get("item.csv"));
Writer writer = Files.newBufferedWriter(Paths.get("item2.csv"));) {
List<ItemEntity> items = csvFileDao.read(reader);
items.forEach(System.out::println);
csvFileDao.write(writer, items);
} catch (IOException e) {
e.printStackTrace();
} catch (CsvException e) {
e.printStackTrace();
}
}
}
ItemEntity(id=001, name=Potato chips, price=150, amount=50)
ItemEntity(id=002, name=chocolate, price=100, amount=30)
ItemEntity(id=003, name=ice, price=120, amount=10)
item2.csv
"unit price","Product ID","Product name","quantity"
"150","001","Potato chips","50"
"100","002","chocolate","30"
"120","003","ice","10"
Recommended Posts