//-----------------------------------------------------------
  extensions to hide/show/sort columns of a grid
  edited by: Safaa AlNabulsi
//-----------------------------------------------------------
we customized "ecolumns" extension to be able to handle many languages and

two buttons were added "select all/unselect all" ..

Here's a "step by step" article that shows how to use it :

1- unzip file and put it in /protected/extensions/
2- take the files in  /protected/extensions/ecolumns/assets/messages and put them in your project
3- add this code to your view before grid code:
 $dialog = $this->widget('ext.ecolumns.EColumnsDialog', array(
                'options' => array(
                    'title' => Yii::t('ecolumns_messages','Layout Settings'),
                    'autoOpen' => false,
                    'show' => 'fade',
                    'hide' => 'fade',
                    'width' =>'320px'
                ),
                'htmlOptions' => array('style' => 'display: none'), //disable flush of dialog content
                'ecolumns' => array(
                    'gridId' => 'grid_id', //id of related grid
                    'storage' => 'session', //where to store settings: 'db', 'session', 'cookie'
                    'fixedLeft' => array('CCheckBoxColumn'), //fix checkbox to the left side
                    'model' => $model, //model is used to get attribute labels
                    'columns' => array(
                       // --------
                    )
                )
            ));

    $this->widget('yiiwheels.widgets.grid.WhGridView', array(
        'id' => 'grid_id',
        'filter' => $model,
        'fixedHeader' => false,
        'headerOffset' => 40, // 40px is the height of the main navigation at bootstrap
        'type' => 'striped bordered',
        'dataProvider' => $model->search(),
        'columns' => $dialog->columns(),
        'template' => $dialog->link() . "{summary}\n{items}\n{pager}",
      )
    );

//------------------------------------------------------------------------------------
if you want this to be reflected on your "export to excel" action :

1- add this action to the controller you want to use
  /**
     * This function is responsible for getting normalized columns to give them to criteria
     * @param Object $model model we want to get its attribute
     * @param string $session_var columns that user has changed in the view and want them to be displayed
     * @param array $configured_attributes attributes with properties
     * @return string normalized columns to give them to criteria
     * @author Safaa AlNabulsi
     */
    public function format_columns($model, $session_var, $configured_attributes) {
        //variables
        $attributes = array();
        $header = array();
        $column = "";
        //---------------------------------------------
        //remove the button column from string of columns
        $columns = str_replace(",CButtonColumn", "", $session_var);
        //extract attributes from string and get its properties from $configured_attributes array
        $current_attributes = explode(",", $columns);
        $configured_attributes_keys = array_keys($configured_attributes);
        foreach ($current_attributes as $value) {
            if (in_array($value, $configured_attributes_keys)) {
                $attributes[$value] = $configured_attributes[$value];
            }
        }
        //---------------------------------------------
        //start formation attributes according to its types
        foreach ($attributes as $attribute => $properties) {
            //columns we don't want them to be shown in excel like "details"
            if (in_array('ignored', $properties)) {
                continue;
            }
            //---------------------------------------------
            //columns with boolean type is prefered to be shown as "yes","No" , better that 0,1
            if (in_array('boolean', $properties)) {
                $header[$attribute] = $this->getLabel($model, $attribute);
                //when there's relation with other tables that have same columns,
                //we have to add"t" to point that we want the column from current table
                if (in_array('t', $properties)) {
                    $attribute = 't.' . $attribute;
                }
                Yii::app()->session['lang'] == "en" ? $yes = 'Yes' : $yes = 'نعم';
                Yii::app()->session['lang'] == "en" ? $no = 'No' : $no = 'لا';
                $attribute = 'CASE ' . $attribute . "    WHEN 'True' THEN '" . $yes . "'
                            WHEN 'False' THEN '" . $no . "'
                            END";
                $column = $column . $attribute . ',';
                continue;
            }
            //---------------------------------------------
            //when there's relation with other tables that have same columns,
            //we have to add"t" to point that we want the column from current table
            if (in_array('t', $properties)) {
                $header[$attribute] = $this->getLabel($model, $attribute);
                $attribute = 't.' . $attribute;
            }
            //---------------------------------------------
            //columns with relation need to specify the refernced table and its attribute
            if (in_array('relation', $properties)) {
                $key = $properties['relation_attributes']['tbl'] . "." . $properties['relation_attributes']['col'];
                $header[$key] = $this->getLabel($model, $attribute);
                $attribute = $key . " as " . $attribute;
            }

            //---------------------------------------------
            //this part is used fot SQLSERVER datetime to remove time from it and show just date
            if (in_array('datetime', $properties)) {
                $header[$attribute] = $this->getLabel($model, $attribute);
                $attribute = 'CONVERT(' . $properties['datetime_attributes']['type'] . ',[' . $attribute . '],' . $properties['datetime_attributes']['size'] . ')';
            }
            //---------------------------------------------
            //when column is a query
            if (in_array('query', $properties)) {
                $header[$attribute] = $this->getLabel($model, $attribute);
                $attribute = $properties['query_sql'];
            }
            //---------------------------------------------
            //it should remain the last one beacuse alias always comes in the end of column
            if (in_array('alias', $properties)) {
                $attribute = $attribute . ' as ' . $properties['alias_name'];
            }
            //---------------------------------------------

            $column = $column . $attribute . ',';
        }
        $column = trim($column, ',');
        return array('header' => $header, 'columns' => $column);
    }

    /**
     * This function is responsible for getting normalized label
     * @param Object $model model we want to get its attribute
     * @param string $attribute attribute of the model
     * @return string label of given attribute
     * @author Safaa AlNabulsi
     */
    function getLabel($model, $attribute) {
        //when header defined like this:
        //'shareholder_identifier' => yii::t('default', 'Shareholder') . "<font class='red-star' color='#B94A48'> * </font>",
        $attr_header = $model->getAttributeLabel($attribute);
        $res = explode("<", $attr_header);
        return $res[0];
    }

2- in your controller "export to excel" action you have to define and configure attributes like this:
  $configured_attributes['shareholder_identifier'] = array('relation', 'relation_attributes' => array('tbl' => 'shareholder', 'col' => 'full_name'));
        $configured_attributes['communication_type_id'] = array('relation', 'relation_attributes' => array('tbl' => 'communication_type', 'col' => 'name'));
        $configured_attributes['date'] = array('datetime', 'datetime_attributes' => array('type' => 'VARCHAR(25)', 'size' => '105'), 'alias', 'alias_name' => 'date');
        $configured_attributes['description'] = array('t');
        $configured_attributes['subject'] = array('t');
        $configured_attributes['is_outgoing'] = array('t', 'boolean');
        $configured_attributes['details'] = array('ignored');
        $query1 = "  STUFF(
         (SELECT ', ' + t1.full_name
          from shareholder as t1
          inner join shareholder_communication on shareholder_communication.shareholder_id = t1.id and shareholder_communication.communicaiton_id = t.id and shareholder_communication.is_deleted=0
          inner join communication on communication.id = shareholder_communication.communicaiton_id and communication.is_deleted=0
          WHERE t1.id = shareholder_communication.shareholder_id
          FOR XML PATH (''))
          , 1, 1, '')  AS shareholder_communication_array";
        $configured_attributes['shareholder_communication_array'] = array('query', 'query_sql' => $query1);


3- and then call the previous function:
  $index = 'grid_id'. '_' . yii::app()->user->id;
   if (isset($_SESSION[$index])) {
            $result = $this->format_columns($model, $_SESSION['communication-grid_1'], $configured_attributes);
            $column = $result['columns'];
            $header = $result['header'];
        } else {
//export to excel default setting
}

enjoy it :)
//-----------------------------------------------------------------
References:

http://www.yiiframework.com/extension/ecolumns

 