代码之家  ›  专栏  ›  技术社区  ›  Vihung

你能推荐一个Java库来读取(并且可能写)CSV文件吗?[关闭]

  •  46
  • Vihung  · 技术社区  · 17 年前

    您能推荐一个Java库,用于读取、解析、验证和映射逗号分隔值(CSV)文件到Java值对象(JavaBeans)中的行吗?

    8 回复  |  直到 13 年前
        1
  •  36
  •   Community Mohan Dere    8 年前

    我们已经用过 http://opencsv.sourceforge.net/ 取得了很好的成功

    我还遇到了另一个链接很好的问题: Java lib or app to convert CSV to XML file?

        2
  •  23
  •   James Bassett    13 年前

    Super CSV 对于读取/解析、验证和将csv文件映射到pojos是一个很好的选择!

    我们(超级CSV团队)刚刚发布了一个新版本(您可以 download 它来自sourceforge或maven)。

    读取csv文件

    以下示例使用 CsvDozerBeanReader (我们刚刚发布的一个新读者使用 Dozer 对于具有深度映射和基于索引的映射支持的bean映射),它基于 website . 如果您不需要推土机功能(或者您只需要一个简单的独立依赖项),那么您可以使用 CsvBeanReader 相反(看这个 code example )

    示例csv文件

    下面是一个表示对调查的响应的示例csv文件。它有一个标题和3行数据,都有8列。

    age,consentGiven,questionNo1,answer1,questionNo2,answer2,questionNo3,answer3
    18,Y,1,Twelve,2,Albert Einstein,3,Big Bang Theory
    ,Y,1,Thirteen,2,Nikola Tesla,3,Stargate
    42,N,1,,2,Carl Sagan,3,Star Wars
    

    定义从csv到pojo的映射

    每行csv都将被读取到 SurveyResponse 类,每个类都有一个列表 Answer s.为了使映射工作,您的类应该是有效的JavaBeans(即具有默认的无参数构造函数,并且为每个字段定义了getter/setter)。

    在super csv中,您使用一个简单的字符串数组定义映射-数组的每个元素对应于csv文件中的一列。

    CsvDozerBeanMapper 你可以使用:

    • 简单字段映射(例如 firstName )

    • 深度映射(例如 address.country.code )

    • 索引映射(例如 middleNames[1] -数组或集合的零基索引)

    • 深度+索引映射(例如 person.middleNames[1] )

    以下是此示例的字段映射-它使用以下组合:

    private static final String[] FIELD_MAPPING = new String[] { 
            "age",                   // simple field mapping (like for CsvBeanReader)
            "consentGiven",          // as above
            "answers[0].questionNo", // indexed (first element) + deep mapping
            "answers[0].answer", 
            "answers[1].questionNo", // indexed (second element) + deep mapping
            "answers[1].answer", 
            "answers[2].questionNo", 
            "answers[2].answer" };
    

    转换和验证

    超级csv有一个有用的库 cell processors ,可用于将字符串从csv文件转换为其他数据类型(例如日期、整数),或进行约束验证(例如强制/可选、regex匹配、范围检查)。

    使用蜂窝处理器是 完全可选 -没有它们,csv的每一列都将是一个字符串,因此每个字段也必须是一个字符串。

    下面是示例中的单元处理器配置。与字段映射一样,数组中的每个元素表示一个csv列。它演示了单元处理器如何将csv数据转换为字段的数据类型,以及如何将它们链接在一起。

    final CellProcessor[] processors = new CellProcessor[] { 
        new Optional(new ParseInt()), // age
        new ParseBool(),              // consent
        new ParseInt(),               // questionNo 1
        new Optional(),               // answer 1
        new ParseInt(),               // questionNo 2
        new Optional(),               // answer 2
        new ParseInt(),               // questionNo 3
        new Optional()                // answer 3
    };
    

    阅读

    用super csv阅读是非常灵活的:你自己提供 Reader (这样您就可以从文件、类路径、zip文件等读取数据),分隔符和引号字符可以通过 preferences (其中有许多预先定义的配置可满足大多数用途)。

    下面的代码非常简单。

    1. 创建读卡器(使用 读者 和首选项)

    2. (可选)读取标题

    3. 配置bean映射

    4. 继续呼叫 read() 直到你得到 null (文件末尾)

    5. 关闭读卡器

    代码:

    ICsvDozerBeanReader beanReader = null;
    try {
        beanReader = new CsvDozerBeanReader(new FileReader(CSV_FILENAME),
            CsvPreference.STANDARD_PREFERENCE);
    
        beanReader.getHeader(true); // ignore the header
        beanReader.configureBeanMapping(SurveyResponse.class, FIELD_MAPPING);
    
        SurveyResponse surveyResponse;
        while( (surveyResponse = 
            beanReader.read(SurveyResponse.class, processors)) != null ) {
            System.out.println(
                String.format("lineNo=%s, rowNo=%s, surveyResponse=%s",
                    beanReader.getLineNumber(), beanReader.getRowNumber(), 
                    surveyResponse));
        }
    
    } finally {
        if( beanReader != null ) {
            beanReader.close();
        }
    }
    

    输出:

    lineNo=2, rowNo=2, surveyResponse=SurveyResponse [age=18, consentGiven=true, answers=[Answer [questionNo=1, answer=Twelve], Answer [questionNo=2, answer=Albert Einstein], Answer [questionNo=3, answer=Big Bang Theory]]]
    lineNo=3, rowNo=3, surveyResponse=SurveyResponse [age=null, consentGiven=true, answers=[Answer [questionNo=1, answer=Thirteen], Answer [questionNo=2, answer=Nikola Tesla], Answer [questionNo=3, answer=Stargate]]]
    lineNo=4, rowNo=4, surveyResponse=SurveyResponse [age=42, consentGiven=false, answers=[Answer [questionNo=1, answer=null], Answer [questionNo=2, answer=Carl Sagan], Answer [questionNo=3, answer=Star Wars]]]
    

    更多信息

    您可以在 website !

        3
  •  7
  •   Domchi    17 年前

    我可以推荐 SuperCSV . 使用简单,做了我需要的一切。

        4
  •  4
  •   kolrie    17 年前

    嘿,我有一个开源项目: JFileHelpers . 我认为它的主要优点是它使用Java注释,看一下:

    如果你有这个豆子:

    @FixedLengthRecord()
    public class Customer {
        @FieldFixedLength(4)
        public Integer custId;
    
        @FieldAlign(alignMode=AlignMode.Right)
        @FieldFixedLength(20)
        public String name;
    
        @FieldFixedLength(3)
        public Integer rating;
    
        @FieldTrim(trimMode=TrimMode.Right)
        @FieldFixedLength(10)
        @FieldConverter(converter = ConverterKind.Date, 
        format = "dd-MM-yyyy")
        public Date addedDate;
    
        @FieldFixedLength(3)
        @FieldOptional
        public String stockSimbol;    
    }
    

    并希望分析此文件:

    ....|....1....|....2....|....3....|....4                
    1   Antonio Pereira     10012-12-1978ABC
    2   Felipe Coury          201-01-2007
    3   Anderson Polga       4212-11-2007DEF      
    

    你所要做的就是:

    FileHelperEngine<Customer> engine = 
        new FileHelperEngine<Customer>(Customer.class); 
    List<Customer> customers = 
        new ArrayList<Customer>();
    
    customers = engine.readResource(
        "/samples/customers-fixed.txt");
    

    此外,它还支持主细节、日期和格式转换等。告诉我你的想法!

    最好的问候!

        5
  •  3
  •   community wiki ddimitrov    17 年前

    我发现 Flatpack 非常擅长处理奇怪的csv文件(转义、引号、坏记录等)

        6
  •  2
  •   Vihung    17 年前

    前面问的csv文件到xml问题似乎回答了我所有的问题。

    OpenCSV http://opencsv.sourceforge.net/ )还可以使用列位置映射策略绑定到JavaBeans

      ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy();
      strat.setType(YourOrderBean.class);
      String[] columns = new String[] {"name", "orderNumber", "id"}; // the fields to bind do in your JavaBean
      strat.setColumnMapping(columns);
    
      CsvToBean csv = new CsvToBean();
      List list = csv.parse(strat, yourReader);
    

    JSEFA http://jsefa.sourceforge.net 似乎除了支持FLR和XML之外,我还需要做所有我需要的事情——特别是绑定到Java对象。

        7
  •  0
  •   Brendan Long    14 年前

    我已经成功地从爪哇解析和编写CSV文件了。 OpenCSV . 如果您想用Java读取或编写Excel兼容的电子表格,则 POI 阿帕奇的图书馆是通往未来的道路。

        8
  •  0
  •   Paul Croarkin    14 年前