Sometimes you just need to clone a data grid.

In my case, I was recently working on a piece of code that uses the wonderful as3xls library to create Excel spreadsheets. As they stood in the code, the data grids were in no condition to go straight to Excel. There were label functions. Custom renderers. All sorts of things that made the grids look fantastic in the application, and like total shit in Excel.

As a result, I needed to do all sorts of tweaks and modifications to the data grids, but I couldn’t go and muck up the actual grids in use. This is where my ExportableDataGrid class comes into play.

ExportableDataGrid extends AdvancedDataGrid and adds a single export() method. This left me free to modify the exported data grid to make it suitable for Excel without affecting the original.

Unfortunately you can’t do a simple deep copy of an AdvancedDataGrid, so you have to take care of a few things individually.

Here’s the class I came up with:

public class ExportableDataGrid extends AdvancedDataGrid
{
    public function ExportableDataGrid ()
    {
        super ();
    }

    public function export (prependText : Boolean, postpendText
        : Boolean) : AdvancedDataGrid
    {
        var grid : AdvancedDataGrid = new AdvancedDataGrid ();

        grid.dataProvider = this.dataProvider;
        grid.headerRenderer = this.headerRenderer;
        grid.labelFunction = this.labelFunction;
        grid.groupedColumns = new Array ();

        for each (var column : AdvancedDataGridColumn in
            this.groupedColumns)
        {
            if (column is AdvancedDataGridColumnGroup)
            {
                for each (var subcolumn : AdvancedDataGridColumn in
                    (column as AdvancedDataGridColumnGroup).children)
                {
                    var clone : AdvancedDataGridColumn =
                        subcolumn.clone ();

                    if (prependText)
                    {
                        clone.headerText = column.headerText + " " +
                            clone.headerText;
                    }
                    else if (postpendText)
                    {
                        clone.headerText = clone.headerText + " " +
                            column.headerText;
                    }

                    grid.groupedColumns.push (clone);
                }
            }
            else
            {
                grid.groupedColumns.push (column.clone ());
            }
        }

        return grid;
    }
}


As you can see, this method can handle simple grids as well as more advanced ones with nested column groups. While the above method is designed to support only a single column group (all I needed), with a bit of refactoring and some good ol’ recursion you can easily support any number of nested groups.

Since the groups are flattened, I also added the option to pre-or-postpend the header text from the column group onto each nested column.

And while it’s mostly built to support a niche feature, you could also use this sort of approach to prepare a data grid to be printed or saved as a PDF file.