繁体   English   中英

在C#中导出到excel时如何使用正确的十进制分隔符和千位分隔符?

[英]How to use the correct Decimal separator and Thousands separator when exporting to excel in c#?

我有一堂课(可以在互联网上找到,我做了一些修改),可以将数据导出到.csv文件。 这很好。

但是,当我打开文件时,包含十进制值的数字显示错误。

例如:173,8543526将显示为:17.385.435.26,这是由于导出到csv时小数点分隔符不正确。

导出类如下所示:

public class CsvExport
{
    List<string> fields = new List<string>();

    List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();

    Dictionary<string, object> currentRow { get { return rows[rows.Count - 1]; } }

    public object this[string field]
    {
        set
        {
            // Keep track of the field names, because the dictionary loses the ordering
            if (!fields.Contains(field)) fields.Add(field);
            currentRow[field] = value;
        }
    }

    public void AddRow()
    {
        rows.Add(new Dictionary<string, object>());
    }

    public void RemoveLastRow()
    {
        rows.RemoveAt(rows.Count - 1);
    }

    string MakeValueCsvFriendly(object value)
    {
        if (value == null) return "";
        if (value is INullable && ((INullable)value).IsNull) return "";
        if (value is DateTime)
        {
            if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
                return ((DateTime)value).ToString("yyyy-MM-dd");
            return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
        }
        string output = value.ToString();
        if (output.Contains(",") || output.Contains("\""))
            output = '"' + output.Replace("\"", "\"\"") + '"';
        return output;
    }

    public string Export(bool omitHeaders)
    {
        StringBuilder sb = new StringBuilder();

        // The header
        if (!omitHeaders)
        {
            foreach (string field in fields)
                sb.Append(field).Append(";");
            sb.AppendLine();
        }

        // The rows
        foreach (Dictionary<string, object> row in rows)
        {
            foreach (string field in fields)
            {
                if (row.ContainsKey(field))
                {
                    sb.Append(MakeValueCsvFriendly(row[field])).Append(";");
                }
                else
                {
                    sb.Append(";");
                }

            }
            sb.AppendLine();   

        }

        return sb.ToString();
    }

    public string ExportToFileDialog(string defaultFileName)
    {
        string filename = String.Empty;
        var dlg = new Microsoft.Win32.SaveFileDialog
                      {
                          FileName = !String.IsNullOrEmpty(defaultFileName) ? defaultFileName : String.Empty,
                          DefaultExt = ".csv",
                          Filter = "CSV (Comma delimited)|*.csv"
                      };

        // Show save file dialog box
        var result = dlg.ShowDialog();

        // Process save file dialog box results
        if (result == true)
        {
            // Save document
            filename = dlg.FileName;
        }

        return filename;
    }

    public void ExportToFile(string path, bool append = false, bool omitHeaders = false)
    {
        try
        {
            if (append)
                File.AppendAllText(path, Export(omitHeaders), Encoding.UTF8);
            else
                File.WriteAllText(path, Export(omitHeaders), Encoding.UTF8);
        }
        catch (Exception exc) 
        {

        }
    }

所以我的问题是,如何在此类中定义“,”应为小数点分隔符和“。”。 应该是千位分隔符?

为此,您可能需要强制格式使用不同的千位分隔符和小数位。

您可以使用具有NumberFormatInfo类型的自定义数字格式器。 首先,在类中放置一个类变量:

NumberFormatInfo customNumFormat;

然后定义一个构造函数,如下所示:

public CsvExport()
{
    customNumFormat = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone();
    customNumFormat.NumberGroupSeparator = ".";
    customNumFormat.NumberDecimalSeparator = ",";
}

这将定义一个带有所需分隔符的数字格式器。 这使您可以控制分隔符和小数位标记以使用所需的任何字符。

要使用此功能,您需要自己设置数字的格式,因此请在MakeValueCsvFriendly方法中添加另一个if语句,如下所示:

if (value is decimal || value is double || value is int)
  return string.Format(customNumFormat, "{0:N}", value);

如果字典中还有其他数字类型,则需要将这些类型相应地添加到if语句中。

希望这可以帮助。

我试图向MakeValueCsvFriendly添加逻辑:

string MakeValueCsvFriendly(object value)
{
    if (value == null) return "";
    if (value is INullable && ((INullable)value).IsNull) return "";
    if (value is DateTime)
    {
        if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
            return ((DateTime)value).ToString("yyyy-MM-dd");
        return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
    }
    else if(value is int || value is double || value is float || value is decimal || value is long || value is uint || value is ulong || value is ushort)
    {
        // Output numbers
        // Specific culture: da-DK
        // Specific format: N (thousand separator + 2 decimals)
        // 123456789098.7654321 => 123.456.789.098,77
        return value.ToString("N", new CultureInfo("da-DK"));
    }
    else
    {
        string output = value.ToString();
        if (output.Contains(",") || output.Contains("\""))
            output = '"' + output.Replace("\"", "\"\"") + '"';
        return output;
    }
}

在此处查看更多数字格式:

  1. 标准: http//msdn.microsoft.com/en-us/library/dwhawy9k(v = vs.110).aspx
  2. 自定义: http : //msdn.microsoft.com/zh-cn/library/0c899ak8(v=vs.110).aspx

而不是string output = value.ToString(); , 采用:

string output;
if (value is Decimal)
    output = value.ToString("N");
else
    output = value.ToString();

这里的问题在于解释,而不是输出。

只要正确设置了千位分隔符(以及字段分隔符),就可以将十进制数写为173,8543526到CSV并没有问题。

在Excel(2010)中,如果单击“ Data > From Text然后按照“ Text Import Wizard进行步骤3,则可以单击“ Advanced为每列选择小数和千位分隔符。

请注意,CSV不是正式的标准(虽然有一些事实上的规则),所以您可以选择所需的任何分隔符,只要可以正确解释它们即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM