【问题标题】:How to write an Object with list into csv file using univocity writer如何使用单义性编写器将带有列表的对象写入 csv 文件
【发布时间】:2015-08-12 04:57:23
【问题描述】:

我有一个 Java bean A 如下

String name;
List<Address> address;

Address 又是一个 bean,如下所示

String city;
int pinCode;

当使用 @Parsed 的 univocity bean writer 处理器注解时,地址字段被写入 csv 文件中的对象。如何使它打印城市和密码值?

这是我生成 CSV 文件的代码

File csvFile = File.createTempFile("NEW" + ".csv", "");
Writer out = new FileWriter(csvFile);

FixedWidthFieldLengths lengths = new FixedWidthFieldLengths(30, 20);
FixedWidthWriterSettings settings = new FixedWidthWriterSettings(lengths);

// Creates a BeanWriterProcessor that handles annotated fields in the UserVo class.
settings.setRowWriterProcessor(new BeanWriterProcessor<UserVO>(UserVO.class));

// Sets the file headers
settings.setHeaders("Username", "listOfAddresses");

// Creates a writer with the above settings;
FixedWidthWriter writer = new FixedWidthWriter(out, settings);

// Writes the headers specified in the settings
writer.writeHeaders();

// writes a fixed width row with empty values (new UserVO instance).
writer.processRecord(new UserVO());

// writes values of UserVO
writer.processRecords(userVOs);

writer.close();

response().setContentType("text/csv");
response().setHeader("Content-disposition", "attachment;filename=" + csvFile.getName());
return ok(csvFile);

并且UserVO 映射到带有@Parsed 注释的输出文件,如下所示

public class UserVO {
    @NullString(nulls = { "?", "-" })
    @LowerCase
    @Parsed
    private String username;

    @Parsed
    private List<Address> listOfAddresses;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public List<Address> getListOfAddresses() {
        return listOfAddresses;
    }

    public void setListOfAddresses(List<Address> listOfAddresses) {
        this.listOfAddresses = listOfAddresses;
    }
}

【问题讨论】:

  • 张贴一些你在 CSV 中写作的代码
  • @Sarz 已经发布了代码 sn-p

标签: java csv export-to-csv


【解决方案1】:

对于您的情况,您可以创建一个自定义转换类来处理 bean 中的任意元素。检查tutorial 的以下部分:在注释中使用您自己的转换

使用您自己的示例,我创建了以下自定义转换以打印集合中的对象:

public class CollectionConversion implements Conversion<String, Collection<?>> {

private String separator = "|";

public CollectionConversion(String[] args) {
    if (args.length > 0) {
        separator = args[0];
    }
}

@Override
public Collection<?> execute(String input) {
    return null;
}

//You only need to implement this one when writing.
@Override
public String revert(Collection<?> input) {
    if (input == null) {
        return "";
    }
    StringBuilder out = new StringBuilder();
    for (Object element : input) {
        if (out.length() > 0) {
            out.append(this.separator);
        }
        out.append(element.toString());
    }
    return out.toString();
}
}

此实现依赖于集合中元素的 toString(),因此我的 Address 类如下所示:

public class Address {
    String city;
    int pinCode;

    public String toString() {
        return city + " (" + pinCode + ")";
    }
}

现在,在您的 UserVO 类中,您可以像这样指定地址列表:

@Convert(conversionClass = CollectionConversion.class, args = { ";" })
@Parsed
private List<Address> listOfAddresses;

在我的测试中,我创建了几个地址: ... writer.processRecord(new UserVO());

    List<Address> addresses = new ArrayList<Address>();
    Address a = new Address();
    a.city = "New York";
    a.pinCode = 14;

    Address b = new Address();
    b.city = "Sydney";
    b.pinCode = 345;

    addresses.add(a);
    addresses.add(b);

    UserVO vo1 = new UserVO();
    vo1.setUsername("User1");
    vo1.setListOfAddresses(addresses);

    List<UserVO> userVOs = new ArrayList<UserVO>();
    userVOs.add(vo1);

    writer.processRecords(userVOs);
    ...

我将第二个字段的长度从 20 更改为 50(否则输出将被截断)。这将产生:

Username                      listOfAddresses                                   
?                                                                               
user1                         New York (14);Sydney (345)                        

【讨论】:

  • 是的,这将是打印集合值的解决方案。但是如果需要将城市和密码值打印为列,那么我们必须在 UserVO 类中将它们声明为单独的字段
【解决方案2】:

我正在使用相同的单义性编写器将对象写入 csv 文件。一些数据写为空。在写之前。我正在记录它,我可以看到数据。但是一旦完成写入,它就会在 csv 文件中反映为空。

settings.setRowWriterProcessor(new BeanWriterProcessor<Employee>(Employee.class));

writers.writeHeaders("added headers here");

List<Employee> employeeList = service.generatereport(start,enddate);

for(employeel:employeeList) {

//here when i print the values of employeel.getSomethings - i'm getting the value

writer.processRecord(employeel);

//in csv it is null.
}

【讨论】:

  • 谢谢,从某种意义上说是格式化,我需要使用univocity中称为格式化的任何方法吗?
  • 你能回答我过去 3 小时一直卡在这里吗。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2013-04-27
相关资源
最近更新 更多