I have created a few charts dynamically and would like to export the data to excel using closedxml.
I created a custom item on legend and when I click it, the page posts back and the event handler was raised properly. But I couldn't get the save window to pop up, hence not being able to save the excel file. Help me please?
I am using C# on asp.NET Framework 4.5.
Here's a simplified version of my code.
protected void Page_Load(object sender, EventArgs e)
{
Add_Chart();
}
public void Add_Chart()
{
System.Web.UI.DataVisualization.Charting.Chart Add_Chart1 = new System.Web.UI.DataVisualization.Charting.Chart();
//Create Chart here
//Add chart to htmltablecell
Add_Chart1.Click += Chart_Legend_Click;
}
protected void Chart_Button_Click(object sender, ImageMapEventArgs e)
{
string sheetname = "trial";
string filename = "trial.xlsx";
var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add(sheetname);
HttpResponse httpResponse = Response;
httpResponse.Clear();
httpResponse.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
httpResponse.AddHeader("content-disposition", "attachment;filename=" + filename);
//Create header and data rows here
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
{
workbook.SaveAs(memoryStream);
memoryStream.WriteTo(httpResponse.OutputStream);
memoryStream.Close();
}
httpResponse.End();
}
Related
i am come up with scenario that while exporting grid view to excel its not refreshing my grid data source. Below is my code what i have done before. Below code is updating flag in database and then trying to refresh the grid data source in Fill Grid method.
protected void Process_Command(object sender, CommandEventArgs e)
{
if (!string.IsNullOrEmpty(Convert.ToString(e.CommandArgument)))
{
using (var transaction = context.Database.BeginTransaction())
{
DocumentOGP objDocumentOGP = context.DocumentOGPs.Find(Convert.ToInt64(e.CommandArgument));
objDocumentOGP.UpdationDate = DateTime.Now;
objDocumentOGP.DispatchStatusID = 2;
context.DocumentOGPs.Add(objDocumentOGP);
context.Entry(objDocumentOGP).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
transaction.Commit();
FillGrid();
}
ExportToExcel(Convert.ToInt64(e.CommandArgument));
}
}
Below is the Export to excel method.
public void ExportToExcel(Int64 OGPCode)
{
DataTable dtPickList =GeneralQuery.GetDocumentPickList(OGPCode);
if (dtPickList != null && dtPickList.Rows.Count>0)
{
//Create a dummy GridView
GridView GridView1 = new GridView();
GridView1.AllowPaging = false;
GridView1.DataSource = dtPickList;
GridView1.DataBind();
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=Inbox.xls");
Response.Charset = "";
Response.ContentType = "application/vnd.ms-excel";
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
for (int i = 0; i < GridView1.Rows.Count; i++)
{
//Apply text style to each Row
GridView1.Rows[i].Attributes.Add("class", "textmode");
}
GridView1.RenderControl(hw);
//style to format numbers to string
string style = #"<style> .textmode { mso-number-format:\#; } </style>";
Response.Write(style);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
GridView1.DataSource = null;
Response.Write(Request.RawUrl.ToString());
}
}
public override void VerifyRenderingInServerForm(Control control)
{
}
Please help me what i am doing wrong. Thanks
Finally i found the way to refresh the grid view while exporting the grid view to excel. I just create new web form and put ExportGridToExcel() method in Page_Load and on button click it refresh the grid view data source and open new tab to download excel file. Below is my code.
protected void Process_Command(object sender, CommandEventArgs e)
{
if (Session["Status"] != "Refreshed")
{
if (!string.IsNullOrEmpty(Convert.ToString(e.CommandArgument)))
{
using (var transaction = context.Database.BeginTransaction())
{
DocumentOGP objDocumentOGP = context.DocumentOGPs.Find(Convert.ToInt64(e.CommandArgument));
objDocumentOGP.UpdationDate = DateTime.Now;
objDocumentOGP.DispatchStatusID = 2;
context.DocumentOGPs.Add(objDocumentOGP);
context.Entry(objDocumentOGP).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
transaction.Commit();
FillGrid();
Session["OGPCode"] = Convert.ToString(e.CommandArgument);
}
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "OpenWindow", "window.open('http://localhost:56430/DownLoadExcel','_newtab');", true);
}
}
}
Below is my Download excel file web-form and its implementation
public partial class DownLoadExcel : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (!string.IsNullOrEmpty(Convert.ToString(Session["OGPCode"])))
{
ExportToExcel(Convert.ToInt64(Session["OGPCode"]));
Session["OGPCode"] = null;
}
}
}
public void ExportToExcel(Int64 OGPCode)
{
DataTable dt = GeneralQuery.GetDocumentPickList(OGPCode);
//create a new byte array
byte[] bin;
string FileName = "Pick-List-" + DateTime.Now.ToString();
//create a new excel document
using (ExcelPackage excelPackage = new ExcelPackage())
{
//create a new worksheet
ExcelWorksheet ws = excelPackage.Workbook.Worksheets.Add(FileName);
//add the contents of the datatable to the excel file
ws.Cells["A1"].LoadFromDataTable(dt, true);
//auto fix the columns
ws.Cells[ws.Dimension.Address].AutoFitColumns();
//loop all the columns
for (int col = 1; col <= ws.Dimension.End.Column; col++)
{
//make all columns just a bit wider, it would sometimes not fit
ws.Column(col).Width = ws.Column(col).Width + 1;
var cell = ws.Cells[1, col];
//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"));
//make the header text upper case
cell.Value = ((string)cell.Value).ToUpper();
}
//convert the excel package to a byte array
bin = excelPackage.GetAsByteArray();
}
//clear the buffer stream
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
//set the correct contenttype
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//set the correct length of the data being send
Response.AddHeader("content-length", bin.Length.ToString());
//set the filename for the excel package
Response.AddHeader("content-disposition", "attachment; filename=\"" + FileName + ".xlsx\"");
//send the byte array to the browser
Response.OutputStream.Write(bin, 0, bin.Length);
//cleanup
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
When you update GridView or any control values dynamically you should render and export it to other application.
Sample: check with RenderControl method of GridView.
private void ExportGridToExcel()
{
Response.Clear();
Response.Buffer = true;
Response.ClearContent();
Response.ClearHeaders();
Response.Charset = "";
string FileName = "xyz.xls";
StringWriter strwritter = new StringWriter();
HtmlTextWriter htmltextwrtter = new HtmlTextWriter(strwritter);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName);
GridView1.RenderControl(htmltextwrtter);
Response.Write(strwritter.ToString());
Response.End();
}
I used this code to open the HTML page in HTML editor in c#.
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog() { Multiselect =
false, ValidateNames = true, Filter = "HTML|*.html" })
if (ofd.ShowDialog() == DialogResult.OK)
{
textBox1.Text = ofd.FileName;
FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read);
webBrowser1.DocumentStream = fs;
}
}
and also I used this code to save the changes
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveFileDialog svf = new SaveFileDialog();
svf.Filter = "Text Files (.html)|*.html";
if (svf.ShowDialog() == DialogResult.OK)
{
System.IO.StreamWriter sw = new System.IO.StreamWriter(svf.FileName);
sw.WriteLine(webBrowser1);
sw.Close();
}
}
However, the only line is saved in my HTML page is this message: System.Windows.Forms.WebBrowser.
Do you have any idea that how can I save the content of the HTML page? Thanks
The following should work as you require:
System.IO.StreamWriter sw = new System.IO.StreamWriter(svf.FileName);
webBrowser1.DocumentStream.CopyTo(sw.BaseStream);
sw.Flush();
sw.Close();
The reason yours does not work is because you're trying to write an object to a stream directly, which as stated implicitly calls the ToString() method.
I have a page with grid that generates PDF files using iTextSharp dll. The code is as following:
var document = new Document();
bool download = true;
if (download == true)
{
PdfWriter.GetInstance(document, Response.OutputStream);
BindGrid();
}
string fileName = "PDF" + DateTime.Now.Ticks + ".pdf";
try
{
document.Open();
// adding contents to the pdf file....
}
catch (Exception ex)
{
lblMessage.Text = ex.ToString();
}
finally
{
document.Close();
BindGrid();
}
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
Response.Flush();
Response.End();
BindGrid();
}
I need to bind the grid once the download window pops up, or after user clicks to download it doesn't matters, I just need the grid to bind after the user generates the pdf file. I have tried binding the grid on numerous places as you can see, but none of them worked, the grid binds only after I refresh the page :(.
Is there any way I can do this ???
Response.End ends the page life cycle.
I suggest you to:
Generate the PDF file and save it on the server
Bind the grid
Flush the generated file
Something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindGrid(); // Bind the grid here
// After reloading the page you flush the file
if (Session["FILE"] != null)
FlushFile();
}
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
// Generate & Save PDF here
Session["FILE"] = fullFilePath; // The full path of the file you saved.
Response.Redirect(Request.RawUrl); // This reload the page
}
private void FlushFile()
{
string fullFilePath = Session["FILE"].ToString();
Session["FILE"] = null;
// Flush file here
}
Hope this helps.
Cheers
I want to export a gridview to excel 2007,the code i'm using can import to excel 2007 with the mime type application/vnd.ms-excel (excel 2003)but i get a warning msg that says "The file you are trying to open is in a different format...",with yes and no to clic,clicking in yes the file open,buy i can't have this msg for the customers.And using the mime type for excel 2007 (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)the file doesn't even open "Excel can't open the file because the format or extansion isn't valid".
This is the code i'm using right now:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.IO;
using System.Drawing;
namespace TesteFornecedores
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.BindGrid();
}
}
private void BindGrid()
{
using (DataSet ds = new DataSet())
{
ds.ReadXml(Server.MapPath("~/Customers.xml"));
GridView1.DataSource = ds;
GridView1.DataBind();
}
}
protected void OnPageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
this.BindGrid();
}
protected void ExportToExcel(object sender, EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=ExcelList");
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
using (StringWriter sw = new StringWriter())
{
HtmlTextWriter hw = new HtmlTextWriter(sw);
//To Export all pages
GridView1.AllowPaging = false;
this.BindGrid();
GridView1.HeaderRow.BackColor = Color.White;
foreach (TableCell cell in GridView1.HeaderRow.Cells)
{
cell.BackColor = GridView1.HeaderStyle.BackColor;
}
foreach (GridViewRow row in GridView1.Rows)
{
row.BackColor = Color.White;
foreach (TableCell cell in row.Cells)
{
if (row.RowIndex%2 == 0)
{
cell.BackColor = GridView1.AlternatingRowStyle.BackColor;
}
else
{
cell.BackColor = GridView1.RowStyle.BackColor;
}
cell.CssClass = "textmode";
}
}
GridView1.RenderControl(hw);
//style to format numbers to string
string style = #"<style> .textmode { } </style>";
Response.Write(style);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
}
}
public override void VerifyRenderingInServerForm(Control control)
{
/* Verifies that the control is rendered */
}
}
}
Someone know a solution the can help me open in excel 2007 this gridview?
Thanks.
You are not exporting to an actual Excel format. You're creating an HTML file, and since you're providing a MIME type that Excel knows how to handle, Excel attempts to open it. Excel does know how to read basic HTML files, but it's difficult to control the formatting and you will get that warning message.
Instead what you need to do is generate your .xlsx files is use a library that can generate them for you. Examples of this would be EPPlus and Open Office XML SDK. Note you need to steer clear of using Excel Interop based solutions, as these are not supported by Microsoft on the server side, they will be difficult to debug, and they will cause headaches.
By the way, don't think of it as "exporting a GridView". That's a bad approach. A GridView is a UI element for displaying data in HTML. Think of it instead as "how do I export this data?" In your case, think of it as exporting a DataSet or XML type data.
Response.Clear();
Response.ContentType = "application/excel";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.BinaryWrite(objectData);//objectData is binary data
Response.End();
Your response should be like this. I'm pretty sure that your code will not work, because you are not giving valid excel file to the Response, read about OleDbConnection
Use your DataSet from DataSource of the Grid. After that build OleDbConnection
OleDbConnection conn = new OleDbConnection();
string connectString = String.Format(
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0 Xml;HDR={1};'",
fileName, "YES");
conn.ConnectionString = connectString;
conn.Open();
OleDbCommand comm = new OleDbCommand();
comm.CommandText = string.Format("CREATE TABLE [{0}] ", "TableName");
Add the columns from the DataSet to the comm.CommanText. To build replica of the dataSet column structure. After that:
comm.Connection = conn;
comm.ExecuteNonQuery();
Now you have the table created with the same columns like your data set.
Now you should update the content
OleDbDataAdapter ad = new OleDbDataAdapter(
string.Format("SELECT * FROM [{0}]", "TableName"), conn);
OleDbCommandBuilder builder = new OleDbCommandBuilder(ad);
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
// Saves the data set
ad.Update(DataSetFromTheGrid);
Now you filled the table with data.
//be aware fileName is the same as fileName in the connection string !
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fs);
excelBytes = reader.ReadBytes((int)fs.Length);
//after the returned bytes it will be good to delete the file !
Return this bytes to the Response and you have your excel file.
I'm using 'ExcelDataReader' to read in an Excel file, I want to display the file on screen.
protected void Page_Load(object sender, EventArgs e)
{
string filePath = #"C:\WORK\BoireannSVN\trunk\VS\CRCConnect\Spreadsheet\Spreadsheet.xlsx";
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
while (excelReader.Read())
{
Label x = new Label();
x.Text = result.Tables[0].Rows[0].ItemArray[0].ToString();
uploadExcel.Controls.Add(x);
excelReader.GetInt32(0);
}
excelReader.Close();
}
I've added in the
Label x = new Label();
x.Text = result.Tables[0].Rows[0].ItemArray[0].ToString();
Attempting to get the excel sheet to display on screen, although I'm having no luck with this. I think it is something like
table1.Columns.Add;
table1.Rows.Add;
but can't seem to get it going, any help much appreciated.
I was in a similar situation I did the following:
var rows = results.Tables[0].AsEnumerable();
Then you can iterate and select the value for columns:
foreach (var dataRow in rows)
{
Console.WriteLine(dataRow[0]);
//or
Console.WriteLine(dataRow["ColumnName"]);
}