Mostrando entradas con la etiqueta excel. Mostrar todas las entradas
Mostrando entradas con la etiqueta excel. Mostrar todas las entradas

martes, 26 de noviembre de 2013

Preparando datos para exportar a excel sobre CodeIgniter

En este artículo les voy a poner un ejemplo un poco más completo de cómo generar un excel con información existente en nuestra base de dato. Recomiendo leer primero el artículo “Importando y exportando excel sobre CodeIgniter”, donde presenté la biblioteca PHPExcel para importar y exportar ficheros de hojas de cálculo (excels).

En dicho artículo expliqué cómo instalar esta biblioteca, y cómo en mi caso creé una biblioteca que actúa como interfaz con la PHPExcel, con dos funciones “import” y “export”. En aquel entonces puse un ejemplo de código de exportar en el que solamente se ponía un valor en una celda. Modificando el código para hacerlo cíclicamente quedaría así (en $table vienen los datos sacados de la BD):

function export($table)
{
$objPHPExcel = new PHPExcel(); //creando un objeto excel
$objPHPExcel->getProperties()->setCreator("Yanoski")… //propiedades
$objPHPExcel->setActiveSheetIndex(0); //poniendo active hoja 1
$objPHPExcel->getActiveSheet()->setTitle("Hoja1"); //título de la hoja 1

//llenando celdas
$column = 0;
$row = 1;
foreach ($table as $record)
{
foreach ($record as $value)
{
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($column, $row, $value);
$column++;
}
$column = 0;
$row++;
}

//poniendo en negritas la fila de los títulos
$styleArray = array('font' => array('bold' => true));
$objPHPExcel->getActiveSheet()->getStyle('A1:Z1')-> applyFromArray($styleArray);

//poniendo columnas con tamaño auto según el contenido, asumiendo N como la última
for ($i = 'A'; $i<= 'N'; $i++)
$objPHPExcel->getActiveSheet()->getColumnDimension($i)->setAutoSize(true);

//código de exportar (ver artículo antes mencionado)
}

 


Como puedes ver todo se reduce a hacer un recorrido anidado al arreglo bidimensional $table, donde para cada fila ($record) accedo a cada valor de columna ($value) y lo inserto en la celda $column,$row, valores que voy incrementando convenientemente.

El uso desde un controlador sería sencillamente:

function export_data()   //en el controlador
{
$table = $this->my_model->get_table();
$this->load->library('excel_pdf_manager');
$this->excel_pdf_manager->export($table);
}

 


¿Dónde está el truco entonces? En el modelo. Es ahí donde realmente se formatea el arreglo bidimensional “$table” de forma que coincida con lo que quieras exportar. Los dos segmentos de código que puse arriba son genéricos para cualquier tabla de base de datos. Si quisieras exportar varias tablas de la BD llamarías la línea $table = $this->my_model->get_table() para cada modelo diferente.

Un ejemplo de conformación del arreglo $table sería como sigue, suponiendo una tabla de usuarios que contiene nombre, apellidos, correo electrónico y nombre de usuario, con su correspondiente modelo que llamaré “my_model” para que ajuste con el código anterior:

 

function get_table()   //en el modelo my_model
{
//datos a seleccionar
$this->db->select(users.ID, users.NAME, users.SURNAME, users.EMAIL, users.USERNAME');

//encabezados de las columnas
$headers = array('No', 'Nombre', 'Apellidos', 'Correo electrónico', 'Usuario');

$query = $this->db->get(' users ');
if ($query->num_rows > 0)
{
$table[] = $headers;
$i = 1;
foreach ($query->result() as $row)
{
$row->ID = $i;
$table [] = $row;
$i++;
}
return $table;
}
else
return null;
}

 


Aquí, dos cosas importantes: primero, hacer un select donde acomodas las columnas en el orden deseado y segundo, agregar una fila con los encabezados de las columnas que se pone como primera del arreglo “$table”, y es la fila que se pondrá en negritas.

Como detalle, para no mostrar los ID de los usuarios en el excel (que al final suele ser un autonumérico que actúa como llave de la tabla), he puesto en su lugar un número incremental que comienza en 1, así siempre saldrá en la primera columna del excel un ordinal, independientemente de cual sea el ID del usuario.

Hasta aquí cómo formatear los datos para exportarlos a un excel. En un próximo artículo mostraré el proceso inverso, de importar datos de un excel y verterlos en una tabla de la base de datos.

{ Leer Más }


lunes, 15 de julio de 2013

Importando y exportando excel sobre CodeIgniter.

En este artículo quiero recomendar una biblioteca excelente para importar y exportar ficheros de hojas de cálculo (excels). Esto es una necesidad común en muchos sistemas web y/o de bases de datos, pues en muchos lugares donde nunca se ha contado con una base de datos, al menos han manejado sus datos en tablas de excel, y en el momento de emigrar para un sistema de bases de datos es necesario conservar estos datos sin tener que teclearlos nuevamente. De forma similar, en muchos sistemas web es necesario generar reportes en tablas de excel.

En mi caso y ante una necesidad similar, utilicé la biblioteca PHPExcel v1.7.2[1], creada para ser utilizada sobre PHP puro (versión 5.2.0 o superior[2]), pero perfectamente acoplable al CodeIgniter.

PHPExcel permite generar excels con prácticamente cualquier característica que pudieras lograr trabajando “a mano” sobre un excel directo. Es decir, puedes darle tamaños a las columnas y filas, ponerles formatos, colores, adicionar imágenes, adicionar reglas de validación de celdas, etc. Todo esto, se puede hacer desde el código de PHP.

Para utilizarlo sobre CodeIgniter, primeramente debes copiar la carpeta excel-php\Classes de PHPExcel para el directorio \application\libraries de CodeIgniter. Ahí puedes crear una carpeta excel_pdf y dentro quedarían la carpeta PHPExcel y el fichero PHPExcel.php. Yo le puse “excel_pdf” porque esta biblioteca permite también exportar a PDF, aunque en esto no es muy buena: los elementos a veces salen corridos y son difíciles de ubicar, o al menos no coincide con cómo quedan cuando generas un excel.

La mejor manera de hacer una interfaz de software entre tu sitio web y PHPExcel, es hacer una biblioteca. Para esto creas un fichero excel_pdf_manager.php, dentro del que declaras una clase para manejar los ficheros:

/** PHPExcel */
require_once 'excel_pdf/PHPExcel.php';
/** PHPExcel_IOFactory */
require_once 'excel_pdf/PHPExcel/IOFactory.php';

class Excel_pdf_manager
{
function import($filename)
{

}

function export(…)
{

}
}

Observa la inclusión de los ficheros de la biblioteca PHPExcel.

El fichero excel_pdf_manager.php lo colocas en \application\libraries. La forma de llamar y utilizar la biblioteca sería:

$this->load->library('excel_pdf_manager');

$table = $this->excel_pdf_manager->import('path/to/excel.xls');


Es muy sencillo de incluir. Con la instalación del PHPExcel viene una buena documentación y varios ejemplos dentro de la carpeta test, que van de lo más sencillo a lo más complejo. De todas maneras te pongo algunos ejemplos que se pueden realizar:

EXPORTANDO:
$objPHPExcel = new PHPExcel(); //creando un objeto excel
$objPHPExcel->getProperties()->setCreator("Yanoski")… //propiedades
$objPHPExcel->setActiveSheetIndex(0); //poniendo active hoja 1
$objPHPExcel->getActiveSheet()->setTitle("Hoja1"); //título de la hoja 1

$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($column, $row, $value); //poniendo algo en una celda

$styleArray = array('font' => array('bold' => true));
$objPHPExcel->getActiveSheet()->getStyle('A1:Z1')-> applyFromArray($styleArray); //poniendo en negritas una fila

$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true);
//poniendo una columna con tamaño auto según el contenido

//creando un objeto writer para exportar el excel, y direccionando salida hacia el cliente web para invocar diálogo de salvar:
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$tablename.$ext);
header('Cache-Control: max-age=0');
$objWriter->save('php://output');

IMPORTANDO:

//creando un objeto lector y cargando el fichero
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objPHPExcel = $objReader->load($filename);

//iterando por el contenido de las celdas
$objWorksheet = $objPHPExcel->getActiveSheet();
foreach ($objWorksheet->getRowIterator() as $row)
{
$record = array();
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
foreach ($cellIterator as $cell)
{
$record[] = $cell->getValue();
}

}

Con esta idea, puedes poner el código “EXPORTANDO” dentro de la función “export” de la clase Excel_pdf_manager, y el código “IMPORTANDO” dentro de la función “import”.

En ambos lugares se hace un recorrido cíclico, en el caso de exportar se recorren los records obtenidos de la base de datos y se pasan los valores para las celdas en posiciones (columna;fila) y en el caso de importar se usan los iteradores que ofrece PHPExcel y se pasan los valores de las celdas para un arreglo que luego se puede insertar hacia la base de datos.

Ah, con este código insertas una imagen:

IMÁGENES:

$objDrawing = new PHPExcel_Worksheet_Drawing();

$objDrawing->setPath('path/image.png');

$objDrawing->setCoordinates('B2');

$objDrawing->setOffsetX(110);

$objDrawing->setRotation(25);

$objDrawing->getShadow()->setVisible(true);

$objDrawing->getShadow()->setDirection(45);

$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());

Recuerda que puedes crear reglas de validación para las celdas del excel, esto puede ser útil cuando la entrada de datos para tu sistema se hace normalmente por excels, y en ese caso puedes crear una funcionalidad que genere una plantilla de excel con las columnas requeridas y sin datos, pero con validaciones para cada columna, de forma tal que te entren datos correctos al excel y a la hora de cargar los datos y pasarlos para la base de datos, son menores los riesgos y las validaciones. Agregas un botón de descargar plantilla, y listo.

Bueno, hasta aquí han sido mis experiencias de trabajo con la biblioteca PHPExcel, me ha sido muy útil y genera excels que respetan al pie de la letra lo que le indicas por código, con muchísimas posibilidades de configuración desde el código de PHP. Espero te sea útil si tienes la necesidad de generar excels.




[1] De Maarten Balliauw. Versión 1.7.2 del 11 de enero del 2010.

[2] Deben estar habilitados las extensiones php_zip, php_xml y php_gd2 de PHP.

{ Leer Más }


IconIconIcon