Hi Team,
I'm not sure where I can send this bug to you guys. And tbh, i'm not really sure if it's a bug or not, but this is what happened.
I have followed this guide to try export to csv file: Blazor DataGrid Component - Export to Excel and CSV | Free UI Components by Radzen
In ExportController.cs, we have this :
public FileStreamResult ToCSV(IQueryable query, string fileName = null)
{
var columns = GetProperties(query.ElementType);
var sb = new StringBuilder();
foreach (var item in query)
{
var row = new List<string>();
foreach (var column in columns)
{
row.Add($"{GetValue(item, column.Key)}".Trim());
}
sb.AppendLine(string.Join(",", row.ToArray()));
}
var result = new FileStreamResult(new MemoryStream(UTF8Encoding.Default.GetBytes($"{string.Join(",", columns.Select(c => c.Key))}{System.Environment.NewLine}{sb.ToString()}")), "text/csv");
result.FileDownloadName = (!string.IsNullOrEmpty(fileName) ? fileName : "Export") + ".csv";
return result;
}
If we use the previous code, In some very rare cases:
If a field value is : this is my cat , dog and mouse, the csv parse will interpret that as two fields , not one, resulting in :
Column A: this is my cat
Column B : dog and mouse.
Basically, in csv format, each field is separated by a comma, if a field itself contains a comma, then it must be enclosed in double quote.
I have fixed the issue with this code
public FileStreamResult ToCSV(IQueryable query, string fileName = null)
{
var columns = GetProperties(query.ElementType);
var sb = new StringBuilder();
foreach (var item in query)
{
var row = new List<string>();
foreach (var column in columns)
{
var rawValue = $"{GetValue(item, column.Key)}".Trim();
if (rawValue.Contains(",") || rawValue.Contains("\"") || rawValue.Contains("\n"))
{
rawValue = $"\"{rawValue.Replace("\"", "\"\"")}\"";
}
row.Add(rawValue);
}
sb.AppendLine(string.Join(",", row));
}
var header = string.Join(",", columns.Select(c =>
{
var col = c.Key;
return col.Contains(",") ? $"\"{col}\"" : col;
}));
var result = new FileStreamResult(
new MemoryStream(Encoding.UTF8.GetBytes($"{header}{Environment.NewLine}{sb}")),
"text/csv"
);
result.FileDownloadName = (!string.IsNullOrEmpty(fileName) ? fileName : "Export") + ".csv";
return result;
}}