Skip to content

[Feature] add support for a custom CSVFormat #353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 23, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
import cn.idev.excel.read.listener.ModelBuildEventListener;
import cn.idev.excel.read.metadata.ReadWorkbook;
import cn.idev.excel.support.ExcelTypeEnum;
import org.apache.commons.csv.CSVFormat;

import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.List;

import javax.xml.parsers.SAXParserFactory;
import java.io.File;
Expand Down Expand Up @@ -263,6 +271,19 @@ public ExcelReaderSheetBuilder sheet(Integer sheetNo, String sheetName) {
return excelReaderSheetBuilder;
}

/**
* Sets the CSVFormat for reading CSV files.
* This method also ensures that the Excel type is set to CSV.
*
* @param csvFormat The CSVFormat instance
* @return his ExcelReaderBuilder instance for method chaining
*/
public ExcelReaderBuilder csvFormat(CSVFormat csvFormat) {
excelType(ExcelTypeEnum.CSV);
readWorkbook.setCsvFormat(csvFormat);
return this;
}

@Override
protected ReadWorkbook parameter() {
return readWorkbook;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.csv.CSVFormat;

import javax.xml.parsers.SAXParserFactory;
import java.io.File;
Expand Down Expand Up @@ -123,4 +124,10 @@ public class ReadWorkbook extends ReadBasicParameter {
* Ignore hidden sheet.
*/
private Boolean ignoreHiddenSheet;

/**
* Specifies CSVFormat for parsing.
* Only work on the CSV file.
*/
private CSVFormat csvFormat;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public class CsvReadWorkbookHolder extends ReadWorkbookHolder {
public CsvReadWorkbookHolder(ReadWorkbook readWorkbook) {
super(readWorkbook);
setExcelType(ExcelTypeEnum.CSV);
this.csvFormat = CSVFormat.DEFAULT;
if (readWorkbook.getCsvFormat() == null) {
this.csvFormat = CSVFormat.DEFAULT;
} else {
this.csvFormat = readWorkbook.getCsvFormat();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cn.idev.excel.test.temp.csv;

import cn.idev.excel.ExcelReader;
import cn.idev.excel.FastExcel;
import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder;
import cn.idev.excel.read.metadata.holder.csv.CsvReadWorkbookHolder;
import cn.idev.excel.test.util.TestFileUtil;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.QuoteMode;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.util.List;

public class CsvFormatTest {

private static File csvSimpleFile;
private static File csvSimpleDelimiterFile;
private static File csvSimpleQuoteFile;

@BeforeAll
public static void init() {
csvSimpleFile = TestFileUtil.readFile("csv" + File.separator + "simple.csv");
csvSimpleDelimiterFile = TestFileUtil.readFile("csv" + File.separator + "simple-delimiter.csv");
csvSimpleQuoteFile = TestFileUtil.readFile("csv" + File.separator + "simple-quote.csv");
}

@Test
public void testReadSimple() {
List<CsvData> dataList = FastExcel.read(csvSimpleFile, CsvData.class, new CsvDataListener())
.csvFormat(null)
.doReadAllSync();
Assertions.assertEquals(10, dataList.size());
}

@Test
public void testReadDelimiter() {
char delimiter = '#';
// setting the CsvFormat of ExcelReader
try (ExcelReader excelReader = FastExcel.read(csvSimpleDelimiterFile, CsvData.class, new CsvDataListener()).build()) {
ReadWorkbookHolder readWorkbookHolder = excelReader.analysisContext().readWorkbookHolder();
if (readWorkbookHolder instanceof CsvReadWorkbookHolder) {
CsvReadWorkbookHolder csvReadWorkbookHolder = (CsvReadWorkbookHolder) readWorkbookHolder;
csvReadWorkbookHolder.setCsvFormat(CSVFormat.DEFAULT.builder().setDelimiter(delimiter).build());
}
excelReader.readAll();
}

// use parameter
List<CsvData> dataList = FastExcel.read(csvSimpleDelimiterFile, CsvData.class, new CsvDataListener())
.csvFormat(CSVFormat.DEFAULT.builder().setDelimiter(delimiter).build())
.doReadAllSync();
Assertions.assertEquals(10, dataList.size());
}

@Test
public void testReadQuote() {
List<CsvData> dataList = FastExcel.read(csvSimpleQuoteFile, CsvData.class, new CsvDataListener())
.csvFormat(CSVFormat.DEFAULT.builder().setQuoteMode(QuoteMode.MINIMAL).build())
.doReadAllSync();
Assertions.assertEquals(10, dataList.size());
}
}
11 changes: 11 additions & 0 deletions fastexcel-test/src/test/resources/csv/simple-delimiter.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
字符串标题#日期标题#数字标题
String0#2020-01-01 01:01:00#1
String1#2020-01-02 01:01:00#2
String2#2020-01-03 01:01:00#3
String3#2020-01-04 01:01:00#4
String4#2020-01-05 01:01:00#5
String5#2020-01-06 01:01:00#6
String6#2020-01-07 01:01:00#7
String7#2020-01-08 01:01:00#8
String8#2020-01-09 01:01:00#9
String9#2020-01-10 01:01:00#10
11 changes: 11 additions & 0 deletions fastexcel-test/src/test/resources/csv/simple-quote.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"字符串标题","日期标题","数字标题"
"String0","2020-01-01 01:01:00",1
"String1","2020-01-02 01:01:00",2
"String2""quote""","2020-01-03 01:01:00",3
"String3,,","2020-01-04 01:01:00",4
"String4","2020-01-05 01:01:00",5
"String5","2020-01-06 01:01:00",6
"String6","2020-01-07 01:01:00",7
"String7","2020-01-08 01:01:00",8
"String8","2020-01-09 01:01:00",9
"String9","2020-01-10 01:01:00",10
11 changes: 11 additions & 0 deletions fastexcel-test/src/test/resources/csv/simple.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
字符串标题,日期标题,数字标题
String0,2020-01-01 01:01:00,1
String1,2020-01-02 01:01:00,2
String2,2020-01-03 01:01:00,3
String3,2020-01-04 01:01:00,4
String4,2020-01-05 01:01:00,5
String5,2020-01-06 01:01:00,6
String6,2020-01-07 01:01:00,7
String7,2020-01-08 01:01:00,8
String8,2020-01-09 01:01:00,9
String9,2020-01-10 01:01:00,10