using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Text; using System.Web.UI.WebControls; using System.Web.UI; using System.ComponentModel; using System.Collections; using System.Collections.Specialized; using System.Web.UI.HtmlControls; using System.Drawing; using System.IO; namespace CustomControls { /// <summary> /// Classe : Grid /// Description : Classe étendue de GridView pour permettre l'export des données au format excel /// Utilisation : /// - Inclure en début de page aspx : <%@ Register TagPrefix="foo" Namespace="CustomControls" %> /// - Modifier le tag "" par "<foo:Grid></foo:Grid>" /// </summary> /// <example> /// <%@ Page Language="C#" %> /// <%@ Register TagPrefix="foo" Namespace="CustomControls" %> /// <html><form runat="server"> /// <foo:Grid ID="monNouveauGrid" runat="server" FileName="monFichierExcel"> /// /// <Columns> /// [...] /// </Columns> /// </foo:Grid> /// </form></html> /// </example> [ToolboxData("<{0}:Grid runat=server></{0}:Grid>")] [Designer(typeof(CustomControls.Grid))] public class Grid : GridView, IPostBackDataHandler, IPostBackEventHandler { // Id qui permet de savoir si l'utilisateur a cliqué sur le bouton d'export excel private string BoutonId { get { return this.UniqueID; } } [Bindable(true)] [Category("Comportement")] [DefaultValue(true)] [Localizable(true)] public Boolean ShowExportButton { get; set; } [Bindable(true)] [Category("Comportement")] [DefaultValue("")] [Localizable(true)] public string IdButtonExport { get { String s = (String)ViewState["IdButtonExport"]; return s; } set { ViewState["IdButtonExport"] = value; } } [Browsable(false), DefaultValue(null), Description("ButtonAdd"), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(Button))] public ImageButton ButtonAdd { get { return _ButtonAdd; } set { _ButtonAdd = value; } } private ImageButton _ButtonAdd; [Browsable(false), DefaultValue(null), Description("ButtonAdd"), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(Button))] public ImageButton ButtonImport { get { return _ButtonImport; } set { _ButtonImport = value; } } private ImageButton _ButtonImport; // Liste des noms des colonnes a masquer (séparé par des virgule) [Bindable(true)] [Category("Comportement")] [DefaultValue("")] [Localizable(true)] public string HideColumns { get { String s = (String)ViewState["HideColumns"]; return s; } set { ViewState["HideColumns"] = value; } } [Bindable(true)] [Category("Comportement")] [DefaultValue("")] [Localizable(true)] public string ColumnsTypeNumber { get { String s = (String)ViewState["ColumnsTypeNumber"]; return s; } set { ViewState["ColumnsTypeNumber"] = value; } } // Nom du fichier pour exporter les données du GridView [Bindable(true)] [Category("Comportement")] [DefaultValue("fichier")] [Localizable(true)] public string FileName { get { String s = (String)ViewState["FileName"]; return ((s == null) ? "fichier" : s); } set { ViewState["FileName"] = value; } } // Nom de l'auteur du fichier exporté [Bindable(true)] [Category("Comportement")] [DefaultValue("")] [Localizable(true)] public string FileAuthor { get { String s = (String)ViewState["FileAuthor"]; return s; } set { ViewState["FileAuthor"] = value; } } // Description du fichier exporté [Bindable(true)] [Category("Comportement")] [DefaultValue("")] [Localizable(true)] public string FileDesc { get { String s = (String)ViewState["FileDesc"]; return s; } set { ViewState["FileDesc"] = value; } } // Url pour l'image du bouton d'export des données du GridView [Bindable(true)] [Category("Apparence")] [DefaultValue("")] [Localizable(true)] public string ImageExport { get { String s = (String)ViewState["ImageExport"]; return ((s == null) ? "../../App_Themes/default/images/xlexport.png" : s); } set { ViewState["ImageExport"] = value; } } // Constructeur par défaut public Grid() { GridLines = GridLines.Vertical; BackColor = Color.White; HeaderStyle.CssClass = "txtbloc"; FooterStyle.CssClass = "txtbloc"; HeaderStyle.HorizontalAlign = HorizontalAlign.Center; FooterStyle.HorizontalAlign = HorizontalAlign.Center; RowStyle.HorizontalAlign = HorizontalAlign.Center; ShowFooter = true; } public static T FindControlRec<T>(Control startingControl, string id) where T : Control { // this is null by default T found = default(T); int controlCount = startingControl.Controls.Count; if (controlCount > 0) { for (int i = 0; i < controlCount; i++) { Control activeControl = startingControl.Controls[i]; if (activeControl is T) { found = startingControl.Controls[i] as T; if (string.Compare(id, found.ID, true) == 0) break; else found = null; } else { found = FindControlRec<T>(activeControl, id); if (found != null) break; } } } return found; } public T FindControl<T>(Control parentControl, string id) where T : Control { var ctrl = parentControl; if (ctrl != null && !String.IsNullOrEmpty(id)) { if (id.Equals(ctrl.ID)) return ctrl as T; foreach (Control child in parentControl.Controls) { ctrl = FindControl<T>(child, id); if (ctrl != null) return ctrl as T; } } return null; } protected override DataSourceView GetData() { return base.GetData(); } // Avertit le contrôle serveur qu'il doit exécuter toutes les étapes de pré-rendu nécessaires protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); this.Page.RegisterRequiresRaiseEvent(this); } // Affiche le bouton d'exportation des données du GridView public void RenderContent(HtmlTextWriter writer) { if (!String.IsNullOrEmpty(IdButtonExport)) { try { ImageButton btExport = FindControl((Control)Page.Form, "bttoexport"); if (btExport != null) btExport.Click += new ImageClickEventHandler(ButtonExport_Click); } catch (Exception e) { Page.Response.Write(e); } } if ((ShowExportButton || String.IsNullOrEmpty(IdButtonExport)) && this.Rows.Count > 0) { // affichage du nombre de ligne //writer.Write(" Nombre de ligne : "+ this.Rows.Count.ToString() + " "); writer.AddAttribute(HtmlTextWriterAttribute.Name, this.BoutonId); writer.AddAttribute(HtmlTextWriterAttribute.Value, " "); writer.AddAttribute(HtmlTextWriterAttribute.Title, "Exporter le tableau"); writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit"); writer.AddAttribute(HtmlTextWriterAttribute.Style, "border : none ; background : url(" + ImageExport + ") left top no-repeat;"); writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer"); writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "24px"); writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "24px"); writer.RenderBeginTag(HtmlTextWriterTag.Input); writer.RenderEndTag(); } if (this.Rows.Count == 0) { writer.AddAttribute(HtmlTextWriterAttribute.Style, "text-align:center;font-style:italic;"); writer.RenderBeginTag(HtmlTextWriterTag.Div); if (this.ID != "GridConvetions" || this.ID != "GridViewListLotParMission") { writer.Write(Resources.Lang.AucunResultat); } writer.RenderEndTag(); } if (_ButtonAdd != null) { if (String.IsNullOrEmpty(_ButtonAdd.ImageUrl) && _ButtonAdd != null) { _ButtonAdd.ImageUrl = "../../App_Themes/default/images/add.png"; } this.Controls.AddAt(0, _ButtonAdd); } if (_ButtonImport != null) { this.Controls.AddAt(0, _ButtonImport); } } // Affiche le control Grid de la classe protected override void RenderContents(HtmlTextWriter writer) { RenderContent(writer); base.RenderContents(writer); } protected override void RaisePostBackEvent(string eventArgument) { base.RaisePostBackEvent(eventArgument); } // Gère la gestion du clique sur le bouton d'export du controle bool IPostBackDataHandler.LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) { if (!string.IsNullOrEmpty(postCollection[this.BoutonId])) { // oui, le bouton export a été cliqué donc on créé le fichier excel contenant les données du GridView Export(FileName + ".xls", this, this.FileAuthor, this.FileDesc); } return false; } public void ButtonExport_Click(object sender, ImageClickEventArgs e) { Export(FileName + ".xls", this, this.FileAuthor, this.FileDesc); } // Méthode pour la création du fichier Excel public void Export(string fileName, GridView gv, String FileAuthor, String FileDesc) { gv.AllowPaging = false; gv.DataBind(); HttpContext.Current.Response.Clear(); HttpContext.Current.Response.AddHeader( "content-disposition", string.Format("attachment; filename={0}", fileName)); HttpContext.Current.Response.ContentType = "application/ms-excel"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; HttpContext.Current.Response.Charset = "utf-8"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Default; // toutes mes cellules seront au format texte. string style = @"<style> .text { mso-number-format:\@;text-align:left; } </style> "; HttpContext.Current.Response.Write(style); using (StringWriter sw = new StringWriter()) { using (HtmlTextWriter htw = new HtmlTextWriter(sw)) { // Create a table to contain the grid Table table = new Table(); // Colonne.Visible = false List hiddenColomn = new List(); // Colonne a masquer defini par l'utilisateur String[] hiddenColomnByUser = new String[0]; if (!String.IsNullOrEmpty(HideColumns)) { hiddenColomnByUser = HideColumns.Split(','); } // Colonne a masquer defini par l'utilisateur String[] ColomnTypeNumberByUser = null; if (!String.IsNullOrEmpty(ColumnsTypeNumber)) { ColomnTypeNumberByUser = ColumnsTypeNumber.Split(','); } GridViewRow headerRow = new GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal); headerRow.Font.Bold = true; if (!String.IsNullOrEmpty(FileDesc)) { TableCell descCell = new TableCell(); descCell.Text = FileDesc; descCell.ColumnSpan = 3; headerRow.Cells.Add(descCell); } if (!String.IsNullOrEmpty(FileAuthor)) { TableCell authorCell = new TableCell(); authorCell.Text = FileAuthor; headerRow.Cells.Add(authorCell); } TableCell dateCell = new TableCell(); dateCell.Text = DateTime.Now.Day + "/" + DateTime.Now.Month + "/" + DateTime.Now.Year + " " + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second; headerRow.Cells.Add(dateCell); table.Rows.Add(headerRow); // include the gridline settings table.GridLines = gv.GridLines; // add the header row to the table foreach (DataControlField col in gv.Columns) { try { if (hiddenColomnByUser.Contains(((System.Web.UI.WebControls.BoundField)(col)).DataField)) { col.Visible = false; } } catch { col.Visible = true; } if (!col.Visible) { hiddenColomn.Add(gv.Columns.IndexOf(col)); if (gv.HeaderRow != null) gv.HeaderRow.Cells[gv.Columns.IndexOf(col)].Visible = false; if (gv.FooterRow != null) gv.FooterRow.Cells[gv.Columns.IndexOf(col)].Visible = false; foreach (TableRow rowVisible in gv.Rows) { rowVisible.Cells[gv.Columns.IndexOf(col)].Visible = false; } } else { if (gv.HeaderRow != null) gv.HeaderRow.Cells[gv.Columns.IndexOf(col)].Visible = true; if (gv.FooterRow != null) gv.FooterRow.Cells[gv.Columns.IndexOf(col)].Visible = true; foreach (TableRow rowVisible in gv.Rows) { rowVisible.Cells[gv.Columns.IndexOf(col)].Visible = true; if (ColomnTypeNumberByUser != null && ColomnTypeNumberByUser.Contains<String>(col.HeaderText)) { rowVisible.Cells[gv.Columns.IndexOf(col)].Attributes.Add("class", "text"); } } } } // add the header row to the table if (gv.HeaderRow != null) { PrepareControlForExport(gv.HeaderRow); table.Rows.Add(gv.HeaderRow); } foreach (GridViewRow row in gv.Rows) { PrepareControlForExport(row); TableRow rowTmp = new TableRow(); table.Rows.Add(row); } // add the footer row to the table if (gv.FooterRow != null) { PrepareControlForExport(gv.FooterRow); table.Rows.Add(gv.FooterRow); } // render the table into the htmlwriter table.RenderControl(htw); // render the htmlwriter into the response HttpContext.Current.Response.Write(sw.ToString()); HttpContext.Current.Response.End(); } } } // Remplace n'importe quel controle spécial (ex:DropDownList) par un litéral corespondant private static void PrepareControlForExport(Control control) { for (int i = 0; i < control.Controls.Count; i++) { Control current = control.Controls[i]; if (current is LinkButton) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text)); } else if (current is ImageButton) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText)); } else if (current is System.Web.UI.WebControls.Image) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl("")); } else if (current is HyperLink) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text)); } else if (current is DropDownList) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text)); } else if (current is CheckBox) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False")); } //else if (current is System.Web.UI.WebControls.Image) //{ // control.Controls.Remove(current); //} if (current.HasControls()) { PrepareControlForExport(current); } } } void IPostBackDataHandler.RaisePostDataChangedEvent() { // non utilisé } } }