Excel数字格式问题与国际设置

我正在尝试使用c#3.5写入Excel 2003电子表格。 但是,我无法在不同的国家/地区设置正确的function。 国家设置是英文或德文。 这两个设置有不同的小数和千位设置。 除非用户在“选项”屏幕的“国际”设置中更改了小数点和千位分隔符,否则一切正常。 任何人都可以帮助,因为我觉得我不能再看到树的木材,并失去了明显的东西。

概要:

从访问数据库中检索数据。 通过c#应用程序读取并写入Excel电子表格。

Excel版本2003机器可以是英文或德文。 Excel中的“国际设置”选项中可能会更改十进制和千位分隔符 – 这是发生问题的地方。

观察到的行为:
英语设置默认选项 – >国际 – 如预期
德语设置默认选项 – >国际 – 如预期

英文设置小数点分隔符改为“,”,千位分隔符设为“。” 和系统分隔符在选项 – >国际 – – Excel数据不正确。 请参见星号行。

数据Excel

3706888.0300 3706888.03
2587033.8000 2587033.8
2081071.1800 2081071.18
9030160.3333 90.301.603.333 **
42470.9842 424.709.842 **
4465546.2800 4465546.28
1436037.3200 1436037.32
111650.0000 111650
2567007.0833 25.670.070.833 **

我已经习惯了示例代码来演示这种行为。 如果有人能告诉我我做错了什么,将不胜感激。

要运行此代码示例,只需创build一个新的Windows窗体应用程序并将下面的代码发布到Form1.cs中。 您还需要添加对Microsoft.Office.Interop.Excel的引用。

非常感谢

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.Office.Interop.Excel; using System.Runtime.InteropServices; using System.Threading; using System.Globalization; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public void ExportDTToExcel() { Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); app.Visible = true; Workbook wb = app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet); Worksheet ws = (Worksheet)wb.ActiveSheet; string culture = System.Threading.Thread.CurrentThread.CurrentCulture.ToString();//"en-GB"; CultureInfo ci = new CultureInfo(culture); string excelGroupSeparator = app.ThousandsSeparator.ToString(); string excelDecimalSeparator = app.DecimalSeparator.ToString(); bool systemseparators = app.UseSystemSeparators ; if (app.UseSystemSeparators == false) { app.DecimalSeparator = ci.NumberFormat.NumberDecimalSeparator; app.ThousandsSeparator = ci.NumberFormat.NumberGroupSeparator; //ci.NumberFormat.NumberDecimalSeparator = app.DecimalSeparator; //ci.NumberFormat.NumberGroupSeparator = app.ThousandsSeparator; } //app.DecimalSeparator = ci.NumberFormat.NumberDecimalSeparator; //app.ThousandsSeparator = ci.NumberFormat.NumberGroupSeparator; app.UseSystemSeparators = true; // Content. try { SetCellValue("3706888.0300", ws, 0, 0, ci); SetCellValue("2587033.8000", ws, 1, 0, ci); SetCellValue("2081071.1800", ws, 2, 0, ci); SetCellValue("9030160.3333", ws, 3, 0, ci); SetCellValue("42470.9842", ws, 4, 0, ci); SetCellValue("4465546.2800", ws, 5, 0, ci); SetCellValue("1436037.3200", ws, 6, 0, ci); SetCellValue("111650.0000", ws, 7, 0, ci); SetCellValue("2567007.0833", ws, 8, 0, ci); } catch (Exception e) { MessageBox.Show(e.Message); } //wb.SaveAs(Filepath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); //wb.Close(false, Type.Missing, false); app.DecimalSeparator = excelDecimalSeparator; app.ThousandsSeparator = excelGroupSeparator; app.UseSystemSeparators = systemseparators; //app.Quit(); Marshal.ReleaseComObject(app); Marshal.ReleaseComObject(wb); Marshal.ReleaseComObject(ws); app = null; wb = null; ws = null; } private static void SetCellValue(string data, Worksheet ws,int row, int col, CultureInfo ci) { double val; try { val = Convert.ToDouble(data); Console.WriteLine(val); } catch (Exception e) { //Util.Log("Null Value ignored.", LogType.ERROR); return; } try { string s = val.ToString(); ws.Cells[row + 2 , col + 1] = s; //Util.Log("S:" + s, LogType.ERROR); } catch { //Util.Log("Null Value ignored.", LogType.ERROR); } } private void button1_Click(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; ExportDTToExcel(); this.Cursor = Cursors.Default; } } } 

我没有运行你的代码,只是扫描它…

第一个潜在的问题:您正在检查UseSystemSeparators,然后设置DecimalSeparaor和ThousandsSeparator。

  if (app.UseSystemSeparators == false) { app.DecimalSeparator = ci.NumberFormat.NumberDecimalSeparator; app.ThousandsSeparator = ci.NumberFormat.NumberGroupSeparator; } 

之后,你打开SystemSeparators,所以上面的代码没有做任何事情,因为你打开了系统分隔符。

  app.UseSystemSeparators = true; 

第二个潜在的问题/build议:设置单元格值时,将其设置为双精度值而不是string,让Excel为您设置数字格式。

这篇知识库文章和其他链接到的其他一些知识库文章描述了从.NET自动化Excel时可能遇到的一些本地化问题。

这可能有助于解释你的问题

感谢克里斯和乔,我终于得到了代码工作所需。

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.Office.Interop.Excel; using System.Runtime.InteropServices; using System.Threading; using System.Globalization; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public void ExportDTToExcel() { Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); app.Visible = true; string culture = System.Threading.Thread.CurrentThread.CurrentCulture.ToString();//"en-GB"; CultureInfo ci = new CultureInfo(culture); bool systemseparators = app.UseSystemSeparators ; if (app.UseSystemSeparators == false) { app.UseSystemSeparators = true; } // Content. Workbook wb = app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet); Worksheet ws = (Worksheet)wb.ActiveSheet; try { SetCellValue("3706888.0300", ws, 0, 0, ci); SetCellValue("2587033.8000", ws, 1, 0, ci); SetCellValue("2081071.1800", ws, 2, 0, ci); SetCellValue("9030160.3333", ws, 3, 0, ci); SetCellValue("42470.9842", ws, 4, 0, ci); SetCellValue("4465546.2800", ws, 5, 0, ci); SetCellValue("1436037.3200", ws, 6, 0, ci); SetCellValue("111650.0000", ws, 7, 0, ci); SetCellValue("2567007.0833", ws, 8, 0, ci); } catch (Exception e) { MessageBox.Show(e.Message); } app.UseSystemSeparators = systemseparators; Marshal.ReleaseComObject(app); Marshal.ReleaseComObject(wb); Marshal.ReleaseComObject(ws); app = null; wb = null; ws = null; } private static void SetCellValue(string data, Worksheet ws,int row, int col, CultureInfo ci) { double val; try { val = Convert.ToDouble(data); Console.WriteLine(val); } catch (Exception e) { //Util.Log("Null Value ignored.", LogType.ERROR); return; } try { string s = val.ToString(); ws.Cells[row + 2 , col + 1] = s; //Util.Log("S:" + s, LogType.ERROR); } catch { //Util.Log("Null Value ignored.", LogType.ERROR); } } private void button1_Click(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; ExportDTToExcel(); this.Cursor = Cursors.Default; } } } 

在COM上使用的Excel有几个限制,最重要的要尊重的是:

  • 使用en-US文化( LCID bug )
  • 从同一个线程调用所有方法(设置为正确的文化“en-US”)

然后,您将摆脱关于Excel自动化和本地化的大部分零星的崩溃。