【问题标题】:How to format currency in ClosedXML as numeric如何将 ClosedXML 中的货币格式化为数字
【发布时间】:2015-08-03 12:05:20
【问题描述】:

我们正在使用 ClosedXML 将数据表对象转换为 Excel 电子表格以呈现给用户。 DataTable 对象的构建只需将所有 db 值(来自 NHibernate)分配给字符串,然后将它们格式化如下:

  //formatting
EstimatedCost = Currency.SafeToString(Currency.Create(n.EstimatedCost)),

然后我们将列类型设置为属性类型,即所有情况下的字符串。

输出 Excel 工作表中发生的情况是,该列设置为货币但将数字作为文本警告,然后它不会正确排序。

我的问题是,由于我们将所有数据构建到 DataTable 中,我没有机会正确装饰 ClosedXML 列。有没有我没想到的快速方法?

public const string ExcelDataType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";

public static MemoryStream GenerateExcelFileFromData(IEnumerable<KeyValuePair<string, DataTable>> tabs, int colWidth = 100)
{
  var workbook = new XLWorkbook { ColumnWidth = colWidth };
  foreach (var enumerable in tabs)
  {
    workbook.Worksheets.Add(enumerable.Value, enumerable.Key);
  }

...

 public static DataTable ConvertToDataTable<T>(IEnumerable<T> varlist, List<string> excludedColumns, bool titleizeColumn = false)
 {
   var dtReturn = new DataTable();

   // column names 
   PropertyInfo[] oProps = null;

   if (varlist == null) return dtReturn;

    foreach (T rec in varlist)
    {
     // Use reflection to get property names, to create table, Only first time, others will follow 
        if (oProps == null)
        {
           oProps = rec.GetType().GetProperties();
              foreach (PropertyInfo pi in oProps)
               {
                    if (excludedColumns.Contains(pi.Name))
                    {
                        continue;
                    }
                    var colType = pi.PropertyType;
                    dtReturn.Columns.Add(new DataColumn(GetColumnName(pi, titleizeColumn), colType));
                }
          }

        DataRow dr = dtReturn.NewRow();

        foreach (var pi in oProps.Where(pi => !excludedColumns.Contains(pi.Name)))
          {
             try
                {
                    dr[GetColumnName(pi, titleizeColumn)] = pi.GetValue(rec, null) ?? DBNull.Value;
                }
                catch (ArgumentException)
                {
                    dr[GetColumnName(pi, titleizeColumn)] = DBNull.Value;
                }
            }
            dtReturn.Rows.Add(dr);
        }
        return dtReturn;

【问题讨论】:

    标签: c# excel closedxml


    【解决方案1】:

    您可以这样格式化您的货币值:

    worksheet.Cell(rowIndex, columnIndex).Style.NumberFormat.Format = "$0.00";
    worksheet.Cell(rowIndex, columnIndex).DataType = XLCellValues.Number; // Use XLDataType.Number in 2018 and after
    

    【讨论】:

    • 我希望获得 Excel 使用的完整“会计”格式 - 用于零和所有。这是您必须分配给Style.NumberFormat.Format 以获得真正的会计格式的字符串:"_($* #,##0.00_);_($* (#,##0.00);_($* \" - \"??_);_(@_)"
    • 注意,2018年XLCellValues枚举改名为XLDataType
    【解决方案2】:

    您可以获取所有您知道是货币的列并设置 NumberFormat.Format。以下是如何完成的示例。用于美元货币的正确格式是 "[$$-en-US]#,##0.00_);[Red]([$$-en-US]#,##0.00)"。使用此格式时,如果您在 Excel 中打开电子表格并转到单元格格式,您将看到它设置为货币。

        // Assume all columns that have "price" in the heading are currency types and format as currency.
        var priceColumns = table.Columns(c => c.FirstCell().Value.ToString().Contains("price", StringComparison.InvariantCultureIgnoreCase));
        foreach (var priceColumn in priceColumns)
        {
            try
            {
                // Get all the cells in this column, except for the header row
                var cells = priceColumn.Cells(2, rowCount);
                cells.Style.NumberFormat.Format = @"[$$-en-US]#,##0.00_);[Red]([$$-en-US]#,##0.00)";
            }
            catch { } // Exception here means not all of the cells have a numeric value.
        }
    

    【讨论】:

      【解决方案3】:
      ws.Cell(ro, co).Style.NumberFormat.Format = "[$$-en-US] #,##0.00";
      ws.Cell(ro, co).DataType = XLDataType.Number;
      

      【讨论】:

      • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
      猜你喜欢
      • 1970-01-01
      • 2020-07-18
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多