2012-10-04 78 views
7

puedo crear un archivo CSV para su descarga por nuestro cliente utilizando¿Cómo puedo cambiar los finales de línea utilizados por fputcsv?

$output = fopen('php://output', 'w'); 

y el uso de fputcsv() para escribir datos en un archivo CSV que se descarga por el cliente.

Estoy ejecutando PHP en Linux y, en consecuencia, las terminaciones de línea no son interpretadas por muchas aplicaciones de Windows.

podría escribir el archivo CSV a un directorio en el servidor, leer de nuevo y realizar una str_replace()\n-\r\n, pero esto parece una manera bastante torpe de resolver el problema. ¿Hay alguna manera de realizar la conversión sin crear un archivo físico?

+0

menos que el usuario abre el archivo en un editor de texto de Windows que requiere CRLF, o algunas aplicaciones de Windows bastante antiguas, entonces en realidad no debería importar ... la mayoría de las aplicaciones de Windows actualmente reconocen un LF simple en su lugar –

+1

Perdón por +1 usted estuvo en 1337, el representante más elegante . Pero tu pregunta me interesa, no hay forma de cambiar el escape también ... –

+0

@MarkBaker: Sí, eso es lo que esperaba. Desafortunadamente, están importando el CSV en algunos MIS que utilizan, lo que no parece ser más inteligente que el Notepad en este sentido. – Kalessin

Respuesta

17

usted podría utilizar corriente filtros para lograr esto. Este ejemplo escribe en un archivo físico, pero también debería funcionar bien para php://output.

// filter class that applies CRLF line endings 
class crlf_filter extends php_user_filter 
{ 
    function filter($in, $out, &$consumed, $closing) 
    { 
     while ($bucket = stream_bucket_make_writeable($in)) { 
      // make sure the line endings aren't already CRLF 
      $bucket->data = preg_replace("/(?<!\r)\n/", "\r\n", $bucket->data); 
      $consumed += $bucket->datalen; 
      stream_bucket_append($out, $bucket); 
     } 
     return PSFS_PASS_ON; 
    } 
} 
// register the filter 
stream_filter_register('crlf', 'crlf_filter'); 

$f = fopen('test.csv', 'wt'); 
// attach filter to output file 
stream_filter_append($f, 'crlf'); 
// start writing 
fputcsv($f, array('1 1', '2 2')); 
fclose($f); 
2

No estoy seguro si puede hacer esto con PHP. Puede haber una forma de cambiar la EOL de PHP para la escritura de archivos, pero es probable que dependa del sistema. No tiene un sistema de Windows que pueda hacer ping, ¿verdad? ;)

En cuanto a una solución real, en lugar de str_replace, línea por línea, se puede usar el programa Linux unix2dos (inversa de dos2unix) suponiendo que tiene instalado:

fputcsv($fh ...) 
exec("unix2dos " . escapeshellarg($filename)); 
1
  1. Crear el archivo con los finales de línea \ n en una máquina Linux
  2. FTP el archivo como ASCII de la máquina Linux a una máquina Windows
  3. ¡listo! Todos los finales de línea son ahora \ r \ n en el archivo en la máquina Windows
-1

En lugar de escribir el archivo, una mejor solución es el uso de búferes de salida

function output($buffer) { 
    return str_replace("\r", "\r\n", $buffer); 
} 

ob_start('output'); 
fputcsv(....); 
Cuestiones relacionadas