【发布时间】:2013-06-10 15:33:26
【问题描述】:
我正在使用以下代码从各种 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/neutral locale。
我也试过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-US 或Invariant 文化格式化的数据?
【问题讨论】: