简体   繁体   English

从对象列表生成CSV

[英]Generate CSV from List of Objects

I am trying to generate a CSV from the results of a hibernate query, it could contain up to 200k rows, and when created the CSV could be around 30MB. 我正在尝试从休眠查询的结果生成CSV,它可能包含多达20万行,并且在创建时CSV可能约为30MB。

I am struggling to get the performance anything near acceptable. 我正在努力使性能接近可接受的水平。 Currently my hibernate query will return a list of objects. 目前,我的休眠查询将返回对象列表。 I am then using a StringBuilder to generate a CSV string. 然后我使用StringBuilder生成CSV字符串。 Then I get a byte array from that, and pass the byte array into response.outputstream.write() method. 然后,我从中获得一个字节数组,并将该字节数组传递给response.outputstream.write()方法。

What should I be doing in order to generate a CSV of this size efficiently? 为了有效地生成这样大小的CSV,我应该怎么做?

My Service 我的服务

List<Object> objectList = hibernateDao.getObjectList(objectList);

    StringBuilder sb = new StringBuilder();
    sb.append("field1_id,field2,field3,field14");
    for(Object object : objectList){
        sb.append("\n");
        sb.append(object.field1());
        sb.append(",");
        sb.append(object.field2());
        sb.append(",");
        sb.append(object.field3());
        ...
        ...
        sb.append(",");
        sb.append(object.field14);
    }
    byte[] bytes = sb.toString().getBytes();
    return bytes;

My Controller will get the resulting bytes[] 我的控制器将得到结果字节[]

response.setHeader("Content-Type", "text/comma-separated-values");
response.getOutputStream().write(objectService.getListByteArray());

The problem initially appears to be on your StringBuilder expanding, you could initialize it to allocate big number of characters but then the length of the content you are trying to write might go over Integer.MAX_VALUE (the maximum length of a char[] ) and you'll get a buffer overflow error. 问题最初似乎是在你的StringBuilder扩展,你可以初始化它来分配大量的字符,但是你试图写的内容的长度可能会超过Integer.MAX_VALUEchar[]的最大长度)和你会得到一个缓冲区溢出错误。

There's also the potential problem of escaping commas and quote characters in the values you are writing individually. 还有一个潜在的问题,就是在您单独编写的值中转义逗号和引号字符。 This is tricky to handle and I suggest you to use a CSV library to make sure you get the correct output. 这很难处理,我建议您使用CSV库来确保获得正确的输出。

Try uniVocity-parsers to persist your objects. 尝试使用uniVocity解析器来保存您的对象。 You can use a few annotations to serialize specific fields to CSV. 您可以使用一些注释将特定字段序列化为CSV。

Disclaimer: I'm the author of this library, it's open-source and free (Apache 2.0 license) 免责声明:我是该库的作者,它是开源的且免费的(Apache 2.0许可证)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM