C# - 使用国际设置的Excel数字格式问题

时间:2009-09-01 12:51:14

标签: c# excel interop formatting numbers

我正在尝试使用c#3.5写入Excel 2003电子表格。但是我无法在不同的国家/地区设置中正常运行。国家/地区设置为英语或德语。这两个设置具有不同的十进制和千位设置。除非用户在“选项”屏幕的“国际”设置中更改了小数和千位分隔符,否则一切正常。任何人都可以提供帮助,因为我觉得我再也看不到木头的树木了,我错过了一些明显的东西。

要点:

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

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

观察到的行为:
使用默认选项的英语设置 - >国际 - 正如预期的那样 具有默认选项的德语设置 - >国际 - 如预期的那样

英文设置,小数分隔符更改为“,”,千位分隔符设置为“。”选项中未选中的系统分隔符和>国际 - Excel数据不正确。见星号行。

Data 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 **

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

要运行此代码示例,只需创建一个新的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;
        }
        }
    }

4 个答案:

答案 0 :(得分:4)

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

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

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

然后,您正在打开SystemSeparators,因此上面的代码没有做任何事情,因为您打开了系统分隔符。

        app.UseSystemSeparators = true;

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

答案 1 :(得分:3)

用于COM的Excel有几个限制,最重要的是:

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

然后,您将摆脱有关Excel自动化的大多数零星崩溃事件。定位。

答案 2 :(得分:2)

This KB article以及它链接到的其他几篇知识库文章描述了从.NET自动化Excel时可能遇到的一些本地化问题。

它可能有助于解释您的问题

答案 3 :(得分:2)

感谢Chris和Joe,我终于让代码按照需要运行了。

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;
        }


    }
}