Wednesday, May 4, 2016

Make Excel sheets exported from DevExpress MVC grids hide and rearrange columns based upon how the user hides and rearranges columns at the grid itself.

more settings here... columns are defined, etc. in black copy at the link's blog posting is a place where one fills in columns at a grid. These now need to be hydrated like so:

settings.KeyFieldName = "CustomerID";
foreach (string column in GridViewPartialViewColumns.Get())
{
   settings.Columns.Add(column);
}
settings.ClientLayout = (sender, e) =>
{
   if (e.LayoutMode == ClientLayoutMode.Saving)
   {
      ReportExporter.BackingStore = (MVCxGridView)sender;
   }
};

 
 

We need to pull the master list of columns in default order from a second place. Let's do something like so:

using System.Collections.Generic;
namespace MoreModernModernity.Views.Home
{
   public static class GridViewPartialViewColumns
   {
      public static List<string> Get()
      {
         return new List<string>()
         {
            "ContactName",
            "CompanyName",
            "ContactTitle",
            "City",
            "Phone"
         };
      }
   }
}

 
 

The ReportExporter class I offer here need to be significantly overhauled.

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using DevExpress.Web.Mvc;
using DevExpress.XtraPrinting;
using Modernity.Views.Home;
namespace Modernity.Models
{
   public static class ReportExporter
   {
      public static MVCxGridView BackingStore { get; set; }
      
      private static GridViewSettings PrepareSettings()
      {
         int counter = 0;
         Dictionary<int, Tuple<int, bool>> instructions = new Dictionary<int, Tuple<int,
               bool>>();
         while (counter < BackingStore.Columns.Count)
         {         
            instructions.Add(BackingStore.Columns[counter].VisibleIndex,new
                  Tuple<int,bool>(counter,BackingStore.Columns[counter].Visible));
            counter++;
         }
         var settings = new GridViewSettings();
         settings.Name = "grid";
         settings.KeyFieldName = BackingStore.KeyFieldName;
         foreach (string column in Rearrange(GridViewPartialViewColumns.Get(),
               instructions))
         {
            settings.Columns.Add(column);
         }
         return settings;
      }
      
      private static List<string> Rearrange(List<string> defaultColumns, Dictionary<int,
            Tuple<int, bool>> instructions)
      {
         List<string> newColumns = new List<string>();
         int counter = 0;
         foreach (string defaultColumn in defaultColumns)
         {
            if (instructions[counter].Item2)
            {
               newColumns.Add(defaultColumns[instructions[counter].Item1]);
            }
            counter++;
         }
         return newColumns;
      }
      
      public static ActionResult MakeExcelSheet(Object data)
      {
         GridViewSettings settings = PrepareSettings();
         ActionResult actionResult = GridViewExtension.ExportToXls(settings, data,
               new XlsExportOptionsEx { ExportType =
               DevExpress.Export.ExportType.WYSIWYG });
         return actionResult;
      }
   }
}

 
 

This could be more elegant. BackingStore could be a dictionary of MVCxGridView types that one could look up by magic string names such as "Home" which would allow thus to scale beyond one implemenation. I guess it needs love in other places too if that is to work. GridViewPartialViewColumns needs some sort of inheritance implementation, etc.

No comments:

Post a Comment