【问题标题】:How to set Column Type when using EPPlus使用 EPPlus 时如何设置列类型
【发布时间】:2012-04-09 05:13:39
【问题描述】:

我使用EPPlus 生成Excel 文件,在DAL 中填充DataTable,将数据填充到表中,并将表传递到表示层。从那里我使用LoadFromDataTable() 方法生成Excel 文件。

一切正常,除了我想将列的类型之一设置为Date。我尝试将我的DataTable 的列类型设置为Date,然后将DataTable 传递给表示层,但似乎EPPlus 要么忽略它,要么没有识别,因为当我打开时生成@ 987654331@ 文件,单元格类型为Number

如果我手动设置单元格格式并将类型设置为DateExcel 会显示正确的日期。那么我该如何实现呢?

【问题讨论】:

    标签: .net excel epplus


    【解决方案1】:

    您确实需要 DataTable 列具有正确的类型,但您还需要修改列或单元格的 Style.Numberformat.Format 属性。

    假设您有一个名为wsExcelWorksheet

    ws.Column(1).Style.Numberformat.Format  = "yyyy-mm-dd"; 
    //OR "yyyy-mm-dd h:mm" if you want to include the time!
    

    【讨论】:

    • Excel 会根据个人 Excel 设置更改此格式吗?想想欧盟和美国。
    【解决方案2】:

    基于此讨论 (epplus.codeplex.com/discussions/349927),您还可以将列格式设置为日期。

    worksheet_1.Cells[row, 3].Style.Numberformat.Format = DateTimeFormatInfo.CurrentInfo.ShortDatePattern;

    【讨论】:

    • 仅供参考,这来自 System.Globalization,因此您必须“使用 System.Globalization”添加该命名空间。
    【解决方案3】:

    如果您的列可能会四处移动(我们知道最终用户往往变化无常),或者您的电子表格中散布着许多日期列,那么编写一些更通用的内容会很有帮助。这是我刚刚写的。 它在我的 POCO 中查找所有 DateTime 类型的位置,并创建一个列表,然后用于设置列格式。请记住,数据表是从零开始的,而 Excel 不是。

            ws.Cells.LoadFromDataTable(tbl, true);
            var dPos = new List<int>();
            for (var i = 0; i < tbl.Columns.Count; i++)
                if (tbl.Columns[i].DataType.Name.Equals("DateTime"))
                    dPos.Add(i);
            foreach (var pos in dPos)
            {
                ws.Column(pos+1).Style.Numberformat.Format = "mm/dd/yyyy hh:mm:ss AM/PM";
            }
    

    如果您要处理多个数据表,您可能希望将其重构为一个函数。

    这是一个免费赠品...我不能把这个代码归功于我。它需要一个 POCO 列表并将其转换为数据表。在我的“工具包”中多次使用它使我的生活更轻松。享受吧。

            public DataTable ConvertToDataTable<T>(IList<T> data)
        {
            var properties =
               TypeDescriptor.GetProperties(typeof(T));
            var table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            foreach (T item in data)
            {
                var row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                table.Rows.Add(row);
            }
            return table;
        }
    

    【讨论】:

      【解决方案4】:

      这是一个很好的 C# 扩展方法,可以帮助从集合中加载标题和正确的日期格式:

      (使用列标题的描述属性装饰您的属性)

      public static class EpPlusExtensions
      {
          public static void Load<T>(this ExcelWorksheet worksheet, IEnumerable<T> collection)
          {
              worksheet.Cells["A1"].LoadFromCollection(collection, true);
      
              var properties = typeof(T).GetProperties();
      
              for (var i = 0; i < properties.Length; i++)
              {
                  if (new []{typeof(DateTime), typeof(DateTime?)}.Contains(properties[i].PropertyType)) 
                  {
                      worksheet.Column(i + 1).Style.Numberformat.Format = "m/d/yyyy";
                  }
              }
          } 
      }
      

      【讨论】:

        【解决方案5】:

        要在 excel 格式中使用 build,您需要将正确的字符串传递给

        sheet.Cells[1, 1].Style.Numberformat.Format 
        

        财产。

        现在,在执行期间的某个地方,可能在序列化期间,EPPlus 将尝试将此格式属性与工作簿中的当前样式字典匹配。它可能取决于确切的库版本,但例如 EPPlust 4.1.0.0 短日期键是“mm-dd-yy”。

        对于 4.1.0.0,您可以在以下格式中找到所有硬编码代码和密钥:

        1. ExcelNumberFormatXml.cs,internal static void AddBuildIn(XmlNamespaceManager NameSpaceManager, ExcelStyleCollection&lt;ExcelNumberFormatXml&gt; NumberFormats) - 这里所有这些代码实际上都包含在工作簿中,都是硬编码的
        2. 使用调试器检查Workbook.Styles.NumberFormats枚举(作为键使用ExcelNumberFormatXml.Format
        3. 使用调试器并检查 Workbook.Styles.NumberFormats.(non public memeber)_dic 以获取确切的密钥。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-18
          • 2010-11-22
          • 1970-01-01
          • 2012-02-24
          • 2012-06-09
          • 1970-01-01
          相关资源
          最近更新 更多