【问题标题】:Set format of cells produced by LoadFromCollection (epplus) using data annotation使用数据注释设置由 LoadFromCollection (epplus) 生成的单元格格式
【发布时间】:2018-11-13 18:26:00
【问题描述】:

我正在使用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; }

但单元格内容保持不变。

【问题讨论】:

    标签: data-annotations epplus excelpackage


    【解决方案1】:

    不,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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-24
        • 1970-01-01
        • 2017-06-25
        • 1970-01-01
        • 2015-09-07
        相关资源
        最近更新 更多