@Carl V.Dango,@ Zsolt,@ Jon,
让我们重新开始。这是我的代码和错误(在底部)。您会在控制台输出中注意到原始数据的前两行。第一行中的第一字段(“ item”)在输出中为null。我认为应该是“ 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
最佳答案
这里的问题是CsvBeanReader
不会将空列转换为null
,而是转换为""
(空字符串)。因此,在编写CSV文件时,您只应该真正需要ConvertNullTo
处理器。
所以代替
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-beta-1的更新
最近发布的Super CSV 2.0.0-beta-1包含许多错误修复和新功能(包括Maven支持和用于映射嵌套属性和数组/集合的新Dozer扩展)。它还更改了对null和空字符串的处理。
新版本将
""
(空白列)读取为null
,这意味着您现在可以使用原始代码了:new ConvertNullTo("0", new ParseBigDecimal())
因此,
Optional()
单元处理器现在与null
而不是""
匹配,这意味着您还可以在写入时将其用作单元处理器(null
值现在将写为)。