使用Java opencsv 4.5-提示

时间:2019-02-28 17:50:33

标签: java javabeans opencsv

最近,我需要使用bean读写CSV文件。在此过程中,在研究了数百篇文章之后,我开发了一种功能解决方案。这篇文章是比问题更多的技巧和窍门...希望它可以加快您的工作速度,并避免如果您不遵循这些建议将导致的错误的惊人怪异...

1)要将opencsv与CsvToBean一起使用,您需要在项目中包括所有这些JAR文件(我在Eclipse中将它们作为“外部JAR”添加到了我的构建路径中):

commons-beanutils-1.9.3.jar
commons-collections-3.2.jar
commons-collections4-4.3.jar
commons-lang3-3.8.1.jar
opencsv-4.5.jar

是的-您需要两种版本的commons-collection才能读取和写入bean。

2)构建bean类时,属性和set / get方法必须具有特定的语法,否则您的读/写将失败(opencsv在运行时使用自省和反射)。主要是,您的属性必须全部小写:

Private String ppppp; …

并且get / set例程必须仅将属性的首字母大写:

public String getPpppp() …
public void setPpppp(String  value) …

3)使用@CsvBindByName或@CsvBindByPosition 按名称绑定将设置将在读取时映射到该属性的列的名称,按位置绑定将在写入时设置输出顺序。 (如果csv文件中没有标题,bindbyposition还将在读取时设置字段位置。)

@CsvBindByName(column = "ID", required = true)
@CsvBindByPosition(position = 0)
Private String pppppp;

如果该列中的任何数据为空或为空,则不要包含“ required = true”。

4)您的bean类必须具有null构造函数:(如果类名是“ Account”)

public Account() {
}

示例类文件

---------------- Account.java -------------------

package MyCsv;

import java.util.Optional;
import com.opencsv.*;
import com.opencsv.bean.*;

public class Account {

    @CsvBindByName(column = "PERSONNEL_ID", required = true)
    @CsvBindByPosition(position = 0)
    private String personnelid;

    @CsvBindByName(column = "LAST_NAME")
    @CsvBindByPosition(position = 1)
    private String lastname;

// set as constructor
    public Account() {
    }

    public String getPersonnelid()
    {
        return this.personnelid;
    }

    public void setPersonnelid(String value)
    {
        this.personnelid = value;
    }
    public String getLastname()
    {
        return this.lastname;
    }

    public void setLastname(String value)
    {
        this.lastname = value;
    }
    @Override
    public String toString() {
        return "Account [personnelid=" + this.personnelid + ", 
                     “ lastname=" + this.lastname);
    }
}

----------------结束Account.java -------------------

5)使用[有状态] CsvToBeanBuilder设置CSV阅读器。

…
    List<Account> Accounts = null;
…
    try {
        Reader freader = new FileReader(inFileName); 
        HeaderColumnNameMappingStrategy<Account> beanStrategy = new HeaderColumnNameMappingStrategy<Account>();
        beanStrategy.setType(Account.class);
        CsvToBean<Account> csvToBean = new CsvToBeanBuilder<Account>(freader)
                .withType(Account.class)
                .withIgnoreLeadingWhiteSpace(true)
                .withMappingStrategy(beanStrategy)
                .build();
        // reads all “Account”s – entire file - into a list of Account beans
        Accounts = csvToBean.parse();
        freader.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

6)使用StatefulBeanToCsvBuilder设置编写器。 (您可以在读写时使用相同的类,前提是您在编写时不更改读取字段的顺序):

Writer writer = new FileWriter(outFileName);

StatefulBeanToCsvBuilder<Account> builder = new StatefulBeanToCsvBuilder<Account>(writer);
StatefulBeanToCsv<Account> beanWriter = builder.build();

// build a header for output & make it the first record in your list
// requires a parameterized constructor (not shown above for brevity)
Account accountHeader = new Account("PersonnelID","LastName");
Accounts.add(0, accountHeader);

try {
    // writes all of the account beans in the accounts list at once
    beanWriter.write(Accounts);
} catch (CsvDataTypeMismatchException e) {
    e.printStackTrace();
} catch (CsvRequiredFieldEmptyException e) {
    e.printStackTrace();
}

writer.flush();
writer.close();

7)记住要刷新并关闭“写入”文件,然后关闭读取文件…

8)将所有字段都设为字符串。如果需要输入整数或日期,请在需要时在代码中显式地执行。当bean类具有用int或LocalDate声明的属性时,我得到了无法预料的结果。最简单的方法是在bean类中添加处理转换的get'ers和set'ers:

Public LocalDate getAsDatePpppp() …

Public void setAsDatePpppp(LocalDate theDateToSet) ...

0 个答案:

没有答案