Monday, March 26, 2018

Exporting a CSV generated in-memory in Asp.Net with C#

Last week we discussed how to import CSVs easily using .Net and C#. Today we continue discussing CSVs but now on the other direction: how to generate and export CSVs directly from your database to your users from via a web application.

Sometimes we need to build CSVs on the fly, sourced from the database, and export those records to our users. That happens regardless if you're using a Sql or a NoSql database. Users just need to have their data in their hands. Frequently, the format utilized is CSV.

Obviously there's ways and ways to do it. What you shouldn't do though is to try to create your own CSV parser. Please, don't! Let's use the good stuff that other people made available for us for free like the very good CsvHelper Nuget Package. I've been using that package for a few years already and it has exceeded my expectations so I hope it helps you too.

Let's do Code then!

Enough of talk, let's do some code. I expect to do this in 4 steps (code follows):
  1. Add a reference to the CsvHelper nuget package in your Asp.Net project (which you saw on last week's post);
  2. Grab your records form the database
  3. Build your Csv in-memory;
  4. Format the response, write to it, set an arbitrary file name and return;


That's it! simple as it can be.

Some notes:

  • Lines 12-16: RavenDB is loading the data for me using an index;
  • Line 15: I'm converting between my db entity (BatchRow) to my view model (CsvLine);
  • Line 26: CSVHelper is doing the magic for us. It's better when it's simple!
  • Line 31: I'm formatting the file name;
  • Line 33: Writing the the response stream;
  • Line 34: closing the response stream;

Don't forget to Refactor

As I have a constant desire to make my code as clean as possible, I usually review my code before committing and pushing. If there is bloat there, I usually refactor it, making use of my tests to help me refactor with confidence.

Remember: if the code is bloated, the performance is below acceptable or if you are not satisfied with the solution, consider refactoring or changing how you architected your solution in the first place.

Final Thoughts

If it's a lot of data that you're required to export, maybe you want to stream it to the users, maybe you want to process it in the backend (or in a WebJob) and email it back to your users or even pre-generate the report and just serve it on the click of the download button.

Also consider that depending on your use cases, this code is yes, too simplistic. But that's the objective. We should never implement what we don't need, yet.

See how all those acronyms make sense?

Hope it helps!