如何使用C#在Excel中为单元格设置本地化的短日期格式?

时间:2016-02-14 16:43:15

标签: c# excel date types format

使用C#和VSTO,可以使用以下代码设置Excel中单元格的类型:

worksheet.Cells[i, j].NumberFormat = magicString;

,其中worksheetMicrosoft.Office.Interop.Excel.Worksheet类的对象,i是单元格的行号,j是单元格的列号,{{ 1}}是定义单元格类型的字符串(注意:Excel将类型称为 format ,但下面我使用的单词 type )。

以下magicString定义以下Excel类型:

  • magicString - 定义“常规”Excel类型;
  • string magicString = ""; - 定义“文本”Excel类型;
  • string magicString = "@"; - 定义“百分比”Excel类型。

当我想设置“日期”Excel类型时,情况会更复杂。复杂性与Excel 在Windows系统本地化方面的本地化有关。

所以,例如,我有一个俄语版的Excel(特别是所有类型都是用俄语写的)我的Windows系统有以下短日期格式:“dd。 MM.yyyy“(可在控制面板中找到此设置>区域和语言>格式)。我有一个英文版的Windows,但这绝对没有任何作用。

因此,如果我在代码中使用以下string magicString = "0%";,则单元格的类型将设置为短日期类型:

  • magicString - 定义“日期”(或更确切地说,“短日期”)Excel类型;

正如您所看到的,string magicString = "ДД.ММ.ГГГГ";是俄语字母(俄语 - 因为Excel是俄语)的组合在Windows设置中设置的格式。

如果我使用magicString等于“DD.MM.YYYY”(即英文字母)而不是magicString,则会出现错误。

因此,如果我希望我的Excel加载项能够正确设置所有(英语,俄语,德语和所有其他)Excel版本的“短日期”类型对于Windows的所有本地化设置,我必须能够使用一些通用的magicString,这与上述两个因素无关。

作为一个选项,我可以使用以下代码从Windows设置中读取短日期格式:

magicString

然后,将获得的string shortDatePattern = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern; 字符串中的字母替换为与Excel语言对应的字母。但是,这种方式在我看来太复杂了。

我的问题是:是否有一些通用shortDatePattern适用于所有Windows本地化设置的所有Excel语言,就像其他Excel类型(如“常规”)一样, “文字”和“百分比”?或者,也许有人知道达到这种普遍性的其他简单方法吗?

2 个答案:

答案 0 :(得分:4)

你应该能够这样做:

Application xlApp = new Application();
Workbook wb = xlApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
Worksheet ws = wb.Worksheets[1];

var yearCode = xlApp.International[XlApplicationInternational.xlYearCode];
var monthCode = xlApp.International[XlApplicationInternational.xlMonthCode];
var dayCode = xlApp.International[XlApplicationInternational.xlDayCode];

ws.Cells[1, 1].NumberFormat = string.Format("{0}{1}.{2}{3}.{4}{5}{6}{7}", dayCode, dayCode, monthCode, monthCode, yearCode, yearCode, yearCode, yearCode);

Application上有International属性。您可以使用XlApplicationInternational枚举进行查询。对我而言xlYearCode例如返回é。那应该是Г

之后,您可以使用之前查询的格式代码构建NumberFormat

答案 1 :(得分:3)

非常感谢SzabolcsDézsi提示。但它只解决了我问题的一部分。另一部分是如何从Windows系统本地化设置中提取日期格式代码?我没有在互联网上找到答案并提供我自己的解决方案,结合SzabolcsDézsi的解决方案。

首先,让我们创建以下类:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

using Excel = Microsoft.Office.Interop.Excel;

namespace MyNamespace
{
    internal sealed class DateFormatComponentCodes
    {
        private readonly char year;
        private readonly char month;
        private readonly char day;

        // Constructs the object based on the system localization.
        public DateFormatComponentCodes()
        {
            DateTimeFormatInfo dateTimeFormatInfo = CultureInfo.CurrentCulture.DateTimeFormat;

            var yearMonth = new HashSet<char>(new HashSet<char>(dateTimeFormatInfo.YearMonthPattern.ToCharArray()).Where(c => char.IsLetter(c)));
            var monthDay = new HashSet<char>(new HashSet<char>(dateTimeFormatInfo.MonthDayPattern.ToCharArray()).Where(c => char.IsLetter(c)));

            var monthHashSet = new HashSet<char>(yearMonth);
            monthHashSet.IntersectWith(monthDay);
            this.month = monthHashSet.First();

            yearMonth.ExceptWith(monthHashSet);
            this.year = yearMonth.First();

            monthDay.ExceptWith(monthHashSet);
            this.day = monthDay.First();
        }

        // Constructs the object based on the Excel localization.
        public DateFormatComponentCodes(Excel.Application application)
        {
            this.year = application.International[Excel.XlApplicationInternational.xlYearCode].ToString()[0];
            this.month = application.International[Excel.XlApplicationInternational.xlMonthCode].ToString()[0];
            this.day = application.International[Excel.XlApplicationInternational.xlDayCode].ToString()[0];
        }

        public char Year
        {
            get
            {
                return this.year;
            }
        }

        public char Month
        {
            get
            {
                return this.month;
            }
        }

        public char Day
        {
            get
            {
                return this.day;
            }
        }
    }
}

现在让我们创建这个类的两个对象,并使用它们为Excel生成短日期格式模式(上面称为“魔术字符串”):

private string ConstructExcelShortDatePattern()
{
    var systemDateComponentCodes = new DateFormatComponentCodes();
    var excelDateComponentCodes = new DateFormatComponentCodes(this.application);

    string systemShortDatePattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
    string excelShortDatePattern = systemShortDatePattern.Replace(systemDateComponentCodes.Year, excelDateComponentCodes.Year).Replace(systemDateComponentCodes.Month, excelDateComponentCodes.Month).Replace(systemDateComponentCodes.Day, excelDateComponentCodes.Day);

    return excelShortDatePattern;
}

返回的字符串可用于设置所有Windows本地化和所有Excel本地化的短日期格式,例如

worksheet.Cells[i, j].NumberFormat = ConstructExcelShortDatePattern();