Grid binding error while exporting to excel - c#

I have a GridView with 75000 records. The data will increase in few days. I have no issues while populating in UI as I am using paging. Now, while exporting to excel all the blogs suggest to remove pagination and then load the grid again to export. But during that process the databind fails with out of memory exception. Please help. I even tried to load to datatable and reload to a new gridview.
(Added my code below, currently this is looping only the final page in the grid multiple times)
try
{
GrdReport.AllowPaging = false;
LoadReportData();
int a = GrdReport.PageIndex;
if (GrdReport.PageCount <= 650)
{
DataTable dt = new DataTable();
for (int i = 0; i < GrdReport.PageCount; i++)
{
GrdReport.PageIndex = i;
//GrdReport.SetPageIndex(a);
if (i == 0)
{
for (int k = 0; k < GrdReport.HeaderRow.Cells.Count; k++)
{
if (GrdReport.HeaderRow.Cells[k].HasControls())
{
if (GrdReport.HeaderRow.Cells[k].Controls[0] is LinkButton)
{
LinkButton headerControl = GrdReport.HeaderRow.Cells[k].Controls[0] as LinkButton;
string headerName = headerControl.Text;
dt.Columns.Add(headerName);
}
}
}
}
foreach (GridViewRow row in GrdReport.Rows)
{
dt.Rows.Add();
for (int j = 0; j < row.Cells.Count; j++)
{
dt.Rows[dt.Rows.Count - 1][j] = row.Cells[j].Text;
}
}
}
int x = dt.Rows.Count;
int y = dt.Columns.Count;
GrdReport.SetPageIndex(a);
Session["New"] = dt;
HttpResponse Response = HttpContext.Current.Response;
Response.Redirect("ExportToExcelHandler.ashx?gv=" + Session["New"], false);
}
else
{
lblErr.Text = "Result exceeds 65000 records. Please modify search criteria to reduce records.";
lblErr.Visible = true;
}
}
And this is the code in handler:
public class ExportToExcelHandler : System.Web.UI.Page, IHttpHandler, IRequiresSessionState
{
public new void ProcessRequest(HttpContext context)
{
GridView grid = new GridView();
this.EnableViewState = false;
grid.DataSource = (DataTable)HttpContext.Current.Session["New"];
grid.DataBind();
HttpResponse Response = HttpContext.Current.Response;
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=Results.xls");
Response.Charset = "";
Response.ContentType = "application/vnd.ms-excel";
StringWriter StringWriter = new StringWriter();
HtmlTextWriter HtmlTextWriter = new System.Web.UI.HtmlTextWriter(Response.Output);
grid.RenderControl(HtmlTextWriter);
Response.End();
}
public new bool IsReusable
{
get
{
return false;
}
}
}

An HTML file with XLS extension is not a real MS Excel file. MS Excel only knows how to read them and to display data.
Saving large HTML files leads to high memory allocation and it is time consuming.
You should use an Excel library like EasyXLS that saves xls or xlsx Excel files and has a better memory management.
Check the following links for directions:
Export Gridview to Excel in C#
and
Export large Excel files in C#

Related

Unable to generate complete csv file from gridview

I'm trying to generate a report from a gridview which contains a complete csv listing as shown on the gridview. I'm able to generate the report however it is only generating first 10 on the list. HEres the code for my "Generate Report" button:
protected void BtnGenerateReports_Click(object sender, EventArgs e)
{
string filename = $"PatientList_{DateTime.Now:yyyyMMdd}.csv";
PopulatePatientList();
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", $"attachment;filename={filename}");
Response.Charset = "";
Response.ContentType = "application/text";
GvPatientList.AllowPaging = true;
GvPatientList.DataBind();
StringBuilder columnbind = new StringBuilder();
for (int k = 0; k < GvPatientList.Columns.Count; k++)
{
columnbind.Append(GvPatientList.Columns[k].HeaderText + ',');
}
columnbind.Append("\r\n");
for (int i = 0; i < GvPatientList.Rows.Count; i++)
{
for (int j = 0; j < GvPatientList.Rows.Count; j++)
{
columnbind.Append(GvPatientList.Rows[i].Cells[j].Text + ',');
}
columnbind.Append("\r\n");
}
Response.Output.Write(columnbind.ToString());
Response.Flush();
Response.End();
Change this line of Code and try again
if you have paging in your gridview it will not export all the rows , it will export only the visible rows , so while exporting alone change the below line and export.
GvPatientList.AllowPaging = false;
Link : GridView is not being exported into Excel file

Export datatable with 1 million records to csv

I have a C# Data Table with about one million rows with 20 columns
I need to export this to csv , i tried string builder but page keep loading
public ActionResult DownloadExcel()
{
System.Data.DataTable result = Helpers.TaxMailingExcelBuilder.Export();
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=myData.csv");
Response.Charset = "";
Response.ContentType = #"application/text";
Response.Output.Write(ExportDataTable(result).ToString());
Response.Flush();
Response.End();
return View();
}
private StringBuilder ExportDataTable(System.Data.DataTable dt)
{
var stringBuilder = new StringBuilder();
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
stringBuilder.Append(dt.Rows[i][j].ToString() + ',');
}
stringBuilder.Append("rn");
}
return stringBuilder;
}
}
page keep loading without any progress
I would return a StringWriter like code below
private StringWriter ExportDataTable(DataTable dt)
{
StringWriter writer = new StringWriter();
string[] columnNames = dt.Columns.Cast<DataColumn>().Select(x => x.ColumnName).ToArray();
writer.WriteLine(string.Join(",", columnNames));
foreach(DataRow row in dt.AsEnumerable())
{
writer.WriteLine(string.Join(",", row.ItemArray.Select(x => x.ToString())));
}
return writer;
}

Exporting DataTable to Excel

I have a small web application that creates two datatables from a jquery datepicker. I am able to export those datatables to excel of course if they are on the same page.
I've changed my application to render the datatables on new webforms.
Here is my code to export to excel:
protected void ExportToExcel(object sender, EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.xls");
Response.Charset = "";
Response.ContentType = "application/vnd.ms-excel";
using (StringWriter sw = new StringWriter())
{
HtmlTextWriter hw = new HtmlTextWriter(sw);
//To Export all pages
this.BindGrid1(TextDateFrom.Text, TextDateTo.Text);
GridView2.HeaderRow.BackColor = Color.White;
foreach (TableCell cell in GridView2.HeaderRow.Cells)
{
cell.BackColor = GridView2.HeaderStyle.BackColor;
}
foreach (GridViewRow row in GridView2.Rows)
{
row.BackColor = Color.White;
foreach (TableCell cell in row.Cells)
{
if (row.RowIndex % 2 == 0)
{
cell.BackColor = GridView2.AlternatingRowStyle.BackColor;
}
else
{
cell.BackColor = GridView2.RowStyle.BackColor;
}
cell.CssClass = "textmode";
}
}
GridView2.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();
}
}
Here is where I am having trouble:
this.BindGrid1(TextDateFrom.Text, TextDateTo.Text);
Of course my BindGrid1() is an another form. To call my datatables in my new forms I created a session.
If I have the code on the web form where the data tables are:
DataTable dt = (DataTable)Session["GridData"];
if (dt.Rows.Count > 0)
{
GridView1.DataSource = dt;
GridView1.DataBind();
}
I'm not sure exactly how to call that this. to export all pages. Should I have created a global variable that takes the String values from the BindGrid1 method to then use on the new page?
Pertinent to your task, the data export from DataTable dt to Excel can be achieved using the following procedure, which utilizes Microsoft.Office.Interop.Excel object library:
/// <summary>
/// export DataTable to Excel (C#)
/// </summary>
internal static void Export2Excel(DataTable dataTable)
{
object misValue = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.Application _appExcel = null;
Microsoft.Office.Interop.Excel.Workbook _excelWorkbook = null;
Microsoft.Office.Interop.Excel.Worksheet _excelWorksheet = null;
try
{
// excel app object
_appExcel = new Microsoft.Office.Interop.Excel.Application();
// excel workbook object added to app
_excelWorkbook = _appExcel.Workbooks.Add(misValue);
_excelWorksheet = _appExcel.ActiveWorkbook.ActiveSheet as Microsoft.Office.Interop.Excel.Worksheet;
// column names row (range obj)
Microsoft.Office.Interop.Excel.Range _columnsNameRange;
_columnsNameRange = _excelWorksheet.get_Range("A1", misValue).get_Resize(1, dataTable.Columns.Count);
// column names array to be assigned to _columnNameRange
string[] _arrColumnNames = new string[dataTable.Columns.Count];
for (int i = 0; i < dataTable.Columns.Count; i++)
{
// array of column names
_arrColumnNames[i] = dataTable.Columns[i].ColumnName;
}
// assign array to column headers range, make 'em bold
_columnsNameRange.set_Value(misValue, _arrColumnNames);
_columnsNameRange.Font.Bold = true;
// populate data content row by row
for (int Idx = 0; Idx < dataTable.Rows.Count; Idx++)
{
_excelWorksheet.Range["A2"].Offset[Idx].Resize[1, dataTable.Columns.Count].Value =
dataTable.Rows[Idx].ItemArray;
}
// Autofit all Columns in the range
_columnsNameRange.Columns.EntireColumn.AutoFit();
}
catch { throw; }
}
just pass dt as an argument.
Hope this may help.

How to send details of excel data in Detailview

I am developing an application that should extract excel data in a Gridview and show the details of individual data in a Detailsview. There is no use of SQL Server and sqlDataSource here. I am in dilemma though.
protected void btnViewDetail_Click(object sender, EventArgs e)
{
{
// What to write in here?
}
}
I have a button named 'View Detail' in GridView that should redirect me to Detailsview with the details of selected data.
Thanks.
Use this method for exporting datagridview to excel
parameters -> excel path, and grid name
public void exportExcel(string path, DataGridView dgv)
{
try
{
Microsoft.Office.Interop.Excel._Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
ExcelApp.Application.Workbooks.Add(Type.Missing);
ExcelApp.Columns.ColumnWidth = 10;
for (int j = 0; j < dgv.ColumnCount; j++)
{
ExcelApp.Cells[1, j + 1] = dgv.Columns[j].HeaderText;
}
Microsoft.Office.Interop.Excel.Range headerColumnRange = ExcelApp.get_Range("A1", "Z1");
headerColumnRange.Font.Bold = true;
headerColumnRange.Font.Color = 0xFF0000;
for (int i = 1; i < dgv.Rows.Count; i++)
{
//DataGridViewRow row = dataGridView1.Rows[i];
for (int j = 0; j < dgv.ColumnCount; j++)
{
ExcelApp.Cells[i + 1, j + 1] = dgv.Rows[i - 1].Cells[j].Value.ToString();
}
}
ExcelApp.ActiveWorkbook.SaveCopyAs(path);
ExcelApp.ActiveWorkbook.Saved = true;
ExcelApp.Quit();
}
catch { }
}
You can use EasyXLS Excel library to extract data from the Excel file. The Excel can be imported into a DataSet and no SQL Server is required.
// Create an instance of the class that imports Excel files
ExcelDocument xls = new ExcelDocument();
// Import Excel file to DataTable
DataSet ds = xls.easy_ReadXLSXActiveSheet_AsDataSet("Excel.xlsx");
DataTable dataTable = ds.Tables[0];
// Set the GridView data
gridView.DataSource = dataTable;
If you have more than one sheet into your Excel file, you may check for more details on import Excel to Dataset in C#.

Display columns and rows after exporting data from gridview to excel

Hi all i am having a task to export gridview data to excel which i have done using the forums and articles available.
But i would like to display complete excel columns after the data was imported to excel, means expect the place occupied by the grid content i would like to display the remaining columns of the excel as it is.
Sample the normal way of exporting the we do in common is as follows
My requirement is to show as follows
I followed as per here
http://www.aspsnippets.com/Articles/Export-GridView-To-Word-Excel-PDF-CSV-Formats-in-ASP.Net.aspx
See your code to export you have removed the border of the excel generated in the code.
You can use the following code to do it
protected void btnExportCSV_Click(object sender, EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition",
"attachment;filename=GridViewExport.csv");
Response.Charset = "";
Response.ContentType = "application/text";
GridView1.AllowPaging = false;
GridView1.DataBind();
StringBuilder sb = new StringBuilder();
for (int k = 0; k < GridView1.Columns.Count; k++)
{
//add separator
sb.Append(GridView1.Columns[k].HeaderText + ',');
}
//append new line
sb.Append("\r\n");
for (int i = 0; i < GridView1.Rows.Count; i++)
{
for (int k = 0; k < GridView1.Columns.Count; k++)
{
//add separator
sb.Append(GridView1.Rows[i].Cells[k].Text + ',');
}
//append new line
sb.Append("\r\n");
}
Response.Output.Write(sb.ToString());
Response.Flush();
Response.End();
}
-->Return only hearder,not view data.Help Me !
Thank you !
Email:tsmcstcd#gmail.com

Categories