I have a very old asp.net application that uses C# .Net and JQuery Mobile, and I need to add 1 feature: Export a list of data to a csv file. Thus far, I have the UI stuff sorted out. I have a jquery button that passes a parameter in the request query string to indicate on page load that we need to export data to Excel. I also have the following C# in the page load event. Unfortunately, when I run this code in Visual Studio with Chrome (or any browser), I do not get a prompt to save the csv file. When I run it with IE, I get the following error:
"Unhandled exception at line 2371, column 4 in http://localhost:53748/js/libs/jquery-mobile/jquery.mobile-1.0a4.1.js
0x800a138f - Javascript runtime error:Unable to get property '_trigger' of undefined or null reference."
I'm not sure if I am handling everything with the response object correctly.
if (Request.QueryString["isExportToExcelRequired"] == "true")
{
StringWriter sw = new StringWriter();
sw.WriteLine("\"ItemID\",\"Description\",\"Price\"");
if (MasterList.Count > 0)
{
for (int i = 0; i < MasterList.Count; i++)
{
sw.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\"",
MasterList[i].item.ItemID,
MasterList[i].item.ItemDesc,
MasterList[i].P0
));
}
string fileName = string.Format("{0}_{1}", SubClassID, DateTime.UtcNow.ToString("dd-MM-yyyy"));
// Write response.
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment;filename=" + fileName + ".csv");
Response.ContentType = "text/csv";
Response.Write(sw.ToString());
Response.End();
}
}
I'd use csvHelper. It's a handy library. It's been around since 2009 so I'd imagine your application isn't too old to benefit from this library. Below is a basic example of going from List to CSV.
The error you're getting is because something that shouldn't be NULL is indeed NULL. Run it in visual studio and let it throw the exception. Go through the debugger and find what's NULL then go through the logic and discover why it didn't get set to a value.
void Export()
{
using (var stream = new MemoryStream())
using (var reader = new StreamReader(stream))
using (var writer = new StreamWriter(stream))
using (var csv = new CsvWriter(writer))
{
foreach (var item in MasterList)
{
foreach (var field in item)
{
csv.WriteField(field);
}
csv.NextRecord();
}
writer.Flush();
stream.Position = 0;
reader.ReadToEnd().Dump();
}
}
The problem with writing the values as you have is what happens if one of the values contains a comma? The NuGet package I use for this is SoftCircuits.CsvParser. I found it to average about four times faster than CsvHelper.
It even supports column values that span multiple lines and has some other advanced features.
I was able to get this working by handling the csv export in the aspx page with a Javascript function. Here's what the solution looks like:
A button control that calls the "download_csv" function in the onclick event:
<button onclick="download_csv('<%= HttpUtility.JavaScriptStringEncode(csvExport)%>')">Download CSV</button>
Note: csvExport is a publicly declared C# variable from the code behind that is filled with the comma separated data on page load - using C# to handle the formatting of the data, etc.
And this Javascript function to instantiate a hidden element and bind the href type, target, and file name, and then fire the click event, thus starting the export/download.
function download_csv(priceExport) {
console.log(priceExport);
var hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(priceExport);
hiddenElement.target = '_blank';
hiddenElement.download = 'pricing.csv';
hiddenElement.click();
}
Tested with Chrome and it works like a champ. Doesn't work with IE, but I'm not too concerned about that right now.
User contributions licensed under CC BY-SA 3.0