2

我正在使用 eeplus 创建一个 excel 电子表格,像这样

using (var pck = new ExcelPackage())
{
  var ws = pck.Workbook.Worksheets.Add("Customers");
  ws.Cells["A1"].LoadFromCollection(customers, PrintHeaders: true);

  var ms = new System.IO.MemoryStream();
  pck.SaveAs(ms);

  ms.WriteTo(Response.OutputStream);
}

客户类具有如下属性

[DisplayName("Customer creation date")]
public DateTime Created { get; set; }

DisplayName似乎很荣幸,所以最上面的行将Customer creation date显示,但单元格内容显示为43257,41667.

我真正想要的是具有格式的单元格2018-04-05

我可以这样做吗?我都试过了

[DisplayName("Customer creation date")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime Created { get; set; }

[DisplayName("Customer creation date")]
[DataType(DataType.Date)]
public DateTime Created { get; set; }

但单元格内容保持不变。

4

2 回答 2

4

不,EPPlus 不会根据数据注释格式化您的数据。它将日期格式化为整数,因此您应该指定要格式化为的列

ws.Column(colPosition+1).Style.Number.Format="yyyy-mm-dd";

您可以在此处找到详细信息: https ://github.com/JanKallman/EPPlus/wiki/Formatting-and-styling

https://codereview.stackexchange.com/questions/139569/ensuring-specific-columns-in-an-excelworksheet-format-as-shortdate

于 2018-06-05T10:12:41.773 回答
0

EPPlus 在根据 DisplayName 属性更新到 excel 时总是更改列名,否则如果没有设置 DisplayName 属性,则它将在列名中查找"_"(下划线)字符并将其替换为" "(空格)字符,因此我们不能轻易在列名的帮助下找到 PropertyInfo 以根据我们的需要格式化列。

这是基于 PropertyInfo 索引来格式化列的简单快捷的解决方案

PropertyInfo[] props = typeof(T).GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < props.Length; i++)
{
    Type t = props[i].PropertyType;
    if (t == typeof(DateTime) || t == typeof(DateTime?))
        ws.Column(i + 1).Style.Numberformat.Format = "dd-MMM-yyyy HH:mm:ss";
    else if (t == typeof(TimeSpan) || t == typeof(TimeSpan?))
        ws.Column(i + 1).Style.Numberformat.Format = "HH:mm:ss";
}

如果您需要根据列名格式化列,我还有另一个解决方案。

void ApplyDateTimeFormatting<T>(ExcelWorksheet ws, IEnumerable<T> data)
{
    if (data.Count() == 0) 
        return;
    Type type = data.First().GetType();
    for (int c = 1; c <= toColumns; c++)
    {
        string column = ws.Cells[1, c].Text;
        var t = type.GetPropertyWithDisplayName<T>(column).PropertyType;
        if (t == typeof(DateTime) || t == typeof(DateTime?))
            ws.Column(c).Style.Numberformat.Format = "dd-MMM-yyyy HH:mm:ss";
        else if (t == typeof(TimeSpan) || t == typeof(TimeSpan?))                
            ws.Column(c).Style.Numberformat.Format = "HH:mm:ss";
    }
}

PropertyInfo GetPropertyFromDisplayName(Type type, string DisplayName)
{
    MemberInfo[] members = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (var member in members)
    {
        DisplayNameAttribute displayNameAttribute = member
            .GetCustomAttributes(typeof(DisplayNameAttribute), inherit: false)
            .FirstOrDefault() as DisplayNameAttribute;
        string text = ((displayNameAttribute == null) ? member.Name.Replace('_', ' ') :
            displayNameAttribute.DisplayName);
        if (text == DisplayName)
            return type.GetProperty(member.Name);
    }
    return null;
}
于 2021-02-27T20:01:06.840 回答