简体   繁体   中英

TableRow styling for Export To Excel

I have following code that I am using for export to excel of a gridview. I am adding the gridview rows into System.Web.UI.WebControls.Table. Now, I need to apply background color to the header and data rows in the exported excel (There are two header rows).

I tired the following. It is not providing the desired result.

Issues of current solution

  1. One header row does not have background color
  2. Coloring is applied to cells that does not have data (cells “H”, “I”, etc.)

How can we correct it?

在此处输入图片说明

Note: I am trying to learn the export feature. So, please don't suggest to use any third party controls. I am just exploring all features of this approach.

I am adding the header grouping to the original gridview using following code.

protected void gvCustomers_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        System.Text.StringBuilder sbNewHeader = new StringBuilder();
        sbNewHeader.AppendFormat("&nbsp;</th>" +
            "<th colspan='2' class='tableColGroupAssociate'>Associate Info <a href='#' class='associateHide'> Hide </a> </th>" +
            "<th colspan='2' class='tableColGroupTransaction'>Financial Info <a href='#' class='financialHide'> Hide </a> </th>" +
            "<th colspan='2' class='tableColGroupDailyTax'>Tax Info <a href='#' class='dailyTaxHide'> Hide </a> </th>"
            + "</tr>");
        sbNewHeader.AppendFormat("<tr class='{0}'><th>{1}", this.gvCustomers.HeaderStyle.CssClass, e.Row.Cells[0].Text);
        e.Row.Cells[0].Text = sbNewHeader.ToString();
    }
}

Complete Code

public static void Export(GridView gv)
{
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", "MyExcelFile.xls"));
    HttpContext.Current.Response.ContentType = "application/ms-excel";

    using (StringWriter stringWriter = new StringWriter())
    {
        using (HtmlTextWriter tetxWriter = new HtmlTextWriter(stringWriter))
        {

            System.Web.UI.WebControls.Table tableControl = new Table();
            tableControl.GridLines = gv.GridLines;

            //Before the next step - we can remove any controls inside the gridview and replace with literal control

            //  Add the header row to the table
            if (gv.HeaderRow != null)
            {
                TableRow tableRow = gv.HeaderRow;
                tableRow.Style[System.Web.UI.HtmlTextWriterStyle.BackgroundColor] = "Orange";
                tableControl.Rows.Add(gv.HeaderRow);
            }

            //  Add each of the data rows to the table
            foreach (GridViewRow row in gv.Rows)
            {
                TableRow tableRow = row;
                tableRow.Style[System.Web.UI.HtmlTextWriterStyle.BackgroundColor] = "Yellow";
                tableControl.Rows.Add(row);
            }


            //  Render the table into the htmlwriter
            tableControl.RenderControl(tetxWriter);

            //  Render the htmlwriter into the response
            HttpContext.Current.Response.Write(stringWriter.ToString());
            HttpContext.Current.Response.End();


        }
    }
}

EDIT

Based on comment from Ankit, I tried the following; still the result is not as expected.

            if (gv.HeaderRow != null)
            {
                TableRow tableRow = gv.HeaderRow;

                foreach (TableCell cell in tableRow.Cells)
                {
                    cell.Style[System.Web.UI.HtmlTextWriterStyle.BackgroundColor] = "Orange";
                }
                tableControl.Rows.Add(gv.HeaderRow);
            }

在此处输入图片说明


If you want more control over how your excel files are written take a look at ClosedXML

Adding a table is as simple as

var wb = new XLWorkbook();
wb.Worksheets.Add(myDataTable);
wb.SaveAs("MySheet.xlsx");

Using the API you can code like this:

var rngTable = ws.Range("B2:F6");
rngTable.FirstCell().Style
    .Font.SetBold()
    .Fill.SetBackgroundColor(XLColor.CornflowerBlue)
    .Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center);

I figured a way to do it... For the benefit of others I will post it here:

References:

  1. ASP.NET Excel export encoding problem

在此处输入图片说明

Other Note: When a new Table is created TableSection can be used to define header

 newRow.TableSection = TableRowSection.TableHeader;

CODE

//Changed the logic used for adding dynamic header for HTML rendering:

protected void gvCustomers_RowCreated(object sender, GridViewRowEventArgs e)
{

    if (e.Row.RowType == DataControlRowType.Header)
    {
        GridViewRow newHeaderRow = new GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);

        TableCell cell1 = new TableHeaderCell();
        cell1.ColumnSpan = 1; //e.Row.Cells.Count;
        cell1.Text = "";

        TableCell cell2 = new TableCell();
        cell2.ColumnSpan = 2;
        cell2.Text = "One";

        TableCell cell3 = new TableCell();
        cell3.ColumnSpan = 2;
        cell3.Text = "Two";

        TableCell cell4 = new TableCell();
        cell4.ColumnSpan = 2;
        cell4.Text = "Three";

        newHeaderRow.Cells.Add(cell1);
        newHeaderRow.Cells.Add(cell2);
        newHeaderRow.Cells.Add(cell3);
        newHeaderRow.Cells.Add(cell4);

        ((GridView)sender).Controls[0].Controls.AddAt(0, newHeaderRow);
    }

    if (e.Row.RowType == DataControlRowType.Header)
    {

        //System.Text.StringBuilder sbNewHeader = new StringBuilder();
        //sbNewHeader.AppendFormat("&nbsp;</th>" +
        //    "<th colspan='2' class='tableColGroupAssociate'>Associate Info <a href='#' class='associateHide'> Hide </a> </th>" +
        //    "<th colspan='2' class='tableColGroupTransaction'>Financial Info <a href='#' class='financialHide'> Hide </a> </th>" +
        //    "<th colspan='2' class='tableColGroupDailyTax'>Tax Info <a href='#' class='dailyTaxHide'> Hide </a> </th>"
        //    + "</tr>");
        //sbNewHeader.AppendFormat("<tr class='{0}'><th>{1}", this.gvCustomers.HeaderStyle.CssClass, e.Row.Cells[0].Text);
        //e.Row.Cells[0].Text = sbNewHeader.ToString();


    }

}

//Export Logic - Applied similar logic once again

public static void Export(GridView gv)
{
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", "MyExcelFile.xls"));
    HttpContext.Current.Response.ContentType = "application/ms-excel";


    //Response.ContentEncoding = System.Text.Encoding.Unicode;
    //Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());


    using (StringWriter stringWriter = new StringWriter())
    {
        using (HtmlTextWriter tetxWriter = new HtmlTextWriter(stringWriter))
        {

            System.Web.UI.WebControls.Table tableControl = new Table();
            tableControl.GridLines = gv.GridLines;

            //  Add the header row to the table
            if (gv.HeaderRow != null)
            {
                ReplaceControlForExport(gv.HeaderRow);


                #region Dynamic Frrst Header Row

                TableRow newRow = new TableRow();

                TableCell cell1 = new TableHeaderCell();
                cell1.ColumnSpan = 1; 
                cell1.Text = "";

                TableCell cell2 = new TableCell();
                cell2.ColumnSpan = 2;
                cell2.Text = "One";

                TableCell cell3 = new TableCell();
                cell3.ColumnSpan = 2;
                cell3.Text = "Two";

                TableCell cell4 = new TableCell();
                cell4.ColumnSpan = 2;
                cell4.Text = "Three";

                newRow.Cells.Add(cell1);
                newRow.Cells.Add(cell2);
                newRow.Cells.Add(cell3);
                newRow.Cells.Add(cell4);

                foreach (TableCell cell in newRow.Cells)
                {
                    cell.Style[System.Web.UI.HtmlTextWriterStyle.BackgroundColor] = "Purple";
                }
                tableControl.Rows.Add(newRow);

                #endregion 

                TableRow originalHeaderRow = gv.HeaderRow;
                foreach (TableCell cell in originalHeaderRow.Cells)
                {
                    cell.Style[System.Web.UI.HtmlTextWriterStyle.BackgroundColor] = "Orange";
                }
                tableControl.Rows.Add(originalHeaderRow);
            }


            //  Add each of the data rows to the table
            foreach (GridViewRow row in gv.Rows)
            {
                ReplaceControlForExport(row);

                TableRow tableRow = row;
                foreach (TableCell cell in tableRow.Cells)
                {
                    cell.Style[System.Web.UI.HtmlTextWriterStyle.BackgroundColor] = "Yellow";
                }
                tableControl.Rows.Add(row);
            }


            //  Render the table into the htmlwriter
            tableControl.RenderControl(tetxWriter);

            //  Render the htmlwriter into the response
            HttpContext.Current.Response.Write(stringWriter.ToString());
            HttpContext.Current.Response.End();


        }
    }
  }

 private static void ReplaceControlForExport(Control mainControlElement)
 {
    for (int i = 0; i < mainControlElement.Controls.Count; i++)
    {
        Control currentControl = mainControlElement.Controls[i];

        if (currentControl is LinkButton)
        {
            mainControlElement.Controls.Remove(currentControl);
            mainControlElement.Controls.AddAt(i, new LiteralControl((currentControl as LinkButton).Text));
        }
        else if (currentControl is ImageButton)
        {
            mainControlElement.Controls.Remove(currentControl);
            mainControlElement.Controls.AddAt(i, new LiteralControl((currentControl as ImageButton).AlternateText));
        }
        else if (currentControl is HyperLink)
        {
            mainControlElement.Controls.Remove(currentControl);
            mainControlElement.Controls.AddAt(i, new LiteralControl((currentControl as HyperLink).Text));
        }
        else if (currentControl is DropDownList)
        {
            mainControlElement.Controls.Remove(currentControl);
            mainControlElement.Controls.AddAt(i, new LiteralControl((currentControl as DropDownList).SelectedItem.Text));
        }
        else if (currentControl is CheckBox)
        {
            mainControlElement.Controls.Remove(currentControl);
            mainControlElement.Controls.AddAt(i, new LiteralControl((currentControl as CheckBox).Checked ? "True" : "False"));
        }

        //Recursive Call
        if (currentControl.HasControls())
        {
            ReplaceControlForExport(currentControl);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM