CSV 到 DataTable 将浮点值解析为日期

问题描述

我试图在 VB.NET 项目中将 CSV 解析为 DataTable,问题是当我导入 CSV 文件时,值像 ;2,08;2;0,82 这样浮动的列被导入为 { {1}} 和 30/12/1899 02:08:00

如何防止 oledb 格式化数据?

这是我如何将 csv 加载到数据表:

30/12/1899 02:00:00

在 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) 包含以下内容

schema.ini

解决方法

我维护一个可以处理这种情况的库: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.CsvSchema.Parse 行来自 Sylvan.Data,这是预发布的。您不必使用 Schema.Parse,而是可以提供自己的 ICsvSchemaProvider。此 Answer 中有一个简单架构提供程序的示例。

与 OleDB 相比,它的优势在于它是完全托管的,不需要外部驱动程序,也不需要 schema.ini。它也是 much,much faster,如果性能是一个问题(实际上,它是 .NET 最快的)。缺点是您需要自己提供架构,而 OleDB 会尝试从数据中自动检测它(有时会出错)。

,

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]:十进制分隔符

字符集指定 CSV 文件使用的编码。标准值为:

  • ANSI(本地代码页)、OEMUnicode。其他编码必须使用它们的 CodePage 指定。例如,需要将 UTF-8 指定为 CodePage 65001
    系统中所有可用的代码页都列在此注册表项中:
    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