J'utilise le code suivant pour lire les données de différents fichiers Excel:lecture des fichiers Excel d'une manière indépendante locale
// 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();
}
Comme vous le voyez, j'étais assez désespérée, en essayant de forcer Excel à utiliser en-US paramètres régionaux compatibles lors de l'importation de données. J'ai besoin de ceci parce que mon code pourrait être exécuté sur des serveurs avec divers paramètres régionaux, mais les données ont besoin d'un traitement supplémentaire qui suppose que les données entrantes sont des paramètres régionaux en-US/neutre. J'ai essayé aussi CultureInfo.InvariantCulture
au lieu de CultureInfo.CreateSpecificCulture("en-US")
.
Peu importe comment j'essaie, lorsque les paramètres régionaux du serveur est défini sur un autre lieu qui utilise .
comme séparateur de milliers et ,
comme séparateur décimal, je reçois des résultats erronés dans mon dt DataTable
.
Pour comparer le résultat pour une valeur monétaire - 200000,00 £ :
Lorsque les paramètres régionaux du serveur correspondent aux paramètres régionaux des États-Unis, je reçois "-£200,000.00"
Lorsque les paramètres régionaux du serveur correspondent aux paramètres régionaux letton, je reçois "-£200 000,00"
Je ne peux même pas post-traiter les données en utilisant les séparateurs numériques actuels de Thread.CurrentThread.CurrentCulture
, car OleDb semble l'ignorer complètement.
D'où OleDb tire-t-il sa culture actuelle? Dois-je dire au fournisseur OleDbConnection ou Microsoft.ACE.OLEDB.12.0 que j'ai besoin des données formatées selon la culture en-US
ou Invariant
?