Importar datos CSV en aplicaciones PHP

Introducción

Una de las tareas más frecuentes en programación de aplicaciones web de mediano/alto calado, es la importación de datos de CSV (comma-separated values o valores separados por comas) que profusamente se  usan en el traslado de información entre sistemas de almacenamiento heterogéneos.

De un caso de la vida real, digamos que cierta empresa requiere publicar en su sitio web la información de las planillas de consumo para sus clientes. Esta información se encuentra almacenada en una base de datos DB2 (IBM) pero el sitio web está construido en  PHP con una base de datos MySQL. Una solución (la que se usa) es la de exportar del DB2 una CSV con los datos (sólo los necesarios de publicar en el web) de las planillas para todos sus clientes; e importar estos datos hacia la base de datos MySQL del web.

Más información acerca del formato CSV se puede encontrar en Wikipedia: http://es.wikipedia.org/wiki/CSV

Importando de archivos CSV

Dado que tenemos líneas de valores separados por comas, la forma más sencilla de procesar cada línea es usando la función PHP explode():

<?php 
$arrResult = array(); 
$arrLines = file( 'data.csv' ); 
foreach( $arrLines as $line ) {
    $arrResult[] = explode( ',', $line ); 
}
?>

Lidiando con caracteres especiales

Esta solución simple no trabajará si tienes una coma dentro de un valor, como por ejemplo, cuando una columna es una dirección y tiene un valor como «Conjunto Alhambra, T6-201».

En tales casos, el valor de la columna en el archivo CSV está encerrado en comillas (quoted) para indicar que la información entre comillas debería ser leída como una sola columna.Para lidiar con esta situación, puede usar una expresión regular especializada o usar la función  PHP fgetcsv(). http://www.php.net/fgetcsv

<?php 
$arrResult = array(); 
$handle = fopen("data.csv", "r"); 
if( $handle ) { 
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 
        $arrResult[] = $data; 
    } 
    fclose($handle); 
} 
?>

Nota que las opciones de localización (locale) pueden afectar el cómo trabaja fgetcsv(). Como se indica en el el manual PHP, si el «locale» LANG es por ejemplo «es_EC.UTF-8», los archivos con codificación de 1 byte serán leídos erróneamente por esta función, así que ten cuidado.

Importando datos CSV directamente a una base de datos

Si estás importando datos de un archivo CSV hacia una base de datos MySQL, la deberías importar directamente a una tabla de la base de datos. Esto será mucho más rápido que procesar línea por línea usando PHP.

Afortunadamente, la mayoría de las bases de datos relacionales tienen herramientas para la importación masiva desde archivos CSV. Por ejemplo, en MySQL puedes usar la consulta/sentencia LOAD DATA INFILE. http://dev.mysql.com/doc/refman/5.0/es/load-data.html

Interface de usuario amigable para importar datos CSV hacia una base de datos

Una solución alternativa de importar datos CSV hacia una base de datos es usar la la clase «Quick CSV Import» del autor original en inglés de este artículo (Alexander Skakunov) disponible en el sitio de PHPClasses: http://www.phpclasses.org/quick_csv_import

Una, aún más amigable, alternativa para importar datos CSV a una base de datos consiste en usar la aplicación «Quick CSV import with visual mapping» que está basada en la clase anterior.

Esta aplicación ayuda a importar archivos CSV hacia una tabla de base de datos, permitiendo definir las columans del CSV que serán mapeadas hacia las columas de la tabla de la base de datos. Esta aplicación puede incluso sugerir automáticamente el caracter separador además de la coma. http://i1t2b3.com/2009/01/14/quick-csv-import-with-mapping/