diff --git a/CHANGELOG.md b/CHANGELOG.md index 03a556481..6ddda765f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * 【core 】 增加UniqueKeySet(issue#I4WUWR@Gitee) * 【core 】 阿拉伯数字转换成中文对发票票面金额转换的扩展(pr#570@Gitee) * 【core 】 ArrayUtil增加replace方法(pr#570@Gitee) +* 【core 】 CsvReadConfig增加自定义标题行行号(issue#2180@Github) * ### 🐞Bug修复 * 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvBaseReader.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvBaseReader.java index 84a244e37..2ac2f9186 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvBaseReader.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvBaseReader.java @@ -177,7 +177,7 @@ public class CsvBaseReader implements Serializable { final CsvParser csvParser = parse(reader); final List rows = new ArrayList<>(); read(csvParser, rows::add); - final List header = config.containsHeader ? csvParser.getHeader() : null; + final List header = config.headerLineNo > -1 ? csvParser.getHeader() : null; return new CsvData(header, rows); } diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java index 21d996039..690127f4f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java @@ -84,13 +84,13 @@ public final class CsvParser extends ComputeIter implements Closeable, S } /** - * 获取头部字段列表,如果containsHeader设置为false则抛出异常 + * 获取头部字段列表,如果headerLineNo < 0,抛出异常 * * @return 头部列表 * @throws IllegalStateException 如果不解析头部或者没有调用nextRow()方法 */ public List getHeader() { - if (false == config.containsHeader) { + if (config.headerLineNo < 0) { throw new IllegalStateException("No header available - header parsing is disabled"); } if (lineNo < config.beginLineNo) { @@ -152,7 +152,7 @@ public final class CsvParser extends ComputeIter implements Closeable, S } //初始化标题 - if (config.containsHeader && null == header) { + if (lineNo == config.headerLineNo && null == header) { initHeader(currentFields); // 作为标题行后,此行跳过,下一行做为第一行 continue; diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvReadConfig.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvReadConfig.java index f9373f8fc..5ad7c7d85 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvReadConfig.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvReadConfig.java @@ -11,8 +11,8 @@ import java.io.Serializable; public class CsvReadConfig extends CsvConfig implements Serializable { private static final long serialVersionUID = 5396453565371560052L; - /** 是否首行做为标题行,默认false */ - protected boolean containsHeader; + /** 指定标题行号,-1表示无标题行 */ + protected long headerLineNo = -1; /** 是否跳过空白行,默认true */ protected boolean skipEmptyRows = true; /** 每行字段个数不同时是否抛出异常,默认false */ @@ -34,13 +34,26 @@ public class CsvReadConfig extends CsvConfig implements Serializa } /** - * 设置是否首行做为标题行,默认false + * 设置是否首行做为标题行,默认false
+ * 当设置为{@code true}时,默认标题行号是{@link #beginLineNo},{@code false}为-1,表示无行号 * * @param containsHeader 是否首行做为标题行,默认false * @return this + * @see #setHeaderLineNo(long) */ public CsvReadConfig setContainsHeader(boolean containsHeader) { - this.containsHeader = containsHeader; + return setHeaderLineNo(containsHeader ? beginLineNo : -1); + } + + /** + * 设置标题行行号,默认-1,表示无标题行
+ * + * @param headerLineNo 标题行行号,-1表示无标题行 + * @return this + * @since 5.7.23 + */ + public CsvReadConfig setHeaderLineNo(long headerLineNo) { + this.headerLineNo = headerLineNo; return this; }