在c#中导出到excel时如何使用正确的小数分隔符和千位分隔符
本文关键字:分隔符 小数 千位 excel 何使用 | 更新日期: 2023-09-27 18:13:11
我有一个类(发现在互联网上,我做了一些修改),可以导出数据到。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;
}
}
查看更多数字格式:
- 标准:http://msdn.microsoft.com/en-us/library/dwhawy9k (v = vs.110) . aspx
- 自定义:http://msdn.microsoft.com/en-us/library/0c899ak8 (v = vs.110) . aspx
代替string output = value.ToString();
,使用:
string output;
if (value is Decimal)
output = value.ToString("N");
else
output = value.ToString();
这里的问题在于解释,而不是输出。
只要您的千位分隔符设置正确(以及您的字段分隔符),将十进制写入CSV为173,8543526
没有任何错误。
在Excel(2010)中,如果您点击Data > From Text
,并按照Text Import Wizard
到步骤3,您可以点击Advanced
来选择每列的小数和千位分隔符。
请注意,CSV并不是一个正式的标准(虽然有一些事实上的规则),所以您可以选择任何您喜欢的分隔符,只要您能正确地解释它们。