C # - проблема форматирования номера Excel с международными настройками - PullRequest
2 голосов
/ 01 сентября 2009

Я пытаюсь записать в электронную таблицу Excel 2003, используя c # 3.5. Однако я не могу заставить его работать правильно в разных странах. Настройки страны - либо английский, либо немецкий. Эти две настройки имеют разные десятичные и тысячи настроек. Все работает нормально, если пользователь не изменил десятичный разделитель и разделитель тысяч в Международных настройках экрана Параметры. Может ли кто-нибудь помочь, так как я чувствую, что больше не вижу дрова для деревьев и упускаю что-то очевидное.

Резюме:

Данные получены из базы данных доступа. Прочитано приложением 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 **

Я привел пример кода, чтобы продемонстрировать это поведение. Если кто-нибудь может показать мне, что я делаю неправильно, это будет высоко ценится.

Чтобы запустить этот пример кода, просто создайте новое приложение для форм 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 ]

4 голосов
/ 01 сентября 2009

Я не запускал твой код, просто отсканировал его ...

Первая потенциальная проблема: вы проверяете UseSystemSeparators, а затем устанавливаете DecimalSeparaor и ThousandsSeparator.

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

Затем сразу после этого вы включаете SystemSeparators, поэтому приведенный выше код ничего не делает, так как вы включаете системные разделители.

        app.UseSystemSeparators = true;

Вторая потенциальная проблема / предложение: При установке значения ячейки задайте его как двойное значение вместо строки, пусть Excel отформатирует для вас число.

3 голосов
/ 15 сентября 2009

Excel, используемый через COM, имеет несколько ограничений, наиболее важными из которых являются:

  • Используйте культуру en-US ( Ошибка LCID )
  • Вызвать все методы из одного и того же потока (установить правильную культуру "en-US")

Тогда вы избавитесь от большинства спорадических сбоев, связанных с автоматизацией и локализацией Excel.

2 голосов
/ 01 сентября 2009

Благодаря Крису и Джо, я наконец-то получил код для работы по своему усмотрению.

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


    }
}
2 голосов
/ 01 сентября 2009

В этой статье базы знаний и нескольких других статьях базы знаний, на которые она ссылается, описываются некоторые проблемы локализации, с которыми вы можете столкнуться при автоматизации Excel из .NET.

Это может помочь объяснить вашу проблему

...