I have created a generic method which downloads a csv file for any input. I am facing issue with the chinese and korean character as they are coming differently in the csv file.
private IActionResult ReturnCsvFile<T>(IEnumerable<T> users)
{
var csvString = new StringBuilder();
Type typeParameterType = typeof(T);
var propInfos = typeParameterType.GetProperties(
BindingFlags.Instance | BindingFlags.Public).OrderBy(x => x.MetadataToken)
.Select(p => p.GetCustomAttribute<JsonPropertyAttribute>());
csvString.AppendLine(string.Join(",", propInfos.Select(x => x.PropertyName)));
var counter = 1;
foreach (var item in users)
{
PropertyInfo[] props = item.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).OrderBy(x => x.MetadataToken).ToArray();
props[0].SetValue(item, Convert.ChangeType(counter , props[0].PropertyType, CultureInfo.InvariantCulture), null);
string commaSeperatedValues = string.Join(",", props.Select(prop => "\"" Convert.ToString(prop.GetValue(item), CultureInfo.InvariantCulture) "\""));
csvString.AppendLine(commaSeperatedValues);
}
var test = new UTF8Encoding(false).GetBytes(csvString.ToString());
return File(test, "text/csv", "UsersList.csv");
}
CodePudding user response:
The problem is:
Excel can't open Unicode files without a BOM (Byte Order Mark).
It will open them as Ansi files, which will show unicode characters as garbage.
Since you're using Encoding.GetBytes()
there will never be a BOM.
To get a BOM, you must use StreamWriter
.
You can fix that by replacing the last 2 lines by this:
using (MemoryStream ms = new())
{
using (StreamWriter sw = new(ms, new UTF8Encoding(true)))
{
sw.Write(csvString);
}
}
return File(ms, "text/csv", "UsersList.csv");
Now there should be a BOM and Excel should be able to to open it correctly.