Comunidad de diseño web y desarrollo en internet

Exportar datos de Flex a Excel

Buenas gente!

Cuántas veces nos toca exportar datos que se muestran en un datagrid/advanceddatagrid/olap a excel y siempre repetimos lo mismo, sólo se puede hacer desde backend (bueno, no es del todo cierto ya que con javascript se puede hacer a medias). Pero bueno ahora gracias a una librería que encontré en google code se pueden generar desde AS3 gracias a la clase ByteArray.

El proyecto de google code es: http://code.google.com/p/as3xls/ e intenta portar las especificaciones de las estructuras BIFF a AS3 (estructuras de los archivos excel brindadas por openoffice).

Estado de la librería: Recién acepta excel 2 (BIFF 2) por lo que solo se pueden manejar texto y tipos de datos de columna simple y algo de formulas.

Bueno... para mi trabajo tuve que generar exportaciones a excel de datos que se muestran en un datagrid y por ahora con este nivel de desarrollo de la librería me es suficiente.

Entonce creé un Util para utilizar la librería de forma mas sencilla, veamos como exportar los datos desde un datagrid

Ejemplo en Flex:

Código :

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
   xmlns:mx="http://www.adobe.com/2006/mxml" 
   layout="vertical">
   
   <mx:Script>
      <![CDATA[
         import com.kcc.tempos.utils.exporter.ExcelExporterUtil;
         import mx.collections.IViewCursor;
         import com.as3xls.xls.ExcelFile;
         import com.as3xls.xls.Sheet;
         import mx.collections.ArrayCollection;
         
         [Bindable]
         private var flat:ArrayCollection = new ArrayCollection([
                                 {nombre:"Andrés", apellido:"Sanchez"},
                                 {nombre:"Mónica", apellido:"Sanchez"},
                                 {nombre:"Agustina", apellido:"Sanchez"},
                                 {nombre:"Pablo", apellido:"Sanchez"},
                                 {nombre:"Magalí", apellido:"Sanchez"}
                                 ]);
                                 
         private function onExportToExcel():void
         {
            ExcelExporterUtil.dataGridExporter(this.dg, "prueba_excel.xls");
         }
         
      ]]>
   </mx:Script>
   
   <mx:DataGrid id="dg" dataProvider="{flat}">
      <mx:columns>
         <mx:DataGridColumn dataField="nombre" headerText="Nombre" />
         <mx:DataGridColumn dataField="apellido" headerText="Apellido" />
      </mx:columns>
   </mx:DataGrid>
   
   <mx:Button label="Export" click="onExportToExcel();" />
   
</mx:Application>


Esta no es la única funcionalidad, sino que puede exportar cualquier cosa, un array, arraycollecion, xml, xmllist, etc.

Aca les dejo la clase

Código :

package com.kcc.tempos.utils.exporter
{
   import com.as3xls.xls.ExcelFile;
   import com.as3xls.xls.Sheet;
   
   import flash.errors.IllegalOperationError;
   import flash.net.FileReference;
   import flash.utils.ByteArray;
   
   import mx.collections.ArrayCollection;
   import mx.collections.ICollectionView;
   import mx.collections.IViewCursor;
   import mx.collections.XMLListCollection;
   import mx.controls.DataGrid;
   
   /**
    *
    * Author: Andrés Lozada Mosto
    * Version: 0.1
    * Fecha release: 10/03/2009
    * Contacto: alfathenus@gmail.com
    *  
    * Clase que maneja la exportacion de elementos
    * a Excel.
    * 
    * Se utiliza el proyecto http://code.google.com/p/as3xls/ 
    * para la generacion de Excel.
    * 
    * Se necesita la version 10 de Flash player para realizar el correcto
    * guardado del archivo sin pasar por backend.
    * 
    * @example
    * <code>
    * private var flat:ArrayCollection = new ArrayCollection([
    *                              {nombre:"Andrés", apellido:"Sanchez"},
    *                              {nombre:"Mónica", apellido:"Sanchez"},
    *                              {nombre:"Agustina", apellido:"Sanchez"},
    *                              {nombre:"Pablo", apellido:"Sanchez"},
    *                              {nombre:"Magalí", apellido:"Sanchez"}
    *                              ]);
    * ExcelExporterUtil.dataGridExporter(this.dg, "prueba_excel.xls");
    * </code>
    * 
    * Lista de funciones
    * <list>
    *  dataGridExporter:       Exporta un datagrid a un excel de forma automatica
    *  export:             Exporta un listado de objetos
    * </list>
         *
    */

   public class ExcelExporterUtil
   {
      public function ExcelExporterUtil()
      {
         throw new IllegalOperationError("Class \"ExcelExporterUtil\" is static. You can't instance this");
      }
      
      //-----------------------------
      // Public function
      //-----------------------------
      /**
       * 
       * Exporta los datos de un datagrid hacia un Excel.
       * Toma el dataProvider del mismo y las columnas para su exportacion
       * 
       * @param dg          Referencia al datagrid
       * @defaultName         Nombre default con el que se va a generar el archivo excel
       * 
       */
      static public function dataGridExporter(dg:DataGrid, defaultName:String):void
      {
         if (dg == null || dg.dataProvider == null || defaultName == null || defaultName == "")
            return;
         
         var cols:Number = 0;
         var colsValues:Array = [];
         var cantCols:Number = dg.columnCount;
         var fieldT:String;
         var headerT:String;
         
         // armo el listado de headers y variables para cada columna
         for ( ; cols < cantCols; cols++)
         {
            headerT = (dg.columns[cols] as Object).headerText
            fieldT = (dg.columns[cols] as Object).dataField;
            if ( fieldT == null || fieldT == "" || headerT == null || headerT == "")
               continue; 
            colsValues.push({
                        header:headerT,
                        value:fieldT
            });
         }
         
         if ( colsValues.length == 0 )
            return;
            
         ExcelExporterUtil.export(dg.dataProvider, colsValues, defaultName);
      }
      
      /**
       * 
       * Export to Excell
       * 
       * @param obj          Objeto simple, XML, XMLList, Array, ArrayCollection o XMLListCollection
       *                   que se quiere exportar a excel
       * @colsValues         Listado de objetos que indican cual es el nombre de la columna
       *                   y que propiedad del objeto se utiliza para sacar los datos de la columna
       *                   {header:"nombre del header", value:"propiedad del objeto que contiene el valor"}
       * @param defaultName   Nombre default con el que se genera el excel
       * 
       */
      static public function export(obj:Object, colsValues:Array, defautlName:String):void
      {
         var _dp:ICollectionView = ExcelExporterUtil.getDataProviderCollection(obj);
         if ( _dp == null )
            return;
         
         var rows:Number = 0;
         var cols:Number = 0;
         var cantCols:Number = colsValues.length;
         var sheet:Sheet = new Sheet();
         sheet.resize(_dp.length, colsValues.length);
         
         for ( ; cols < cantCols; cols++)
         {
            sheet.setCell(rows, cols, colsValues[cols].header);
         }
         
         cols = 0;
         rows++;
         var cursor:IViewCursor = _dp.createCursor();
         while ( !cursor.afterLast )
         {
            for (cols = 0 ; cols < cantCols; cols++)
            {
               if ( (cursor.current as Object).hasOwnProperty(colsValues[cols].value) )
                     sheet.setCell(rows, cols, (cursor.current as Object)[colsValues[cols].value]);
            }
            
            rows++;
            cursor.moveNext();
         }
         
         var xls:ExcelFile = new ExcelFile();
         xls.sheets.addItem(sheet);
         var bytes:ByteArray = xls.saveToByteArray();
         
         var fr:FileReference = new FileReference();
         fr.save(bytes, defautlName);
      }
      
      //-----------------------------
      // Private function
      //-----------------------------
      /**
       * 
       * A partir de un elemento pasado se genera un ICollectionView
       * para su correcto recorrido
       * 
       * @param obj         Objeto a convertir a ICollectionView
       * 
       * 
       * @return referencia a un ICollectionView. 
       * 
       */
      static private function getDataProviderCollection(obj:Object):ICollectionView
      {
         if ( (obj is Number && isNaN(obj as Number)) || (!(obj is Number) && obj == null))
         {
            return null;
         }
         else if ( obj is ICollectionView )
         {
            return obj as ICollectionView;
         }
         else if ( obj is Array )
         {
            return new ArrayCollection(obj as Array);
         }
         else if ( obj is XMLList )
         {
            return new XMLListCollection(obj as XMLList);
         }
         else if ( obj is XML )
         {
            var col:XMLListCollection = new XMLListCollection();
            col.addItem(obj);
            return col;
         }
         else if ( obj is Object )
         {
            return new ArrayCollection([obj]);
         }
         else
         {
            return null;
         }
      }
   }
}


Nivel de desarrollo actual de la clase:
- Exporta listas de objetos a un excel
- Exporta un datagrid a un excel

Tareas en desarrollo:
- Testing
------ En entorno Flash
------ Exportacion de XML, XMLList, XMLListCollection
------ Exportaciones directas desde AdvancedDataGrid y OLAPDataGrid
- Implementar BIFF 8 asi se le puede agregar cualquier tipo de multimedia

Saludos y espero que les sirva

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate