Какой клеточный процессор использовать в строках при использовании SuperCSV CSVBeanReader
@Carl V. Dango,@Zsolt, @Jon, давай начнем сначала. Вот мой код и ошибка (внизу). В консоли вы увидите первые две строки необработанных данных. Первое поле в первой строке ("элемент") является нулевым в выходных данных. Я подумал, что это должно быть 'xx', потому что у меня есть столбец StrReplace(" ","xx"). Больше всего меня беспокоит то, как перехватить ноль / пробел в столбце 4 третьей записи. Это кажется настолько основополагающим, что я немного встревожен, что это такая большая проблема, чтобы решить.
package com.mycompany.data.transfers.app;
import java.io.FileReader;
import org.supercsv.cellprocessor.ConvertNullTo;
import org.supercsv.cellprocessor.ParseBigDecimal;
import org.supercsv.cellprocessor.ParseDate;
import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.prefs.CsvPreference;
import com.mycompany.data.transfers.models.Invoice;
public class Test {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
char quote = '"';
int delimeter = 124;
String newLine = "\n";
CellProcessor[] cp = new CellProcessor[] {
new StrReplace(" ", "xx"),
null,
new ParseDate("yyyyMMdd"),
new ParseBigDecimal(),
new ConvertNullTo("0", new ParseBigDecimal()),
new ParseDate("yyyyMMdd"),
null,
new ParseDate("yyyyMMdd"),
null,
null,
null,
null,
null,
new ParseInt()
};
Invoice bean = new Invoice();
CsvBeanReader inFile = new CsvBeanReader(new FileReader("c:\\temp\\my_test_file.txt"), new CsvPreference(quote, delimeter, newLine));
while ((bean = inFile.read(bean.getClass(), new String[] {"item", "loc", "schedDate", "fracQty", "recQty",
"expDate", "poNum", "dateShip", "masterLoadId", "loadId",
"confirmationNumber", "sourceWarehouse", "purchasingGroup",
"poDistFlag" }, cp)) != null) {
System.out.println(bean);
}
}
}
Invoice [item=, loc=NEW, schedDate=Wed Nov 02 00:00:00 CDT 2011, fracQty=5, recQty=4]
Invoice [item=0006268410, loc=SHR, schedDate=Thu Nov 03 00:00:00 CDT 2011, fracQty=12, recQty=5]
Exception in thread "main" null
Parser error context: Line: 3 Column: 4 Raw line:
[0000939515, NEW, 20111102, 50, , 20111102, , 20111102, 0000000000, 0000000000, , , BBA, 1]
offending processor: org.supercsv.cellprocessor.ParseBigDecimal@17a8913
at org.supercsv.cellprocessor.ParseBigDecimal.execute(Unknown Source)
at org.supercsv.cellprocessor.ConvertNullTo.execute(Unknown Source)
at org.supercsv.util.Util.processStringList(Unknown Source)
at org.supercsv.io.CsvBeanReader.read(Unknown Source)
at com.mycompany.data.transfers.app.Test.main(Test.java:48)
Caused by: java.lang.NumberFormatException
at java.math.BigDecimal.<init>(BigDecimal.java:534)
at java.math.BigDecimal.<init>(BigDecimal.java:728)
... 5 more
1 ответ
Эта проблема здесь заключается в том, что CsvBeanReader
не преобразует пустой столбец в null
, но ""
(пустой строки). Поэтому вам действительно нужно только ConvertNullTo
процессор при записи файлов CSV.
Так что вместо
new ConvertNullTo("0", new ParseBigDecimal())
ты должен использовать
new Token("", "0", new ParseBigDecimal()) // replace "" with "0"
Это предполагает, что вы хотите BigDecimal со значением ноль для пустых столбцов - если вы хотите, чтобы это было null
вместо этого используйте
new Optional(new ParseBigDecimal)
Я признаю, что сайт и javadoc должны сделать это более явным, и над этим я работаю над предстоящим выпуском Super CSV.
Изменить: Обновление для Super CSV 2.0.0-бета-1
Недавно выпущенный Super CSV 2.0.0-beta-1 включает в себя множество исправлений ошибок и новые функции (включая поддержку Maven и новое расширение Dozer для отображения вложенных свойств и массивов / коллекций). Также изменилась обработка нулей и пустой строки.
Новая версия гласит ""
(пустой столбец) как null
, что означает, что теперь вы можете использовать свой оригинальный код:
new ConvertNullTo("0", new ParseBigDecimal())
В результате этого Optional()
клеточный процессор теперь совпадает с null
вместо ""
, что означает, что вы также можете использовать его в качестве процессора ячейки при записи (null
значение теперь будет записано как ""
).