I'm using Blazor Server in .net 8. I'm am trying to save a CSV file and am using jitbit/CsvExport to do it. The issue is that additional characters are being added to the first entry.
My razor.cs file looks like this:
private async Task ExportToCSV()
{
var myExport = new CsvExport(includeColumnSeparatorDefinitionPreamble: false, includeHeaderRow: false);
myExport.AddRow();
myExport["Directions"] = "Directions";
myExport["Leg"] = "Leg";
myExport["LegTime"] = "Leg Time";
myExport["Trip"] = "Trip";
myExport["TripTime"] = "Trip Time";
foreach (var direction in LoadedDrivingDirections)
{
var row = new object[5]
{
$"{direction.Maneuver} on {direction.Road}",
direction.LegDistance.ToString("0.00"),
TimeSpan.FromMinutes(direction.Time).ToString(@"hh\:mm"),
direction.DistanceAtStart.ToString("0.00"),
TimeSpan.FromMinutes(drivingDirectionViews.Where(w => w.Direction.Latitude == direction.Latitude).Select(s => s.TotalTime).FirstOrDefault()).ToString(@"hh\:mm")
};
myExport.AddRow();
myExport["Directions"] = row[0];
myExport["Leg"] = row[1];
myExport["LegTime"] = row[2];
myExport["Trip"] = row[3];
myExport["TripTime"] = row[4];
}
await _js.SaveAs("ProMilesTrip.csv", myExport.ExportAsMemoryStream().ToArray());
}
And my js function is as follows:
function saveAsFile(filename, bytesBase64) {
if (navigator.msSaveBlob) {
//Download document in Edge browser
var data = window.atob(bytesBase64);
var bytes = new Uint8Array(data.length);
for (var i = 0; i < data.length; i++) {
bytes[i] = data.charCodeAt(i);
}
var blob = new Blob([bytes.buffer], { type: "application/octet-stream" });
navigator.msSaveBlob(blob, filename);
}
else {
var link = document.createElement('a');
link.download = filename;
link.href = "data:application/octet-stream;base64," + bytesBase64;
document.body.appendChild(link); // Needed for Firefox
link.click();
document.body.removeChild(link);
}
}
The characters at the beginning of your CSV appear to be a byte order mark.
Since you are using jitbit/CsvExport, the method CsvExport.ExportAsMemoryStream(Encoding encoding = null)
has an optional parameter Encoding encoding
:
private readonly Encoding _defaultEncoding = Encoding.UTF8; public MemoryStream ExportAsMemoryStream(Encoding encoding = null) { MemoryStream ms = new MemoryStream(); encoding = encoding ?? _defaultEncoding;
The default value, Encoding.UTF8
:
returns a
UTF8Encoding
object that provides a Unicode byte order mark (BOM).
Since you don't want that, you should pass in your own UTF8Encoding
with the constructor parameter encoderShouldEmitUTF8Identifier
set to false
:
_js.SaveAs("ProMilesTrip.csv",
myExport.ExportAsMemoryStream(encoding : new UTF8Encoding(false)).ToArray());