Tuesday, May 29, 2012

C#Asp.net MVC Export CSV ActionResult

Exporting Csv format at MVC is extremely easy. In fact, with clean codes. My scenario: Lead data stores in a database. From the one click event which named download will pop out csv file to download.

The following code I found on develoq.net blog which is very useful. Literally, just drop that in and call it in actionresult from controller page.

   1:   public sealed class CsvActionResult : FileResult
   2:      {
   3:          private readonly DataTable dataTable;
   4:          public CsvActionResult(DataTable dataTable)
   5:              : base("text/csv")
   6:          {
   7:              this.dataTable = dataTable;
   8:          }
   9:   
  10:          protected override void WriteFile(HttpResponseBase response)
  11:          {
  12:              var outputStream = response.OutputStream;
  13:              using (var memoryStream = new MemoryStream())
  14:              {
  15:                  WriteDataTable(memoryStream);
  16:                  outputStream.Write(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
  17:              }
  18:          }
  19:   
  20:          private void WriteDataTable(Stream stream)
  21:          {
  22:              var streamWriter = new StreamWriter(stream, Encoding.Default);
  23:   
  24:              WriteHeaderLine(streamWriter);
  25:              streamWriter.WriteLine();
  26:              WriteDataLines(streamWriter);
  27:   
  28:              streamWriter.Flush();
  29:          }
  30:          
  31:          private void WriteHeaderLine(StreamWriter streamWriter)
  32:          {
  33:              foreach (DataColumn dataColumn in dataTable.Columns)
  34:              {
  35:                  WriteValue(streamWriter, dataColumn.ColumnName);
  36:              }
  37:          }
  38:   
  39:          private void WriteDataLines(StreamWriter streamWriter)
  40:          {
  41:              foreach (DataRow dataRow in dataTable.Rows)
  42:              {
  43:                  foreach (DataColumn dataColumn in dataTable.Columns)
  44:                  {
  45:                      WriteValue(streamWriter, dataRow[dataColumn.ColumnName].ToString());
  46:                  }
  47:                  streamWriter.WriteLine();
  48:              }
  49:          }
  50:   
  51:          private static void WriteValue(StreamWriter writer, String value)
  52:          {
  53:              writer.Write("\"");
  54:              writer.Write(value.Replace("\"", "\"\""));
  55:              writer.Write("\",");
  56:          }
  57:   
  58:      }

Using by Datatable to manipulate data to display in Excel sheet. The following actionresult to fire when the download button clicked. And you can see how to read the model to datatable dynamically.

You can see the first loop is for table column name to display. And I use another loop to populate the data to right column.

   1:   [HttpPost]
   2:          public ActionResult Report(int formId)
   3:          {
   4:              DataTable table = new DataTable();
   5:              var formFieldList = formFieldRepo.Where(m => m.FormId == formId);
   6:              var formEntries = formEntryRepo.Where(m => m.FormId == formId);
   7:   
   8:              foreach (var item in formFieldList)
   9:              {
  10:                  table.Columns.Add(item.Title, typeof(string));
  11:                  //string[] rows = item.valu
  12:              }
  13:   
  14:              foreach (var item in formEntries)
  15:              {
  16:                  string[] rows = item.Value.Split(',');
  17:   
  18:                  DataRow dataRow = table.NewRow();
  19:                  foreach (var rowItem in rows)
  20:                  {
  21:                      if (!string.IsNullOrEmpty(rowItem))
  22:                      {
  23:                          dataRow[rowItem.Split('/').First().ToString()] = rowItem.Split('/').Last().ToString();
  24:                      }
  25:                  }
  26:                  table.Rows.Add(dataRow);
  27:              }
  28:   
  29:              return new CsvActionResult(table) { FileDownloadName = "ExportedFile.csv" };
  30:          }

Any questions and different opnions are warmly welcomed.

No comments: