CSV 到 DataTable 将浮点值解析为日期
CSV to DataTable parsing float values as Date
我正在尝试将 CSV 解析为 VB.NET 项目中的数据表,问题是当我导入 CSV 文件时,值浮动的列如 ;2,08;2;0,82
导入为 30/12/1899 02:08:00
和 30/12/1899 02:00:00
如何防止 oledb 格式化数据?
这是我将 csv 加载到数据表的方式:
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & path & ";Extended Properties=""text;HDR=YES;FMT=Delimited(;)""")
con.Open()
Dim da As New OleDbDataAdapter(sqlquery, con)
da.Fill(dt)
在 CSV 所在的同一文件夹中,我有 schema.ini
,内容如下:
[anar_adm.csv]
Format=Delimited(;)
Schema.ini 文件有不同的选项,您可以在这里阅读。
Schema.ini File (Text File Driver)
您可以指定列数据类型以及小数点分隔符等。例如,定义 4 列的架构,其中:
ColNameHeader=True
:数据文件包含列定义
Format=Delimited(;)
: 列之间用分号分隔
DecimalSymbol=,
:小数点分隔符为逗号
Col(N)=ColumnName TYPE [WIDTH] [#]
:列的名称和类型以及列的宽度(可选)。宽度值 ([#]
) 是必需的。
如果列可能包含不是系统默认值的货币符号,请指定货币格式。例如,使用欧元 €
符号:
CurrencySymbol=[Symbol]
:数据文件中使用的货币符号。
CurrencyPosFormat=[N]
:正值的符号位置。这可以是以下 4 个值之一:
0 = €1,1 1 = 1,1€ 2 = € 1,1 3 = 1,1 €
CurrencyNegFormat=[N]
:同上,但可以指定更多的位置。有关可能值的列表,请参阅先前链接的文档
CurrencyDigits=[N]
:货币的小数位数
CurrencyThousandSymbol=[Symbol]
: 千位分隔符号
CurrencyDecimalSymbol=[Symbol]
:小数点分隔符号
CharacterSet 指定 CSV 文件使用的编码方式。标准值为:
ANSI
(本地代码页),OEM
,Unicode
。必须使用其代码页指定其他编码。例如UTF-8需要指定为CodePage65001
.
系统中所有可用的代码页都列在此注册表项中:
HKEY_CLASSES_ROOT\MIME\Database\Charset
使用此 CSV 内容:
ID;Description;Quantity;FloatValue;Price
1;String 1;100;10,56;€10,79
2;String 2;101;12,72;€200,34
3;String 3;33;100657,72;€0,98
一个Schema.ini文件可以如下:
[filename.csv]
ColNameHeader=True First row is the Columns Header
MaxScanRows=0 No auto-detect Column Type
CharacterSet=65001 UTF-8 file Format
Format=Delimited(;) Columns delimiter
DecimalSymbol=, Decimals separator
NumberLeadingZeros=1 Below 1 values leading zeros (0,12)
CurrencySymbol=€ Currency symbol (if present)
CurrencyPosFormat=0 Currency positive format: €1,1
CurrencyNegFormat=1 Currency negative format: -€1,1
CurrencyDigits=2 Number of Decimal digits
CurrencyThousandSymbol=. Thousands separator
CurrencyDecimalSymbol=, Decimal separator
Col1=ID Long |-- Columns definition
Col2=Description Text WIDTH 50 |
Col3=Quantity Integer |
Col4=FloatValue Double |
Col5=Price Currency |
[otherFilename.csv]
ColNameHeader=True
MaxScanRows=25 | Auto-detect the data type, using 25 rows as sample
CharacterSet=ANSI
Format=Delimited() | Standard delimiter: (,)
无论如何,我建议得到一个图书馆 CsvHelper
我维护了一个可以处理这种情况的库:Sylvan.Data.Csv
这是我编写的代码,用于验证它是否按预期工作。抱歉,这是在 C# 中,因为我不太了解 VB,应该很容易翻译。
using var reader = new StringReader("Name;Value1;Value2\nTest;2,08;0,82\n");
var schema = Schema.Parse("Name,Value1:float,Value2:float");
var options = new CsvDataReaderOptions {
Schema = new CsvSchema(schema),
// you would likely replace this with CurrentCulture
// the default is InvariantCulture
Culture = CultureInfo.GetCultureInfoByIetfLanguageTag("it-IT")
};
var csv = CsvDataReader.Create(reader, options);
var dt = new DataTable();
dt.Load(csv);
CsvDataReader
来自 Sylvan.Data.Csv
而 Schema.Parse
行来自 Sylvan.Data
,这是预发布的。您不必使用 Schema.Parse
,而是可以提供您自己的 ICsvSchemaProvider
。 Answer.
中有一个简单模式提供程序的示例
与 OleDB 相比,它的优势在于它是完全托管的,不需要外部驱动程序,也不需要 schema.ini。它也是 much, much faster,如果性能是一个问题(事实上,它是 .NET 最快的)。缺点是您需要自己提供架构,而 OleDB 会尝试自动从数据中检测它(有时会出错)。
我正在尝试将 CSV 解析为 VB.NET 项目中的数据表,问题是当我导入 CSV 文件时,值浮动的列如 ;2,08;2;0,82
导入为 30/12/1899 02:08:00
和 30/12/1899 02:00:00
如何防止 oledb 格式化数据?
这是我将 csv 加载到数据表的方式:
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & path & ";Extended Properties=""text;HDR=YES;FMT=Delimited(;)""")
con.Open()
Dim da As New OleDbDataAdapter(sqlquery, con)
da.Fill(dt)
在 CSV 所在的同一文件夹中,我有 schema.ini
,内容如下:
[anar_adm.csv]
Format=Delimited(;)
Schema.ini 文件有不同的选项,您可以在这里阅读。
Schema.ini File (Text File Driver)
您可以指定列数据类型以及小数点分隔符等。例如,定义 4 列的架构,其中:
ColNameHeader=True
:数据文件包含列定义Format=Delimited(;)
: 列之间用分号分隔DecimalSymbol=,
:小数点分隔符为逗号Col(N)=ColumnName TYPE [WIDTH] [#]
:列的名称和类型以及列的宽度(可选)。宽度值 ([#]
) 是必需的。
如果列可能包含不是系统默认值的货币符号,请指定货币格式。例如,使用欧元 €
符号:
CurrencySymbol=[Symbol]
:数据文件中使用的货币符号。CurrencyPosFormat=[N]
:正值的符号位置。这可以是以下 4 个值之一:
0 = €1,1 1 = 1,1€ 2 = € 1,1 3 = 1,1 €
CurrencyNegFormat=[N]
:同上,但可以指定更多的位置。有关可能值的列表,请参阅先前链接的文档CurrencyDigits=[N]
:货币的小数位数CurrencyThousandSymbol=[Symbol]
: 千位分隔符号CurrencyDecimalSymbol=[Symbol]
:小数点分隔符号
CharacterSet 指定 CSV 文件使用的编码方式。标准值为:
ANSI
(本地代码页),OEM
,Unicode
。必须使用其代码页指定其他编码。例如UTF-8需要指定为CodePage65001
.
系统中所有可用的代码页都列在此注册表项中:
HKEY_CLASSES_ROOT\MIME\Database\Charset
使用此 CSV 内容:
ID;Description;Quantity;FloatValue;Price
1;String 1;100;10,56;€10,79
2;String 2;101;12,72;€200,34
3;String 3;33;100657,72;€0,98
一个Schema.ini文件可以如下:
[filename.csv]
ColNameHeader=True First row is the Columns Header
MaxScanRows=0 No auto-detect Column Type
CharacterSet=65001 UTF-8 file Format
Format=Delimited(;) Columns delimiter
DecimalSymbol=, Decimals separator
NumberLeadingZeros=1 Below 1 values leading zeros (0,12)
CurrencySymbol=€ Currency symbol (if present)
CurrencyPosFormat=0 Currency positive format: €1,1
CurrencyNegFormat=1 Currency negative format: -€1,1
CurrencyDigits=2 Number of Decimal digits
CurrencyThousandSymbol=. Thousands separator
CurrencyDecimalSymbol=, Decimal separator
Col1=ID Long |-- Columns definition
Col2=Description Text WIDTH 50 |
Col3=Quantity Integer |
Col4=FloatValue Double |
Col5=Price Currency |
[otherFilename.csv]
ColNameHeader=True
MaxScanRows=25 | Auto-detect the data type, using 25 rows as sample
CharacterSet=ANSI
Format=Delimited() | Standard delimiter: (,)
无论如何,我建议得到一个图书馆 CsvHelper
我维护了一个可以处理这种情况的库:Sylvan.Data.Csv
这是我编写的代码,用于验证它是否按预期工作。抱歉,这是在 C# 中,因为我不太了解 VB,应该很容易翻译。
using var reader = new StringReader("Name;Value1;Value2\nTest;2,08;0,82\n");
var schema = Schema.Parse("Name,Value1:float,Value2:float");
var options = new CsvDataReaderOptions {
Schema = new CsvSchema(schema),
// you would likely replace this with CurrentCulture
// the default is InvariantCulture
Culture = CultureInfo.GetCultureInfoByIetfLanguageTag("it-IT")
};
var csv = CsvDataReader.Create(reader, options);
var dt = new DataTable();
dt.Load(csv);
CsvDataReader
来自 Sylvan.Data.Csv
而 Schema.Parse
行来自 Sylvan.Data
,这是预发布的。您不必使用 Schema.Parse
,而是可以提供您自己的 ICsvSchemaProvider
。 Answer.
与 OleDB 相比,它的优势在于它是完全托管的,不需要外部驱动程序,也不需要 schema.ini。它也是 much, much faster,如果性能是一个问题(事实上,它是 .NET 最快的)。缺点是您需要自己提供架构,而 OleDB 会尝试自动从数据中检测它(有时会出错)。