如何使用C#和ADO.NET从Excel中读取小数和日期



我正在尝试使用以下代码(ADO.NET(读取ASP.NET应用程序中的Excel文件:

// Create OleDbCommand object and select data from worksheet Sheet1    
String query = String.Format("Select * From [{0}$]", sheetName);
OleDbCommand cmd = new OleDbCommand(query, oledbConn);
// Create new OleDbDataAdapter
OleDbDataAdapter oleda = new OleDbDataAdapter();
oleda.SelectCommand = cmd;
//Fills Data to DataTable
oleda.Fill(dt);

问题是数据表中的值表示为

1(对于带逗号(3,14(或带点(3.14(的小数,

2(对于格式为"DD/MM/YYYY"或"MM/DD/YYYY"的日期

对于相同的Excel文件,取决于服务器的区域设置。

有没有任何方法可以读取特定区域设置中的数据,以便从Excel文件中获得正确的值?

如果列中包含小数,请使用以下内容进行解析:(Decimal.Parse(

string decimal1 = "3,14";
string decimal2 = "3.14";
decimal d1 = decimal.Parse(decimal1, new NumberFormatInfo { NumberDecimalSeparator = "," });
decimal d2 = decimal.Parse(decimal2);

请注意,对于,,您需要使用自定义NumberFormatInfo才能正确解析。

然后对于您的DateTime列:

string date1 = "14/03/2018";
string date2 = "03/14/2018";
DateTime dt1 = DateTime.ParseExact(date1, "dd/MM/yyyy", CultureInfo.InvariantCulture);
DateTime dt2 = DateTime.ParseExact(date2, "MM/dd/yyyy", CultureInfo.InvariantCulture);

在这里,您需要为日期指定不同的格式。


编辑:

为了更全面地解析未知的DateTime格式,您可以尝试迭代CultureInfo或多个CultureInfo的所有格式(如果您知道可能不止一个(。下面是一个如何做到这一点的例子:

string dateTimeString = @"03/14/2018";
string[] possibleStandardFormats = new CultureInfo("en-US")
.DateTimeFormat.GetAllDateTimePatterns();
DateTime? result = null;
foreach (string format in possibleStandardFormats) {
if (DateTime.TryParse(dateTimeString, out DateTime dateTime)) {
// this format could work
result = dateTime;
break;
}
}
if (result == null) {
// no luck with any format
// try one last parse
if (DateTime.TryParse(dateTimeString, out DateTime dateTime)) {
// finally worked
result = dateTime;
}
else {
// no luck
}
}

在这里,首先尝试通用DateTime.TryParse可能更有效(如本例末尾所示(,因为它可以通过其他格式节省迭代。这取决于您想要如何处理,但本示例应该处理大多数情况。

编辑2:

为了获得标准的DateTime格式,您可以使用CurrentCulture,这将有助于您的日期。在我之前的编辑中,我对new CultureInfo("en-US")进行了硬编码,但下面的内容有点笼统。

string[] possibleStandardFormats = new CultureInfo(CultureInfo.CurrentCulture.Name)
.DateTimeFormat.GetAllDateTimePatterns();

第3版:要进一步阐述以前对小数的解析,请首先检查字符串是否有逗号,然后根据上面列出的方法进行解析。

string decimal1 = "3,14";
if (decimal1.Contains(",")) {
decimal d1 = decimal.Parse(decimal1, new NumberFormatInfo { NumberDecimalSeparator = "," });
}
else {
decimal d1 = decimal.Parse(decimal1);
}

第4版:

要将区域性纳入小数解析中,可以尝试Convert.ToDecimal方法。其中一个参数采用CultureInfo,您可以将其作为CultureInfo.CurrentCulture传入当前区域性。例如,我使用de-de(德语(,因为这是1.234,14的有效区域性

string decimal1 = "1.234,14";
string decimal2 = "1,234.14";
decimal d1 = Convert.ToDecimal(decimal1, new CultureInfo("de-de"));
decimal d2 = Convert.ToDecimal(decimal2, CultureInfo.CurrentCulture);

最新更新