如何使用jackson-dataformat-csv正确解析CSV中带换行的双引号字段
解决方案
核心问题是Jackson CSV默认的CsvSchema未开启多行值支持,解析器遇到引号内的换行会误判为行结束,把单个多行字段拆成多条记录,才会触发列缺失报错、跳行的问题。按如下方式配置即可正确解析:
- 保留原有CsvMapper的基础配置,不需要额外添加
Feature.FAIL_ON_MISSING_COLUMNS配置。该配置仅做严格列数校验,和多行解析能力无关,你之前碰到的跳行本质是解析逻辑错误导致行拆分异常,和这个配置本身没有关系。 - 构建CsvSchema时显式开启多行值支持,指定双引号为字段包裹符,完全匹配你当前的CSV格式规则。
完整配置代码
@Bean public CsvMapper csvMapper() { CsvMapper csvMapper = new CsvMapper(); csvMapper.registerModule(new JavaTimeModule()); csvMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); return csvMapper; } @Bean public CsvSchema csvSchema() { // 如果不需要手动指定列顺序,想自动根据表头映射字段,可直接用空Schema配置 // return CsvSchema.emptySchema() // .withQuoteChar('"') // .withAllowMultiLineValues(true) // .withUseHeader(true); return CsvSchema.builder() .setUseHeader(true) // 识别第一行作为表头映射实体字段 .setQuoteChar('"') // 匹配规则:双引号作为特殊内容字段的包裹符 .setAllowMultiLineValues(true) // 核心配置:允许引号包裹的字段值包含换行、跨多行 .addColumn("id") .addColumn("name") .addColumn("description") .addColumn("age") .build(); }
读取调用示例
解析CSV时传入提前配置好的Schema即可:
// 将YourEntity替换为你自己的业务实体类,csvInputStream替换为实际的CSV输入流 MappingIterator<YourEntity> iterator = csvMapper .readerFor(YourEntity.class) .with(csvSchema) .readValues(csvInputStream); List<YourEntity> resultList = iterator.readAll();
效果说明
- 配置完全适配你描述的CSV规则:单行无特殊字符的字段不需要加双引号,仅多行内容用双引号包裹时,解析器会持续读取直到碰到闭合的双引号,中间的换行符会完整保留在字段值中,不会误判为CSV行结束
- 解析你提供的示例CSV时,
description字段会完整获取到Self-made\nChef\nShoemaker的内容,不会出现内容拆分、行丢失、字段错位的问题
内容的提问来源于stack exchange,提问作者Shubham A.
相关产品推荐
相关产品推荐

