Override the render for the ASP.NET page. Look through all the controls (See my other tiptrick for iterating controls).
Notes:
- You will probably need to handle itemtemplates in your grid/details views if you use anything other than a
string
literal.
- I put all detailsViews on the first page and grids on their own worksheet as that was my need but you probably won't want it exactly that way.
Note: Utilities.FindControls is located here:
Findcontrol using a non recursive approach with no new fangled crap.[
^]
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
Workbook workBook = new Workbook();
List<control> controlList = Utilities.FindControls(this);
int detailsRowStart = 0;
Worksheet detailsSheet = workBook.Worksheets.Add("Details");
detailsSheet.Columns[0].Width = 8000;
foreach (var item in controlList )
{
if (item.GetType() == typeof(GridView))
{
Utilities.RenderControlInExcel((GridView)item, workBook);
}
if (item.GetType() == typeof(DetailsView))
{
detailsRowStart = Utilities.RenderControlInExcel((DetailsView)item, detailsSheet, detailsRowStart);
}
}
ExcelExporter.WriteToResponse(workBook,String.Format( "report{0}.xls", Guid.NewGuid().ToString()), Response);
}
Render the
gridview detailsview
:
public static void RenderControlInExcel(GridView view, Workbook book)
{
if (view.Rows.Count == 0 || view.Columns.Count==0)
{
return;
}
Worksheet workSheet = book.Worksheets.Add(view.ID);
for (int i = 0; i < view.Columns.Count; ++i)
{
WorksheetCell cell = workSheet.Rows[0].Cells[i];
cell.Value = view.Columns[i].HeaderText;
cell.CellFormat.Font.Bold =ExcelDefaultableBoolean.True;
}
const int HeaderOffset = 1;
for (int row = 0; row < view.Rows.Count; ++row)
{
for (int col = 0; col < view.Columns.Count; ++col)
{
int destRow = row + HeaderOffset;
try
{
if (view.Rows[row].Cells[col].Controls.Count > 0)
{
if (view.Rows[row].Cells[col].Controls[0].GetType() == typeof(DataBoundLiteralControl))
{
workSheet.Rows[destRow].Cells[col].Value = ((System.Web.UI.DataBoundLiteralControl)(view.Rows[row].Cells[col].Controls[0])).Text.Trim();
}
}
else
{
if (view.Rows[row].Cells[col].Text == " ")
{
continue;
}
workSheet.Rows[destRow].Cells[col].Value = view.Rows[row].Cells[col].Text;
}
}
catch
{
workSheet.Rows[destRow].Cells[col].Value = "Error";
}
}
}
}
}
public static int RenderControlInExcel(DetailsView view, Worksheet workSheet, int rowStart )
{
if (view.Rows.Count == 0 )
{
return rowStart;
}
++rowStart;
WorksheetCell cell = workSheet.Rows[rowStart].Cells[0];
cell.Value = view.HeaderRow.Cells[0].Text;
cell.CellFormat.Font.Bold = ExcelDefaultableBoolean.True;
++rowStart;
for (int row=0; row < view.Rows.Count; ++row)
{
for (int col = 0; col <view.rows[row].cells.count;> {
int destRow = rowStart + row;
if (view.Rows[row].Cells[col].Controls.Count > 0)
{
if (view.Rows[row].Cells[col].Controls[0].GetType() == typeof(DataBoundLiteralControl))
{
workSheet.Rows[destRow].Cells[col].Value = ((System.Web.UI.DataBoundLiteralControl)(view.Rows[row].Cells[col].Controls[0])).Text.Trim();
}
}
else
{
if (view.Rows[row].Cells[col].Text == " ")
{
continue;
}
workSheet.Rows[destRow].Cells[col].Value = view.Rows[row].Cells[col].Text;
}
}
}
rowStart += view.Rows.Count;
return rowStart;
}
Write with infragistics Excel object (could be rewritten easily).
public static void WriteToResponse(Workbook theWorkBook, string FileName, HttpResponse resp)
{
System.IO.MemoryStream theStream = new System.IO.MemoryStream();
if (theWorkBook.Worksheets.Count == 0)
{
return;
}
BIFF8Writer.WriteWorkbookToStream(theWorkBook, theStream);
byte[] byteArr = (byte[])Array.CreateInstance(typeof(byte), theStream.Length);
theStream.Position = 0;
theStream.Read(byteArr, 0, (int)theStream.Length);
theStream.Close();
resp.Clear();
resp.AddHeader("content-disposition", "attachment; filename=" + FileName);
resp.BinaryWrite(byteArr);
resp.End();
}