export dataset to excel using c# (Mvc) - c#

I tried to export the dataset which have 2 tables to the excel sheet, unfortunately I can't.
I have code to export data table to excel. So instead of dataset, I called the ExportToExcel function which I have in my code to export datatable to excel 4 times. But once it created the first sheet, it stops the control flow. Control doesn't call the second function
ExportToExcel(getReports.Tables[1], "ConsumerBookedSlots");
Here is the code:
public ActionResult GetCuratorsAvailability(string availabilitydate)
{
string fromDate = "";
string endDate = "";
if (availabilitydate != "")
{
fromDate = availabilitydate.Split('-')[0];
endDate = availabilitydate.Split('-')[1];
if (DateTime.Parse(endDate) >= DateTime.Parse(fromDate))
{
DataSet getReports = AdminBLL.GetCuratorsAvailability(fromDate, endDate);
ExportToExcel(getReports.Tables[0], "CuratorsAvailableSlots");
ExportToExcel(getReports.Tables[1], "ConsumerBookedSlots");
}
}
return View("Reports");
}
public void ExportToExcel(DataTable dt, string FileName)
{
if (dt.Rows.Count > 0)
{
if (System.Web.HttpContext.Current.Response.RedirectLocation == null)
{
string filename = FileName + ".xls";
System.IO.StringWriter tw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
DataGrid dgGrid = new DataGrid();
dgGrid.DataSource = dt;
dgGrid.DataBind();
//Get the HTML for the control.
dgGrid.RenderControl(hw);
//Write the HTML back to the browser.
//Response.ContentType = application/vnd.ms-excel;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename + "");
Response.ContentType = "application/vnd.ms-excel";
Response.Write(tw.ToString());
Response.Flush();
Response.End();
}
}
}
I am unable to download getReports.Tables[1] data because I am getting this error:
server cannot append header after http headers have been sent. mvc
And it is downloading firstfile after error in the browser.

After the download of the first file, the execution hits this line-
Response.End();
That means, the response is ended, and headers have been sent to the client. There's no way you can initiate the download of the second file. If you want to download multiple files in a single button click, you need to zip it into one, and then initiate the download.
To zip the files you can do this-
using System;
using System.IO;
using System.IO.Compression;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
string extractPath = #"c:\example\extract";
ZipFile.CreateFromDirectory(startPath, zipPath);
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
}
}
Snippet from here.
If you want to make both excel spreadsheets a part of single excel document by putting each one of them as a worksheet, you can use ClosedXML.

I've used ClosedXML (an OpenXML implementation) several times, including in an ASP.NET MVC application and it works like a charm.
Exporting data is a breeze:
using (var memoryStream = new MemoryStream())
{
using (XLWorkbook workbook = new XLWorkbook())
{
using (IXLWorksheet worksheet = workbook.AddWorksheet("WorksheetName"))
{
var toExport = GetData();
worksheet.Row(1).Style.Font.Bold = true;
worksheet.Cell(1, 1).Value = "Column 1";
worksheet.Cell(1, 2).Value = "Column 2";
worksheet.Cell(1, 3).Value = "Column 3";
// Export the data and set some properties
worksheet.Cell(2, 1).Value = toExport.AsEnumerable();
worksheet.RangeUsed().SetAutoFilter();
worksheet.Columns().AdjustToContents();
workbook.SaveAs(memoryStream);
memoryStream.Position = 0;
return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "filename.xlsx");
}
}
}

Related

Export to Excel in ASP.Net Core 2.0

I used to export data to excel in asp.net mvc using below code
Response.AppendHeader("content-disposition", "attachment;filename=ExportedHtml.xls");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.ms-excel";
this.EnableViewState = false;
Response.Write(ExportDiv.InnerHtml);
Response.End();
When this Code Run it create a file and ask for a location to save
I tried working with NPOI and create Excel file very well but cant save file on client location .
Is there any way to make above code works on asp.net core 2.0 or any other way where I can save data in excel format on client machine ?
There are many ways to achieve that.
Option 1: save to wwwroot
You can generate the Excel and save it to the wwwroot folder. And then you can serve it as static content on the page.
For example you have a folder called 'temp' inside the wwwroot folder to contain all the newly generated excels.
<a href="\temp\development\user1\2018\5\9\excel1.xlsx" download>Download</a>
There are limitations on this approach. 1 of them is the new download attribute. It only works on modern browsers.
Option 2: byte array
Another way is to generate the Excel, convert it into byte array and send it back to the controller. For that I use a library called "EPPlus" (v: 4.5.1) which supports .Net Core 2.0.
The following is just some sample codes I put together to give you an idea. It's not production ready.
using OfficeOpenXml;
using OfficeOpenXml.Style;
namespace DL.SO.Web.UI.Controllers
{
public class ExcelController : Controller
{
public IActionResult Download()
{
byte[] fileContents;
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
// Put whatever you want here in the sheet
// For example, for cell on row1 col1
worksheet.Cells[1, 1].Value = "Long text";
worksheet.Cells[1, 1].Style.Font.Size = 12;
worksheet.Cells[1, 1].Style.Font.Bold = true;
worksheet.Cells[1, 1].Style.Border.Top.Style = ExcelBorderStyle.Hair;
// So many things you can try but you got the idea.
// Finally when you're done, export it to byte array.
fileContents = package.GetAsByteArray();
}
if (fileContents == null || fileContents.Length == 0)
{
return NotFound();
}
return File(
fileContents: fileContents,
contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
fileDownloadName: "test.xlsx"
);
}
}
}
Agreed with David Liang's answer.
Slide modifications if want to export whole DataTable.
string export="export";
DataTable dt = new DataTable();
//Fill datatable
dt = *something*
byte[] fileContents;
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add(export);
worksheet.Cells["A1"].LoadFromDataTable(dt, true);
fileContents = package.GetAsByteArray();
}
if (fileContents == null || fileContents.Length == 0)
{
return NotFound();
}
return File(
fileContents: fileContents,
contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
fileDownloadName: export + ".xlsx"
);
Here is our solution to this:
using OfficeOpenXml;
public class XmlService
{
// [...]
public void getXlsxFile(SomeTableObject tbl, ref byte[] bytes)
{
using (ExcelPackage pck = new ExcelPackage())
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add(tbl.name);
ws.Cells["A1"].LoadFromDataTable(tbl, true);
bytes = pck.GetAsByteArray();
}
}
}
More information on EPPlus is available here and the source code above can be found at our open source repo (GPL).
Just use this code instead of your own:
Response.Clear();
Response.ContentType = "application/vnd.ms-excel";
Response.Headers[HeaderNames.ContentDisposition] = "attachment; filename=ExportedHtml.xls";
Response.WriteAsync(sb.ToString()).Wait();

Export data as CSV with line breaks

I'm trying to export data as a CSV file in C#, but the problems starts when i'm trying to import the csv file in excel.
In excel I'm using the function "import from text", and afterwards I set the delimiter to semicolon
My problem is that some of the columns have linebreaks and then the import in excel is wrong.
I have tried with single and doubles quotes with no luck.
I have searched for a solution, but has not found one yet.
Anyone knows if lumenworks has a export function, because i'm using this for the import function
The problem is the export function and the linebreaks are required.
if (list.Any())
{
result = list.Select(i => new
{
i.Product.ProductIdentifier,
i.Product.Header,
body = string.Format("\"" + "{0}" + "\"", i.Product.Body),
Active = i.Product.Active ? 1 : 0,
Approved = i.Product.Approved ? 1 : 0,
i.Product.Sort,
i.Product.MetaDescription,
i.Product.MetaKeywords,
i.CatalogMenuItemContentItemId
}).ToList().ToCsv(";");
}
string attachment = "attachment; filename=myfile.csv";
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("content-disposition", attachment);
HttpContext.Current.Response.ContentType = "text/csv";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
HttpContext.Current.Response.Write(result);
HttpContext.Current.Response.End();
public static string ToCsv<T>(this IEnumerable<T> items, string seperator = ",")
where T : class
{
var csvBuilder = new StringBuilder();
var properties = typeof(T).GetProperties();
foreach (T item in items)
{
string line = string.Join(seperator, properties.Select(p => p.GetValue(item, null).ToCsvValue()).ToArray());
csvBuilder.AppendLine(line);
}
return csvBuilder.ToString();
}
private static string ToCsvValue<T>(this T item)
{
return string.Format("{0}", HttpUtility.HtmlDecode(item.ToString()));
}
Any idea ?

How to create and write Excel .xls file using C#

I have few tests which run three times and there average is calculated through c# code.I am able to write the three test times and there average to the xls file if created before in the below picture format . But now I have to run each test every hour everyday through a batch file using windows scheduler. I want to create the xls file dynamically in every hour in below mentioned format with a specific name so that at the first iteration the file is created and for next 19 iteration it should write in the same file then next hour new file created with a specific name.How to create and write the excel file dynamically ?????
If there is any other simple procedure plz suggest that. The code which I was using to write in already created xls file is :`/*
using System;
using System.IO;
using Ranorex;
namespace PEPI_Performance.Utility
{
/// <summary>
/// Description of ExcelWriter.
/// </summary>
public class ExcelWriter
{
/// <summary>
/// Constructs a new instance.
/// </summary>
public ExcelWriter()
{
// Do not delete - a parameterless constructor is required!
}
public void Driver(int row , int col, string time, string sheetName){
string sDataFile = "Ranorex_Reports.xls";
string sFilePath = Path.GetFullPath(sDataFile);
string sOldvalue = "Automation\\bin\\Debug\\" + sDataFile;
sFilePath = sFilePath.Replace(sOldvalue,"")+
"PEPI_Performance\\ExecutionReport\\" + sDataFile;
fnOpenExcel(sFilePath,sheetName);
writeExcel(row,col,time);
fnCloseExcel();
}
Excel.Application exlApp ;
Excel.Workbook exlWB ;
Excel.Sheets excelSheets ;
Excel.Worksheet exlWS;
//Open Excel file
public int fnOpenExcel(string sPath, string iSheet){
int functionReturnValue = 0;
try {
exlApp = new Excel.ApplicationClass();
exlApp.Visible = true;
exlWB=
exlApp.Workbooks.Open(sPath,Type.Missing,Type.Missing,
Type.Missing,Type.Missing,Type.Missing,Type.Missing,
Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing);
// get all sheets in workbook
excelSheets = exlWB.Worksheets;
// get some sheet
//string currentSheet = "Cycle1";
exlWS = (Excel.Worksheet)excelSheets.get_Item(iSheet);
functionReturnValue = 0;
}
catch (Exception ex) {
functionReturnValue = -1;
Report.Error(ex.Message);
}
return functionReturnValue;
}
// Close the excel file and release objects.
public int fnCloseExcel(){
//exlWB.Close();
try{
exlApp.ActiveWorkbook.Save();
exlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(exlWS);
System.Runtime.InteropServices.Marshal.ReleaseComObject(exlWB);
System.Runtime.InteropServices.Marshal.ReleaseComObject(exlApp);
GC.GetTotalMemory(false);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.GetTotalMemory(true);
}catch(Exception ex){
Report.Error(ex.Message);
}
return 0;
}
public void writeExcel(int i, int j , string time){
Excel.Range exlRange = null;
exlRange = (Excel.Range)exlWS.UsedRange;
((Excel.Range)exlRange.Cells[i,j]).Formula = time;
}
}
}
`
In all honesty you might be better off using a csv file, that way from your ranorex tests you can simply use system.IO.File to write the output text to the file, and the nice thing about the csv format is it can then be opened in excel
There is a way to handle this using a data grid.
The example below accepts a DataSet (you could pass a list or table).
Then on the FLY a GridView is created and exported to Excel. I use this method on many sites.
public static void ExportDataSetToExcel(DataSet ds, string filename)
{
try
{
HttpResponse response = HttpContext.Current.Response;
// first let's clean up the response.object
response.Clear();
response.Charset = "";
// set the response mime type for excel
response.ContentType = "application/vnd.ms-excel";
response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
// create a string writer
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
// instantiate a datagrid
DataGrid dg = new DataGrid();
dg.DataSource = ds;
dg.DataBind();
dg.RenderControl(htw);
response.Write(sw.ToString());
response.End();
}
}
}
catch { }
}

Export a System.Web.UI.WebControls.Datagrid to an Excel file in C#? [duplicate]

whats the best way to export a Datagrid to excel? I have no experience whatsoever in exporting datagrid to excel, so i want to know how you guys export datagrid to excel.
i read that there are a lot of ways, but i am thinking to just make a simple export excel to datagrid function.i am using asp.net C#
cheers..
The simplest way is to simply write either csv, or html (in particular, a <table><tr><td>...</td></tr>...</table>) to the output, and simply pretend that it is in excel format via the content-type header. Excel will happily load either; csv is simpler...
Here's a similar example (it actually takes an IEnumerable, but it would be similar from any source (such as a DataTable, looping over the rows).
public static void WriteCsv(string[] headers, IEnumerable<string[]> data, string filename)
{
if (data == null) throw new ArgumentNullException("data");
if (string.IsNullOrEmpty(filename)) filename = "export.csv";
HttpResponse resp = System.Web.HttpContext.Current.Response;
resp.Clear();
// remove this line if you don't want to prompt the user to save the file
resp.AddHeader("Content-Disposition", "attachment;filename=" + filename);
// if not saving, try: "application/ms-excel"
resp.ContentType = "text/csv";
string csv = GetCsv(headers, data);
byte[] buffer = resp.ContentEncoding.GetBytes(csv);
resp.AddHeader("Content-Length", buffer.Length.ToString());
resp.BinaryWrite(buffer);
resp.End();
}
static void WriteRow(string[] row, StringBuilder destination)
{
if (row == null) return;
int fields = row.Length;
for (int i = 0; i < fields; i++)
{
string field = row[i];
if (i > 0)
{
destination.Append(',');
}
if (string.IsNullOrEmpty(field)) continue; // empty field
bool quote = false;
if (field.Contains("\""))
{
// if contains quotes, then needs quoting and escaping
quote = true;
field = field.Replace("\"", "\"\"");
}
else
{
// commas, line-breaks, and leading-trailing space also require quoting
if (field.Contains(",") || field.Contains("\n") || field.Contains("\r")
|| field.StartsWith(" ") || field.EndsWith(" "))
{
quote = true;
}
}
if (quote)
{
destination.Append('\"');
destination.Append(field);
destination.Append('\"');
}
else
{
destination.Append(field);
}
}
destination.AppendLine();
}
static string GetCsv(string[] headers, IEnumerable<string[]> data)
{
StringBuilder sb = new StringBuilder();
if (data == null) throw new ArgumentNullException("data");
WriteRow(headers, sb);
foreach (string[] row in data)
{
WriteRow(row, sb);
}
return sb.ToString();
}
You can do it in this way:
private void ExportButton_Click(object sender, System.EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "";
this.EnableViewState = false;
System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
this.ClearControls(dataGrid);
dataGrid.RenderControl(oHtmlTextWriter);
Response.Write(oStringWriter.ToString());
Response.End();
}
Complete example here.
SpreadsheetGear for .NET will do it.
You can see live ASP.NET samples with C# and VB source code here. Several of these samples demonstrate converting a DataSet or DataTable to Excel - and you can easily get a DataSet or DataTable from a DataGrid. You can download the free trial here if you want to try it yourself.
Disclaimer: I own SpreadsheetGear LLC

export Datagrid to excel asp

whats the best way to export a Datagrid to excel? I have no experience whatsoever in exporting datagrid to excel, so i want to know how you guys export datagrid to excel.
i read that there are a lot of ways, but i am thinking to just make a simple export excel to datagrid function.i am using asp.net C#
cheers..
The simplest way is to simply write either csv, or html (in particular, a <table><tr><td>...</td></tr>...</table>) to the output, and simply pretend that it is in excel format via the content-type header. Excel will happily load either; csv is simpler...
Here's a similar example (it actually takes an IEnumerable, but it would be similar from any source (such as a DataTable, looping over the rows).
public static void WriteCsv(string[] headers, IEnumerable<string[]> data, string filename)
{
if (data == null) throw new ArgumentNullException("data");
if (string.IsNullOrEmpty(filename)) filename = "export.csv";
HttpResponse resp = System.Web.HttpContext.Current.Response;
resp.Clear();
// remove this line if you don't want to prompt the user to save the file
resp.AddHeader("Content-Disposition", "attachment;filename=" + filename);
// if not saving, try: "application/ms-excel"
resp.ContentType = "text/csv";
string csv = GetCsv(headers, data);
byte[] buffer = resp.ContentEncoding.GetBytes(csv);
resp.AddHeader("Content-Length", buffer.Length.ToString());
resp.BinaryWrite(buffer);
resp.End();
}
static void WriteRow(string[] row, StringBuilder destination)
{
if (row == null) return;
int fields = row.Length;
for (int i = 0; i < fields; i++)
{
string field = row[i];
if (i > 0)
{
destination.Append(',');
}
if (string.IsNullOrEmpty(field)) continue; // empty field
bool quote = false;
if (field.Contains("\""))
{
// if contains quotes, then needs quoting and escaping
quote = true;
field = field.Replace("\"", "\"\"");
}
else
{
// commas, line-breaks, and leading-trailing space also require quoting
if (field.Contains(",") || field.Contains("\n") || field.Contains("\r")
|| field.StartsWith(" ") || field.EndsWith(" "))
{
quote = true;
}
}
if (quote)
{
destination.Append('\"');
destination.Append(field);
destination.Append('\"');
}
else
{
destination.Append(field);
}
}
destination.AppendLine();
}
static string GetCsv(string[] headers, IEnumerable<string[]> data)
{
StringBuilder sb = new StringBuilder();
if (data == null) throw new ArgumentNullException("data");
WriteRow(headers, sb);
foreach (string[] row in data)
{
WriteRow(row, sb);
}
return sb.ToString();
}
You can do it in this way:
private void ExportButton_Click(object sender, System.EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "";
this.EnableViewState = false;
System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
this.ClearControls(dataGrid);
dataGrid.RenderControl(oHtmlTextWriter);
Response.Write(oStringWriter.ToString());
Response.End();
}
Complete example here.
SpreadsheetGear for .NET will do it.
You can see live ASP.NET samples with C# and VB source code here. Several of these samples demonstrate converting a DataSet or DataTable to Excel - and you can easily get a DataSet or DataTable from a DataGrid. You can download the free trial here if you want to try it yourself.
Disclaimer: I own SpreadsheetGear LLC

Categories

Resources