gpt4 book ai didi

c# - 以独立于区域设置的方式读取 Excel 文件

转载 作者:行者123 更新时间:2023-12-03 00:29:47 24 4
gpt4 key购买 nike

我使用以下代码从各种 Excel 文件读取数据:

    // IMEX=1 - to force strings on mixed data
// HDR=NO - to process all the available data
// Locale 1033 is en-US. This was my first attempt to force en-US locale.
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Locale Identifier=1033;Extended Properties=\"{1};READONLY=TRUE;HDR=NO;IMEX=1;\"";

// source type according to the
// http://www.microsoft.com/en-us/download/details.aspx?id=13255

// try determining from extension
bool isOldFormat =
Path.GetExtension(sourceExcel).Equals(".xls", StringComparison.OrdinalIgnoreCase);

bool isBinary =
Path.GetExtension(sourceExcel).Equals(".xlsb", StringComparison.OrdinalIgnoreCase);

string sourceType = isOldFormat ? "Excel 8.0" : "Excel 12.0";

if (!isOldFormat)
sourceType += " Xml"; // for some reason the new binary xlsb files also need Xml

connectionString = string.Format(connectionString, sourceExcel, sourceType);

// this was my second attempt to force Excel to use US culture
var oldCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");

var dt = new DataTable();
try
{
using (var con = new OleDbConnection(connectionString))
{
con.Open();

// get all the available sheets
using (DataTable dataSet = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null))
{
// this was my third attempt to force Excel to use US culture
dataSet.Locale = CultureInfo.CreateSpecificCulture("en-US");
// get the sheet name in the file (will throw if out of range)
string workSheetName = dataSet.Rows[worksheetIndex]["TABLE_NAME"].ToString();//.Trim(new[] { '$' }).Replace("'", "");

string sql = String.Format("select * from [{0}]", workSheetName);

var da = new OleDbDataAdapter(sql, con);
// this was my fourth attempt to force Excel to use US culture
dt.Locale = CultureInfo.CreateSpecificCulture("en-US");
da.Fill(dt);
}

con.Close();
}

如您所见,我非常绝望,试图强制 Excel 在导入数据时使用 en-US 兼容区域设置。我需要这个,因为我的代码可能在具有各种区域设置的服务器上执行,但数据需要一些额外的处理,假设传入的数据是 en-US/中性区域设置。

我还尝试了 CultureInfo.InvariantCulture 而不是 CultureInfo.CreateSpecificCulture("en-US")

无论我如何尝试,当服务器区域设置设置为使用 . 作为千位分隔符和 , 作为小数分隔符的其他区域设置时,我会得到错误的结果我的dt DataTable

比较货币值的结果 - £200000.00:

当服务器区域设置对应于美国区域设置时,我得到“-£200,000.00”

当服务器区域设置对应于拉脱维亚语言环境时,我得到“-£200 000,00”

我什至无法使用 Thread.CurrentThread.CurrentCulture 中的当前数字分隔符对数据进行后处理,因为 OleDb 似乎完全忽略了它。

OleDb 从哪里获取当前文化?如何告诉 OleDbConnection 或 Microsoft.ACE.OLEDB.12.0 提供程序我需要根据 en-USInvariant 文化格式化的数据?

最佳答案

经过大量的试验和错误并阅读这篇过时的文章后 http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q320744我发现当前版本的 OLEDB 默认情况下似乎使用 HKEY_CURRENT_USER\Control Panel\International 中的区域性。不幸的是,我没有找到如何调用SetVarConversionLocaleSetting我的 C# 代码中的函数强制 OLEDB 使用当前线程区域性,因此我遵循以下原则 - 如果我无法为我的代码调整 OLEDB,那么我将调整我的代码以与 OLEDB 区域性兼容。完成后,我可以将所有数据转换为不变区域性。

但是有一个棘手的部分。您不能只从 HKEY_CURRENT_USER\Control Panel\International 中获取小数点分隔符,因为OLEDB忽略用户自定义的数字格式设置。 OLEDB 仅采用该区域性的默认预设值。所以我必须执行以下操作:

var oldCulture = Thread.CurrentThread.CurrentCulture;

using (RegistryKey international =
Registry.CurrentUser.OpenSubKey("Control Panel\\International", false))
{
string userDefaultCulture = international.GetValue("LocaleName").ToString();
// notice: although the user might have customized his decimal/thousand separators,
// still OLEDB ignores these customizations. That is why I create a culture with default settings.
cultureToNormalize = new CultureInfo(userDefaultCulture, false);
}

// force both OLEDB and current thread cultures to match for the next ToString() etc. conversions in my function
Thread.CurrentThread.CurrentCulture = cultureToNormalize;

string decSep = cultureToNormalize.NumberFormat.NumberDecimalSeparator;
string groupSep = cultureToNormalize.NumberFormat.NumberGroupSeparator;

现在我可以根据需要处理数据,而且我还可以安全地调用 ToString() - OLEDB 和 .NET 字符串化数字和货币的文化将匹配。而且,为了做一个好 child ,我在任期结束时恢复了以前的文化。

如果有人有更好的解决方案,我将非常感激。但现在我将保持原样 - 我所有的单元测试现在都是绿色的。

关于c# - 以独立于区域设置的方式读取 Excel 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17027552/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com