使用 EPPlus 的 Excel 日期格式

本文关键字:日期 格式 Excel EPPlus 使用 | 更新日期: 2023-09-27 17:56:16

我在格式化单元格时遇到问题。

FileInfo info = new FileInfo(path);
using (ExcelPackage package = new ExcelPackage(info))
{
      ExcelWorksheet ws = package.Workbook.Worksheets.Add(sheetName);
      ws.Cells[3, 1].Style.Numberformat.Format = "yyyy-mm-dd";
      ws.Cells["A3"].Formula = "=DATE(2014,10,5)";
}

Excel 中的输出:41 917,00

为什么这不起作用?

使用 EPPlus 的 Excel 日期格式

我同意Yosoyke的观点。您可能定位了错误的单元格。您可以尝试:

ws.Cells["A3"].Style.Numberformat.Format = "yyyy-mm-dd";
ws.Cells["A3"].Formula = "=DATE(2014,10,5)";
worksheet.Cells["YOURDATECELL_OR_YOURDATECELLRANGE"].Style.Numberformat.Format = "mm-dd-yy";

如果您使用塔拉兹提到的公式。最后计算()。参考https://epplus.codeplex.com/wikipage?title=About%20Formula%20calculation

或者不使用公式,替代方法

private static decimal GetExcelDecimalValueForDate(DateTime date)
{
    DateTime start = new DateTime(1900, 1, 1);
    TimeSpan diff = date - start;
    return diff.Days + 2;
}

参考

worksheet.Cells["A2"].Value = GetExcelDecimalValueForDate(Convert.ToDateTime('2016-04-29'));
worksheet.Cells["A2"].Style.Numberformat.Format = "mm-dd-yy";//or m/d/yy h:mm

默认情况下,当 excel 保存日期字段时,它会将其保存为 numFormatId 14(查看 xls 中的 xml 文件)。这可确保打开文件时在任何国家/地区正确设置日期格式。在 Epplus 中,mm-dd-yy转换为 excel 的 numFormatId 14。这将确保在任何国家/地区打开文件时,将根据国家/地区的短日期设置正确格式化日期。还注意到m/d/yy h:mm任何国家/地区的格式正确。

var dateColumns = from DataColumn d in dt.Columns
                  where d.DataType == typeof(DateTime) || d.ColumnName.Contains("Date")
                  select d.Ordinal + 1;
foreach (var dc in dateColumns)
{
    worksheet.Cells[2, dc, rowCount + 2, dc].Style.Numberformat.Format = "mm/dd/yyyy hh:mm:ss AM/PM";
}

它将格式化所有带有标题日期的列,以给定/提供的特定格式

我在转换

CSV 时遇到了同样的问题。我能够以稍微不同的方式做到这一点。

private string ConvertToExcel(string CSVpath, string EXCELPath)
    {
        try
        {
            string Filename = System.IO.Path.GetFileNameWithoutExtension(CSVpath);
            string DirectoryName = System.IO.Path.GetDirectoryName(CSVpath);
            EXCELPath = DirectoryName + "''" + Filename + ".xlsx";
            string worksheetsName = "Report";
            bool firstRowIsHeader = false;
            var format = new OfficeOpenXml.ExcelTextFormat();
            format.Delimiter = '|';
            format.EOL = "'n";
            using (OfficeOpenXml.ExcelPackage package = new OfficeOpenXml.ExcelPackage(new System.IO.FileInfo(EXCELPath)))
            {
                string dateformat = "m/d/yy h:mm";
                //string dateformat = System.Globalization.DateTimeFormatInfo.CurrentInfo.ShortDatePattern;
                OfficeOpenXml.ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(worksheetsName);
                worksheet.Cells["A1"].LoadFromText(new System.IO.FileInfo(CSVpath), format, OfficeOpenXml.Table.TableStyles.Medium2, firstRowIsHeader);
                worksheet.Column(3).Style.Numberformat.Format = dateformat;
                worksheet.Column(5).Style.Numberformat.Format = dateformat;
                worksheet.Column(6).Style.Numberformat.Format = dateformat;
                worksheet.Column(20).Style.Numberformat.Format = dateformat;
                worksheet.Column(21).Style.Numberformat.Format = dateformat;
                worksheet.Column(22).Style.Numberformat.Format = dateformat;


                package.Save();
            }
        }
        catch (Exception ex)
        {
            //DAL.Operations.Logger.LogError(ex);
            Console.WriteLine(ex);
            Console.Read();
        }
        return EXCELPath;
    }

采用 IEnumerable(数据)的通用解决方案,它遍历通用对象的属性,查找 DateType 或 nullableDate 类型并应用格式:

   //set the list of dateColumns which will be used to formate them
            List<int> dateColumns = new List<int>();
            //get the first indexer
            int datecolumn = 1;
            //loop through the object and get the list of datecolumns
            foreach (var PropertyInfo in data.FirstOrDefault().GetType().GetProperties())
            {
                //check if property is of DateTime type or nullable DateTime type
                if (PropertyInfo.PropertyType == typeof(DateTime) || PropertyInfo.PropertyType == typeof(DateTime?))
                {
                    dateColumns.Add(datecolumn);
                }
                datecolumn++;
            }
            // Create the file using the FileInfo object
            var file = new FileInfo(outputDir + fileName);
            //create new excel package and save it
            using (var package = new ExcelPackage())
            {
                //create new worksheet
                var worksheet = package.Workbook.Worksheets.Add("Results");

                // add headers
                worksheet.Cells["A1"].LoadFromCollection(data, true);
                //format date field 
                dateColumns.ForEach(item => worksheet.Column(item).Style.Numberformat.Format = "dd-mm-yyyy");
                // auto size columns
                worksheet.Cells.AutoFitColumns();
                //save package
                package.SaveAs(file);
            }
如果你想

使用 AM/PM

   worksheet.Cells[1].Style.Numberformat.Format = "dd/MM/yyyy  HH:mm:ss AM/PM";

继非常好的通用解决方案之后,它需要IEnumerable..答案,我们必须更进一步,为不同的属性显示不同的日期格式。例如,有些列需要显示为dd/MM/yyyy,而其他列需要显示为dd/MM/yyyy hh:mm

因此,我们在属性中添加了一个带有DataFormatString(表示DateTime格式)的DisplayFormat注释,如下所示:

using System.ComponentModel.DataAnnotations;
...
[DisplayName("Download Date")]
[DisplayFormat(DataFormatString = "dd/MM/yyyy hh:mm")]
public string DownloadDate { get; set; }
...

然后借用采用 IEnumerable 的通用解决方案,我们在迭代数据对象的属性时从 DisplayFormat 注释中提取日期格式字符串:

public void FormatDateColumns(ExcelWorksheet worksheet, IEnumerable<IResult> data)
{
    // Dictionary 'key' contains the Index of the column that contains DateTime data
    // Dictionary 'value' contains the DateTime format for that column
    Dictionary<int, string> dateColumns = new Dictionary<int, string>();
    int dateColumnIndex = 1;
    // find all the DateTime/DateTime? columns in the data object 
    foreach (var PropertyInfo in data.FirstOrDefault().GetType().GetProperties())
    {
        if (PropertyInfo.PropertyType == typeof(DateTime) || PropertyInfo.PropertyType == typeof(DateTime?))
        {
            string dateTimeFormat = Constants.DefaultDateTimeFormat;
            // attempt to get a DataFormatString from a DisplayFormat annotation which may be decorating the Property
            // looking for an annotation something like [DisplayFormat(DataFormatString = "dd-MM-yyyy hh:mm")] 
            if (PropertyInfo.CustomAttributes != null)
            {
                var dislayFormatAttribute = PropertyInfo.CustomAttributes.Where(x => x.AttributeType.Name == "DisplayFormatAttribute").FirstOrDefault();
                if (dislayFormatAttribute != null && dislayFormatAttribute.NamedArguments != null && dislayFormatAttribute.NamedArguments.Count > 0)
                {
                    var displayFormatArg = dislayFormatAttribute.NamedArguments.First();
                    if (displayFormatArg != null && displayFormatArg.TypedValue != null && displayFormatArg.TypedValue.Value != null)
                    {
                        // NOTE: there is probably an easier way to get at this value?
                        dateTimeFormat = displayFormatArg.TypedValue.Value.ToString();
                    }
                }
            }
            dateColumns.Add(dateColumnIndex, dateTimeFormat);
        }
        dateColumnIndex++;
    }
    if (dateColumns.Count > 0)
    {
        // apply the formatting
        dateColumns.ToList().ForEach(item => worksheet.Column(item.Key).Style.Numberformat.Format = item.Value);
    }
}
我想

补充一点,格式的设置是我的解决方案。但是,在我将 value 属性设置为 DateTime 对象而不是字符串之前,我无法让它工作。这是使这一切发挥作用的关键。

我遇到了类似的问题,即使我正确设置了日期并将正确的数字格式应用于包含日期的单元格,我也看到了日期的数字表示形式。

事实证明,在那之后,我应用了一种样式,有效地重置了我的格式。

代码是这样的:

ws.Cells["A3"].Style.Numberformat.Format = 
System.Globalization.DateTimeFormatInfo.CurrentInfo.ShortDatePattern;
ws.Cells["A3"].Value = New DateTime(2021, 10, 15, 23, 16, 0).ToOADate();

后来,我有了:

ws.Cells("A3").StyleName = colStyle //colstyle is a style created earlier

为了解决这个问题,我需要在设置样式后应用NumberFormat.Format

确保单元格宽度足够大以显示您的日期!如果单元格显示###符号,则会出现此问题。

一个简单的解决方法是自动调整工作表中的单元格宽度:

ws.Cells.AutoFitColumns();

传递DateTime对象的完整示例:

ws.Cells[3, 1].Style.Numberformat.Format = "yyyy-mm-dd";
ws.Cells[3, 1].Value = new DateTime(2014,10,5);
ws.Cells.AutoFitColumns();
<小时 />

有关高级格式设置,请查看 https://support.microsoft.com/en-us/office/number-format-codes-5026bbd6-04bc-48cd-bf33-80f18b4eae68。

请记住不要将数字格式代码的保留字符本地化为另一种语言:为年份编写yyyy,而不是jjjj。如果要设置数字格式并需要小数分隔符,请写0.00,而不是0,00

(发布这个,因为我一直在绊倒这个问题,这个问题是第一个搜索结果。

一些新闻:

唰。单元格["A3"]。Style.Numberformat.Format = "[$-en-US]yyyy-mmm-dd";
互联网服务提供商单元格["A3"]。公式 ="=日期(2014,10,5)";