Having trouble while exporting the gridview data in excel. It is exporting the whole page not Gridview data.
My Code as below :
Response.Clear();
Response.Buffer = true;
Response.ClearContent();
Response.ClearHeaders();
Response.Charset = "";
StringWriter strwritter = new StringWriter();
HtmlTextWriter htmlwritter = new HtmlTextWriter(strwritter);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/ms-excel";
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", "DSR"+DateTime.Now.ToString("dd-MM-yyyy")+".xls"));
GridView1.GridLines = GridLines.Both;
GridView1.HeaderStyle.Font.Bold = true;
GridView1.RenderControl(htmlwritter);
Response.Write(strwritter.ToString());
Response.End();
You can try doing something like that. Simple and straightforward.
Response.Clear();
Response.Buffer = true;
Response.ClearContent();
Response.ClearHeaders();
Response.Charset = "";
StringWriter strwritter = new StringWriter();
HtmlTextWriter htmlwritter = new HtmlTextWriter(strwritter);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringWriter strwritter = new StringWriter();
HtmlTextWriter htmlwritter = new HtmlTextWriter(strwritter);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/ms-excel";
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", "DSR"+DateTime.Now.ToString("dd-MM-yyyy")+".xls"));
GridView1.RenderBeginTag(htmlwritter);
GridView1.HeaderRow.RenderControl(htmlwritter);
foreach (GridViewRow row in GridView1.Rows)
{
row.RenderControl(htmlwritter);
}
GridView1.FooterRow.RenderControl(htmlwritter);
GridView1.RenderEndTag(htmlwritter);
Response.Write(strwritter.ToString());
Response.End();
A simple solution to this problem is to get your C# code to write the GridView's data source to an Excel file.
Here's the C# library I wrote to do exactly that:
Export to Excel
All source code is provided free of charge, and you just need to add a few lines to your ASP.Net code:
// The following ASP.Net code gets run when I click on my "Export to Excel" button.
protected void btnExportToExcel_Click(object sender, EventArgs e)
{
// It doesn't get much easier than this...
CreateExcelFile.CreateExcelDocument(listOfEmployees, "Employees.xlsx", Response);
}
The other advantage of this is that it'll create a "real" .xlsx file (using the OpenDocument library). The downside is that those Microsoft libraries weigh-in at about 5Mb.
Try this,it will work..
private void Export_To_Excel()
{
Microsoft.Office.Interop.Excel._Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = excel.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
try
{
worksheet = workbook.ActiveSheet;
worksheet.Name = "ExportedFromDatGrid";
int cellRowIndex = 1;
int cellColumnIndex = 1;
////Loop through each row and read value from each column.
for (int i = 0; i < this.dGV.Rows.Count - 1; i++)
{
for (int j = 0; j < this.dGV.Columns.Count; j++)
{
//// Excel index starts from 1,1. As first Row would have the Column headers, adding a condition check.
if (cellRowIndex == 1)
{
worksheet.Cells[cellRowIndex, cellColumnIndex] = this.dGV.Columns[j].HeaderText;
worksheet.Cells[cellRowIndex, cellColumnIndex].Font.FontStyle = FontStyle.Bold;
}
else
{
worksheet.Cells[cellRowIndex, cellColumnIndex] = this.dGV.Rows[i].Cells[j].Value.ToString();
}
cellColumnIndex++;
}
cellColumnIndex = 1;
cellRowIndex++;
}
worksheet.Columns.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignLeft;
worksheet.Columns.AutoFit();
////Getting the location and file name of the excel to save from user.
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx";
saveDialog.FilterIndex = 2;
if (saveDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
workbook.SaveAs(saveDialog.FileName);
MessageBox.Show("Export Successful", "Info", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
}
finally
{
excel.Quit();
workbook = null;
excel = null;
}
}
Here an example that uses EPPlus. Just input a SQL query (or stored procedure name) and a filename to exportToExcel and you'll get an Excel file.
exportToExcel("SELECT * FROM yourTable", "myFileName");
using OfficeOpenXml;
using OfficeOpenXml.Style;
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Globalization;
using System.Web;
//=== create an excel document =========================================
public static void exportToExcel(string sqlQuery, string fileName)
{
HttpResponse Response = HttpContext.Current.Response;
DataTable dt = loadExternalDataTable(sqlQuery);
using (ExcelPackage p = new ExcelPackage())
{
//create a new workbook
p.Workbook.Properties.Author = "VDWWD";
p.Workbook.Properties.Title = fileName;
p.Workbook.Properties.Created = DateTime.Now;
//create a new worksheet
p.Workbook.Worksheets.Add(fileName);
ExcelWorksheet ws = p.Workbook.Worksheets[1];
ws.Name = fileName;
ws.Cells.Style.Font.Size = 11;
ws.Cells.Style.Font.Name = "Calibri";
createExcelHeader(ws, dt);
createExcelData(ws, dt);
ws.Cells[ws.Dimension.Address].AutoFitColumns();
//make all columms just a bit wider, they would sometimes not fit
for (int col = 1; col <= ws.Dimension.End.Column; col++)
{
ws.Column(col).Width = ws.Column(col).Width + 1;
}
//send the file to the browser
byte[] bin = p.GetAsByteArray();
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-length", bin.Length.ToString());
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".xlsx\"");
Response.OutputStream.Write(bin, 0, bin.Length);
Response.Flush();
Response.Close();
Response.End();
}
}
//=== create the excel sheet header row =========================================
private static void createExcelHeader(ExcelWorksheet ws, DataTable dt)
{
int colindex = 1;
//loop all the columns
foreach (DataColumn dc in dt.Columns)
{
var cell = ws.Cells[1, colindex];
//make the text bold
cell.Style.Font.Bold = true;
//make the background of the cell gray
var fill = cell.Style.Fill;
fill.PatternType = ExcelFillStyle.Solid;
fill.BackgroundColor.SetColor(ColorTranslator.FromHtml("#BFBFBF"));
//fill the cell with the text
cell.Value = dc.ColumnName.ToUpper();
colindex++;
}
}
//=== create the excel sheet data =========================================
private static void createExcelData(ExcelWorksheet ws, DataTable dt)
{
int colindex = 0;
int rowindex = 1;
//loop all the rows
foreach (DataRow dr in dt.Rows)
{
colindex = 1;
rowindex++;
//loop all the columns
foreach (DataColumn dc in dt.Columns)
{
var cell = ws.Cells[rowindex, colindex];
string datatype = dc.DataType.ToString();
//fill the cell with the data in the correct format, needs to be done here because the headder row makes every column a string otherwise
if (datatype == "System.Decimal" || datatype == "System.Double" || datatype == "System.Float")
{
if (!string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
cell.Value = Convert.ToDecimal(dr[dc.ColumnName]);
cell.Style.Numberformat.Format = "0.00";
}
else if (datatype == "System.Int16" || datatype == "System.Int32" || datatype == "System.Int64" || datatype == "System.Long")
{
if (!string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
cell.Value = Convert.ToInt64(dr[dc.ColumnName]);
}
else if (datatype == "System.Bool" || datatype == "System.Boolean")
{
if (!string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
cell.Value = Convert.ToBoolean(dr[dc.ColumnName]); ;
}
else if (datatype == "System.DateTime")
{
if (!string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
cell.Value = Convert.ToDateTime(dr[dc.ColumnName]);
cell.Style.Numberformat.Format = DateTimeFormatInfo.CurrentInfo.ShortDatePattern;
}
else
{
cell.Value = dr[dc.ColumnName];
}
colindex++;
}
}
}
//=== create a datatable from a query =========================================
public static DataTable loadExternalDataTable(string sqlQuery)
{
DataTable dt = new DataTable();
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString()))
using (SqlDataAdapter adapter = new SqlDataAdapter(sqlQuery, connection))
{
try
{
adapter.Fill(dt);
}
catch
{
}
}
return dt;
}
This code may be help you
protected void btnExportExcel_Click(object sender, EventArgs e)
{
BindData();
GridView1.Visible = true;
string FileName = "Deal Report_(" + DateTime.Now.AddHours(5).ToString("yyyy-MM-dd") + ").xls";
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition",
"attachment;filename=" + FileName);
Response.Charset = "";
Response.ContentType = "application/vnd.ms-excel";
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
GridView1.HeaderRow.Style.Add("color", "#FFFFFF");
GridView1.HeaderRow.Style.Add("background-color", "#1F437D");
for (int i = 0; i < GridView1.Rows.Count; i++)
{
GridViewRow row = GridView1.Rows[i];
row.BackColor = System.Drawing.Color.White;
row.Attributes.Add("class", "textmode");
if (i % 2 != 0)
{
for (int j = 0; j < row.Cells.Count; j++)
{
//row.Cells[j].Style.Add("background-color", "#eff3f8");
}
}
}
GridView1.RenderControl(hw);
string style = #"<style> .textmode { mso-number-format:\#; } </style>";
Response.Write(style);
Response.Output.Write(sw.ToString());
Response.End();
GridView1.Visible = false;
}
Related
I'm working on a legacy system that has export to excel function from database to excel sheet.
the problem was that empty cells was showing symbols and i fixed it . Now the other problem , inside a single cell i found encoding symbols and i tried a lot of solutions and it still there .
My code :
else if (ddl_excel_type.SelectedValue == "1")
{
GridView1.PagerSettings.Visible = false;
//To Export all pages
GridView1.AllowPaging = false;
GridView1.DataBind();
// GridView1.HeaderRow.BackColor = Color.White;
DataTable dt = new DataTable("GridView_Data");
//DataTable dtDetails = new DataTable("GridView_Details_Data");
this.GetAllRisks();
foreach (TableCell cell in GridView1.HeaderRow.Cells)
{
dt.Columns.Add(cell.Text);
// cell.BackColor = GridView1.HeaderStyle.BackColor;
}
GridView GridView2 = (GridView)GridView1.Rows[0].FindControl("GridView2");
GridView2.PagerSettings.Visible = false;
//To Export all pages
GridView2.AllowPaging = false;
GridView2.DataBind();
//controls
if (GridView2.Rows.Count > 0)
{
foreach (TableCell cell in GridView2.HeaderRow.Cells)
{
dt.Columns.Add(cell.Text);
// cell.BackColor = GridView1.HeaderStyle.BackColor;
}
}
dt.Columns.RemoveAt(0);
foreach (GridViewRow row in GridView1.Rows)
{
GridView gvOrderscell = (row.FindControl("GridView2") as GridView);
if (GridView2.Rows.Count > 0)
{
for (int j = 0; j < gvOrderscell.Rows.Count; j++)
{
dt.Rows.Add(row.Cells[1].Text, row.Cells[2].Text, row.Cells[3].Text, row.Cells[4].Text, row.Cells[5].Text, row.Cells[6].Text,
row.Cells[7].Text, row.Cells[8].Text, row.Cells[9].Text, row.Cells[10].Text, row.Cells[11].Text, row.Cells[12].Text,
row.Cells[13].Text, row.Cells[14].Text, row.Cells[15].Text, row.Cells[16].Text, row.Cells[17].Text, row.Cells[18].Text,
row.Cells[19].Text, row.Cells[20].Text, row.Cells[21].Text, row.Cells[22].Text,
gvOrderscell.Rows[j].Cells[0].Text, gvOrderscell.Rows[j].Cells[1].Text, gvOrderscell.Rows[j].Cells[2].Text, gvOrderscell.Rows[j].Cells[3].Text, gvOrderscell.Rows[j].Cells[4].Text
);
//This is what i added for the symbols inside the cells but it didn't work
string textWithNewLine = row.Cells[j].Text.Replace("
", Environment.NewLine);
}
}
else
{
dt.Rows.Add(row.Cells[1].Text, row.Cells[2].Text, row.Cells[3].Text, row.Cells[4].Text, row.Cells[5].Text, row.Cells[6].Text,
row.Cells[7].Text, row.Cells[8].Text, row.Cells[9].Text, row.Cells[10].Text, row.Cells[11].Text, row.Cells[12].Text,
row.Cells[13].Text, row.Cells[14].Text, row.Cells[15].Text, row.Cells[16].Text, row.Cells[17].Text, row.Cells[18].Text,
row.Cells[19].Text, row.Cells[20].Text, row.Cells[21].Text, row.Cells[22].Text);
}
}
Response.Clear();
Response.Charset = "";
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment;filename= Risk and consquences.xls");
//Here we set the correct encoding so that all characters show!
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.Charset = "65001";
byte[] b = new byte[] {
0xef,
0xbb,
0xbf
};
Response.BinaryWrite(b);
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new System.Web.UI.HtmlTextWriter(stringWrite);
System.Web.UI.WebControls.DataGrid dg = new System.Web.UI.WebControls.DataGrid();
dg.DataSource = dt;
dg.DataBind();
dg.RenderControl(htmlWrite);
Response.Write(Convert.ToString( stringWrite));
//This is what i added for the symbols inside the cells removal and didn't work
stringWrite.Write("br {mso-data-placement:same-cell;}");
Response.Write(HttpUtility.HtmlDecode(Convert.ToString(stringWrite)));
Response.End();
}
Any ideas ?
You will need to write the string back to the Cell:
//This is what i added for the symbols inside the cells but it didn't work
string textWithNewLine = row.Cells[j].Text.Replace("
", Environment.NewLine);
row.Cells[j].Formula = textWithNewLine;
I am just trying to Export a Datatable (Datatable doesn't have any data - having only header). In addition, i have a List<String> which i want to append to the column, such that, after export to excel that column (all cells except header) should contain list data as Dropdown format.
I have googled a lot and couldn't able to find any solutions.
Below are the links which i have visited but no luck.
StackOverflow
Codeplex - ClosedXML
And below are the one what i have tried so far.
private void ExcelExport(DataTable dt, GridView Template)
{
bool isListRequired = false;
List<string> groupCodeList = new List<string>(); ;
Template.DataBind();
if (Template.HeaderRow != null)
{
foreach (TableCell cell in Template.HeaderRow.Cells)
{
if (cell.Text == "ActivityGroup_Code")
{
isListRequired = true;
groupCodeList = db.PMS_M_ActivityGroup.Select(a => a.ActivityGroup_Code).ToList();
}
dt.Columns.Add(cell.Text);
}
var workbook = new XLWorkbook();
var returnValue = workbook.AddWorksheet(dt);
var worksheet = workbook.Worksheet(1);
if (isListRequired)
{
//worksheet.Cell("E2").DataValidation.List(string.Join("",groupCodeList.ToArray()));
//worksheet.Cell(2,5).InsertData(groupCodeList);
// Trying to add a list to the Cell (E2) - and applying datavalidation to the Column (5th column - E Range)
// Dropdown is created in excel(with blank) but data is not population to that dropdown
worksheet.Cell(2, 5).InsertData(groupCodeList);
worksheet.Column(5).SetDataValidation().List(string.Join("", groupCodeList.ToArray()));
}
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=ExcelFormat.xlsx");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.Charset = "";
using (MemoryStream MyMemoryStream = new MemoryStream())
{
workbook.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
}
And the code where i am calling this method is
List<PMS_M_ActivityGroup> activitygroup = new List<PMS_M_ActivityGroup>();
activitygroup = db.PMS_M_ActivityGroup.Select(a => a).ToList();
DataTable dt2 = new DataTable("Excel Template");
GridView Template2 = new GridView();
Template2.DataSource = activitygroup;
ExcelExport(dt2, Template2);
Request you to provide me the solution how to achieve the required functionality.
Thank you
I got the solution. It's not that much simple but we need to do few tricks to achieve this functionality. Posting here - might be helpful for other developers who are using specifically ClosedXML library.
So what we need to do is : we need to create a separate(Second) sheet, apply
DataValidation to the 1st sheet column where dropdown to be appeared.
private void ExcelExportValidation(DataTable dt, GridView Template)
{
try
{
bool isListRequired = false;
List<string> groupCodeList = new List<string>(); ;
Template.DataBind();
if (Template.HeaderRow != null)
{
foreach (TableCell cell in Template.HeaderRow.Cells)
{
if (cell.Text == "ActivityGroup_Code")
{
isListRequired = true;
groupCodeList = db.PMS_M_ActivityGroup.Select(a => a.ActivityGroup_Code).ToList();
}
dt.Columns.Add(cell.Text);
}
var workbook = new XLWorkbook();
var returnValue = workbook.AddWorksheet(dt);
var worksheet = workbook.Worksheet(1);
if (isListRequired)
{
var tempDt = Helper.ConvertListToDataTable(groupCodeList);
tempDt.TableName = "Sheet1";
var returnValue2 = workbook.AddWorksheet(tempDt);
var worksheet2 = workbook.Worksheet(2);
int lastCellNo = groupCodeList.Count + 1;
worksheet.Column(5).SetDataValidation().List(worksheet2.Range("A2:A" + lastCellNo), true);
}
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=ExcelFormat.xlsx");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.Charset = "";
using (MemoryStream MyMemoryStream = new MemoryStream())
{
workbook.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
}
catch (Exception ex)
{
ExceptionLogging.SendErrorToText(ex);
}
}
#Chandan has certainly given the right lead to the answer. I'm posting a stand-alone solution code snippet which saves the excel file on disk:
var workbook = new XLWorkbook();
DataTable userData = new DataTable("Sheet1");
userData.Columns.Add("Master Column");
workbook.AddWorksheet(userData);
var worksheet = workbook.Worksheet(1);
DataTable validationTable = new DataTable();
validationTable.Columns.Add("DropDownItems");
validationTable.TableName = "Sheet2";
DataRow dr = validationTable.NewRow();
dr["DropDownItems"] = "Item1";
validationTable.Rows.Add(dr);
dr = validationTable.NewRow();
dr["DropDownItems"] = "Item2";
validationTable.Rows.Add(dr);
dr = validationTable.NewRow();
dr["DropDownItems"] = "Item3";
validationTable.Rows.Add(dr);
var worksheet2 = workbook.AddWorksheet(validationTable);
worksheet.Column(1).SetDataValidation().List(worksheet2.Range("A2:A4"), true);
//optional: you can hide the data validation sheet from your users if you want
//worksheet2.Hide();
workbook.SaveAs(#"C:\myworkbook.xlsx");
It creates drop down in Sheet1 as shown below:
I am currently making a web application using epPlus along with it to save the current database to an excel file. That part is easy and working, but what I'm trying to do is create a pop up dialog box that will allow the client to select the directory they want to save the excel file to. Then use the path they've given me and use the SaveAs function in epPlus with the path they have selected.
The question is how do I go about getting the dialog box to work and getting the path? I've tried using Response and I can't seem to get that working. The problem is that the excel file is only an object until save is done, and I need the path to do the save. Ideas? here's my code.
protected void OnbtnSaveExcelFileClick(object sender, EventArgs e)
{
String FileName = "GamingRecords";
String FilePath = #"C:\....\";
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath);
response.Flush();
response.End();
try
{
using (var package = new ExcelPackage(flUploadLink.FileContent))
{
var worksheet = package.Workbook.Worksheets.Add("Games to Date - " + DateTime.Now.ToShortDateString());
worksheet.DefaultRowHeight = 22;
var headers = new[] { Constants.GameTitle, Constants.GameGenre, Constants.Price, Constants.Quantity };
for (var i = 1; i < headers.Count() + 1; i++)
worksheet.Cells[1, i].Value = headers[i - 1];
var game = new GameClass();
var list = game.FetchAll();
var rowNumber = 2;
foreach (var t in list)
{
worksheet.Cells[rowNumber, 1].Value = t.GameTitle;
worksheet.Cells[rowNumber, 2].Value = t.GameGenre;
worksheet.Cells[rowNumber, 3].Value = t.Price;
worksheet.Cells[rowNumber, 4].Value = t.Quantity;
rowNumber++;
}
for (var i = 1; i < worksheet.Dimension.End.Column; i++)
worksheet.Column(i).AutoFit();
package.Workbook.Properties.Title = "Games on Record";
package.Workbook.Properties.Author = "Kirk Rudzinski";
package.Workbook.Properties.Company = "Logistics+";
package.Save();
litExcelError.Visible = false;
}
}
catch (IOException)
{ litExcelError.Text = "Please close the file to make modifications"; }
}
Alright, just to clarify I figured out how to do it the way I was trying. For reference in case anyone runs into an error like this here is the code!
protected void OnbtnSaveExcelFileClick(object sender, EventArgs e)
{
try
{
using (var package = new ExcelPackage(flUploadLink.FileContent))
{
var worksheet = package.Workbook.Worksheets.Add("Games to Date - " + DateTime.Now.ToShortDateString());
worksheet.DefaultRowHeight = 22;
var headers = new[] { Constants.GameTitle, Constants.GameGenre, Constants.Price, Constants.Quantity };
for (var i = 1; i < headers.Count() + 1; i++)
worksheet.Cells[1, i].Value = headers[i - 1];
int rowNumber = 2;
foreach (GridViewRow row in grdGamingTable.Rows)
{
var index = row.RowIndex;
worksheet.Cells[rowNumber, 1].Value = grdGamingTable.Rows[index].Cells[2].Text;
worksheet.Cells[rowNumber, 2].Value = grdGamingTable.Rows[index].Cells[3].Text;
worksheet.Cells[rowNumber, 3].Value = Convert.ToInt16(grdGamingTable.Rows[index].Cells[4].Text);
worksheet.Cells[rowNumber, 4].Value = Convert.ToInt16(grdGamingTable.Rows[index].Cells[5].Text);
rowNumber++;
}
for (var i = 1; i < worksheet.Dimension.End.Column; i++)
worksheet.Column(i).AutoFit();
package.Workbook.Properties.Title = "Games on Record";
package.Save();
litExcelError.Visible = false;
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=GameRecords.xlsx");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
}
}
catch (IOException)
{ litExcelError.Text = "Please close the file to make modifications"; }
}
I recently started to code in Visual Studio 2010 from Visual Studio 2005. I need code to export to Excel from a datagrid. In Visual Studio 2005 the following code was used.
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=dgd.xls");
Response.Charset = "";
Response.ContentType = "application/vnd.xls";
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
dgd.Visible = true;
dgd.RenderControl(htmlWrite);
Response.Write(stringWrite.ToString());
Response.End();
This does not yield the same result in Visual Studio 2005. The header is not aligned to the column. The pictures in the datagrid are not fetched in Excel, and the links in the datagrid do not appear properly. What would be better code?
Add following code after htmlwriter line
`if (dtDetails.Rows.Count > 0)
{
for (int i = 0; i < gvProduction.HeaderRow.Cells.Count; i++)
{
gvProduction.HeaderRow.Cells[i].Style.Add("background-color", "#507CD1");
}
int j = 1;
//This loop is used to apply stlye to cells based on particular row
foreach (GridViewRow gvrow in gvProduction.Rows)
{
gvrow.BackColor = Color.White;
if (j <= gvProduction.Rows.Count)
{
if (j % 2 != 0)
{
for (int k = 0; k < gvrow.Cells.Count; k++)
{
gvrow.Cells[k].Style.Add("background-color", "#EFF3FB");
}
}
}
j++;
}
gvProduction.RenderControl(hw);
Response.Write(sw.ToString());
Response.End();
}`
I am using same in our project.
private void ExportToExcel(DataTable dt)
{
if (dt.Rows.Count > 0)
{
string filename = "DownloadReport.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 + "");
this.EnableViewState = false;
Response.Write(tw.ToString());
Response.End();
}
}
Hope it helps you
You can use following code.
On the export button click:
FileInfo FI = new FileInfo(Path);
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWriter);
DataGrid DataGrd = new DataGrid();
DataGrd.DataSource = dt1;
DataGrd.DataBind();
DataGrd.RenderControl(htmlWrite);
string directory = Path.Substring(0, Path.LastIndexOf("\\")); // GetDirectory(Path);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
System.IO.StreamWriter vw = new System.IO.StreamWriter(Path, true);
stringWriter.ToString().Normalize();
vw.Write(stringWriter.ToString());
vw.Flush();
vw.Close();
WriteAttachment(FI.Name, "application/vnd.ms-excel", stringWriter.ToString());
Code for writing attachment:
public static void WriteAttachment(string FileName, string FileType, string content)
{
HttpResponse Response = System.Web.HttpContext.Current.Response;
Response.ClearHeaders();
Response.AppendHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.ContentType = FileType;
Response.Write(content);
Response.End();
}
For more references, see Export Gridview Data to Excel in ASP.NET.
The below code may help you to write an Excel sheet using gridview.
// Function to export datagridview to excel sheet
// excel_file contains the path to the excel file.
public void export_to_excel(DataGridView dgv, string excel_file)
{
int cols;
//Open file
StreamWriter wr = new StreamWriter(excel_file);
//Determine the number of columns and write columns to file
cols = dgv.Columns.Count;
for (int i = 0; i < cols; i++)
{
wr.Write(dgv.Columns[i].HeaderText.ToString().ToUpper() + "\t");
}
wr.WriteLine();
//Write rows to the Excel file
for (int i = 0; i < (dgv.Rows.Count - 1); i++)
{
for (int j = 0; j < cols; j++)
{
if (dgv.Rows[i].Cells[j].Value != null)
wr.Write(dgv.Rows[i].Cells[j].Value + "\t");
else
{
wr.Write("\t");
}
}
wr.WriteLine();
}
//Close file
wr.Close();
}
Also, you can go through the blog post How to Export Data to Excel from an ASP.NET Application + Avoid the File Format Differ Prompt.
I have a text file which is in tab deliminator and following is my code to generate its Excel.
protected void to_excel(object sender, EventArgs e)
{
string filepath = Path.Combine(Server.MapPath("~/Files"), fileupload.FileName);
fileupload.SaveAs(filepath);
string fname = fileupload.PostedFile.FileName;
DataTable dt = (DataTable)ReadToEnd(filepath);
string sFilename = fname.Substring(0, fname.IndexOf("."));
HttpResponse response = HttpContext.Current.Response;
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=" + sFilename + ".xls");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new System.Web.UI.HtmlTextWriter(stringWrite);
System.Web.UI.WebControls.DataGrid dg = new System.Web.UI.WebControls.DataGrid();
dg.DataSource = dt;
dg.DataBind();
dg.RenderControl(htmlWrite);
Response.Write(stringWrite.ToString());
Response.End();
}
private object ReadToEnd(string filePath)
{
DataTable dtDataSource = new DataTable();
string[] fileContent = File.ReadAllLines(filePath);
if (fileContent.Count() > 0)
{
string[] columns = fileContent[0].Split('\t');
for (int i = 0; i < columns.Count(); i++)
{
dtDataSource.Columns.Add(columns[i]);
}
for (int i = 1; i < fileContent.Count(); i++)
{
string[] rowData = fileContent[i].Split('\t');
dtDataSource.Rows.Add(rowData);
}
}
return dtDataSource;
}
This code works fine since i am generating 2003 excel file (.xls).
But if i am generating a 2007 (.xlsx) by changing the code to
Response.AddHeader("content-disposition", "attachment;filename=" + sFilename + ".xlsx");
i get an error like this.
I did my homework and came to know that this error is because the .xlsx file generated by my program is done by using HTML (markup language) XML (markup language) which should actually be done for a 2007 excel file.
My question is what changes should i do so that i get the desired result i.e. I get the 2007 excel sheet!!!
You can create the Excel with multiple Worksheet using DataSet like
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
using System.Data;
using System.IO;
[HttpPost]
public ActionResult CreateExcel(int id)
{
DataSet dataSet = new DataSet(); //Your Data Set
if (dataSet.Tables.Count > 0)
{
System.Data.DataTable dt1 = new System.Data.DataTable();
System.Data.DataTable dt2 = new System.Data.DataTable();
dt1 = dataSet.Tables[0];
dt2 = dataSet.Tables[1];
if (dt1.Rows.Count > 1 && dt2.Rows.Count > 1)
{
var excel = new Microsoft.Office.Interop.Excel.Application();
var workbook = excel.Workbooks.Add(true);
AddExcelSheet(dt1, workbook);
AddExcelSheet(dt2, workbook);
//KK-Save the excel file into server path
string strLocation = "~/Upload/TempExcel/";
string fName = "Report_" + DateTime.Now.ToString("MMddyyyyHHmmss") + ".xlsx";
string strPath = Path.Combine(Server.MapPath(strLocation), fName);
workbook.SaveAs(strPath);
workbook.Close();
//KK-Generate downloading link view page
System.Web.HttpResponse Response = System.Web.HttpContext.Current.Response;
Response.ClearContent();
Response.Clear();
//Response.ContentType = "application/vnd.ms-excel"; //This is for office 2003
Response.ContentType = "application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("Content-Disposition", "attachment; filename=YourReport.xlsx");
Response.TransmitFile(strPath);
Response.Flush();
Response.End();
//KK-Deleting the file after downloading
if (System.IO.File.Exists(strPath))
System.IO.File.Delete(strPath);
}
}
return View();
}
/// <summary>
/// KK-This method add new Excel Worksheet using DataTable
/// </summary>
/// <param name="ds"></param>
private static void AddExcelSheet(System.Data.DataTable dt, Workbook wb)
{
Excel.Sheets sheets = wb.Sheets;
Excel.Worksheet newSheet = sheets.Add();
int iCol = 0;
foreach (DataColumn c in dt.Columns)
{
iCol++;
newSheet.Cells[1, iCol] = c.ColumnName;
newSheet.Cells[1, iCol].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.RoyalBlue);
newSheet.Cells[1, iCol].Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.White);
newSheet.Cells[1, iCol].Font.Bold = true;
newSheet.Cells[1, iCol].BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlThin);
}
int iRow = 0;
foreach (DataRow r in dt.Rows)
{
iRow++;
// add each row's cell data...
iCol = 0;
foreach (DataColumn c in dt.Columns)
{
iCol++;
newSheet.Cells[iRow + 1, iCol] = r[c.ColumnName];
newSheet.Cells[iRow + 1, iCol].BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlThin);
}
}
}
You should check the OpenXML SDK:
http://msdn.microsoft.com/en-us/library/office/gg278328.aspx
Alternatively, you can check the various commercial libraries listed here:
http://polymathprogrammer.com/spreadsheetopenxml/spreadsheetcodelibrariescomparison.pdf
I had a good experience with Aspose Cells.
PS: your code doesn't generate a valid xls file, but html that gets somehow correctly interpreted by excel.
You have to use extended libraries which I recommend using EPPlus which is a .net library that reads & writes Excel 2007/2010 files using the Open Office Xml format (xlsx).
Library
and then replace the code
protected void to_excel(object sender, EventArgs e)
{
string filepath = Path.Combine(Server.MapPath("~/Files"), fileupload.FileName);
fileupload.SaveAs(filepath);
string fname = fileupload.PostedFile.FileName;
DataTable dt = (DataTable)ReadToEnd(filepath);
string sFilename = fname.Substring(0, fname.IndexOf("."));
sFilename = sFilename + ".xlsx";
MemoryStream ms = DataTableToExcelXlsx(dt, "Sheet1");
ms.WriteTo(HttpContext.Current.Response.OutputStream);
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + sFilename);
HttpContext.Current.Response.StatusCode = 200;
HttpContext.Current.Response.End();
}
public void toexcel(DataTable dt, string Filename)
{
MemoryStream ms = DataTableToExcelXlsx(dt, "Sheet1");
ms.WriteTo(HttpContext.Current.Response.OutputStream);
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + Filename);
HttpContext.Current.Response.StatusCode = 200;
HttpContext.Current.Response.End();
}
public bool IsReusable
{
get { return false; }
}
public static MemoryStream DataTableToExcelXlsx(DataTable table, string sheetName)
{
MemoryStream Result = new MemoryStream();
ExcelPackage pack = new ExcelPackage();
ExcelWorksheet ws = pack.Workbook.Worksheets.Add(sheetName);
int col = 1;
int row = 1;
foreach (DataColumn column in table.Columns)
{
ws.Cells[row, col].Value = column.ColumnName.ToString();
col++;
}
col = 1;
row = 2;
foreach (DataRow rw in table.Rows)
{
foreach (DataColumn cl in table.Columns)
{
if (rw[cl.ColumnName] != DBNull.Value)
ws.Cells[row, col].Value = rw[cl.ColumnName].ToString();
col++;
}
row++;
col = 1;
}
pack.SaveAs(Result);
return Result;
}
I got this solution here