w3schools create php newline fputcsv

create - php import csv



fputcsv y códigos de nueva linea (8)

Estoy usando fputcsv en PHP para generar un archivo delimitado por comas de una consulta de base de datos. Al abrir el archivo en gedit en Ubuntu, parece correcto: cada registro tiene un salto de línea (no hay caracteres de saltos de línea visibles, pero se puede decir que cada registro está separado y abrirlo en la hoja de cálculo de OpenOffice me permite ver el archivo correctamente).

Sin embargo, estamos enviando estos archivos a un cliente en Windows, y en sus sistemas, el archivo se presenta como una gran línea larga. Al abrirlo en Excel, no reconoce múltiples líneas en absoluto.

He leído varias preguntas aquí que son bastante similares, incluida esta , que incluye un enlace a la explicación realmente informativa de Great Newline Schism .

Desafortunadamente, no podemos simplemente decirles a nuestros clientes que abran los archivos en un editor "más inteligente". Necesitan poder abrirlos en Excel. ¿Hay alguna forma programática de garantizar que se agreguen los caracteres de nueva línea correctos para que el archivo pueda abrirse en un programa de hoja de cálculo en cualquier sistema operativo?

Ya estoy usando una función personalizada para forzar comillas alrededor de todos los valores, ya que fputcsv es selectivo al respecto. He intentado hacer algo como esto:

function my_fputcsv($handle, $fieldsarray, $delimiter = "~", $enclosure =''"''){ $glue = $enclosure . $delimiter . $enclosure; return fwrite($handle, $enclosure . implode($glue,$fieldsarray) . $enclosure."/r/n"); }

Pero cuando el archivo se abre en un editor de texto de Windows, todavía aparece como una sola línea larga.


Como señaló webbiedave (¡gracias!), Probablemente la forma más limpia es usar un filtro de flujo.

Es un poco más complejo que otras soluciones, pero incluso funciona en secuencias que no se pueden editar después de escribirlas (como una descarga usando $handle = fopen(''php://output'', ''w''); )

Aquí está mi enfoque:

class StreamFilterNewlines extends php_user_filter { function filter($in, $out, &$consumed, $closing) { while ( $bucket = stream_bucket_make_writeable($in) ) { $bucket->data = preg_replace(''/([^/r])/n/'', "$1/r/n", $bucket->data); $consumed += $bucket->datalen; stream_bucket_append($out, $bucket); } return PSFS_PASS_ON; } } stream_filter_register("newlines", "StreamFilterNewlines"); stream_filter_append($handle, "newlines"); fputcsv($handle, $list, $seperator, $enclosure); ...


Esta es una versión mejorada de la gran respuesta de @John Douthat, que preserva la posibilidad de usar delimitadores y recintos personalizados y devuelve el resultado original de fputcsv:

function fputcsv_eol($handle, $array, $delimiter = '','', $enclosure = ''"'', $eol = "/n") { $return = fputcsv($handle, $array, $delimiter, $enclosure); if($return !== FALSE && "/n" != $eol && 0 === fseek($handle, -1, SEEK_CUR)) { fwrite($handle, $eol); } return $return; }


Eventualmente obtuve una respuesta en el intercambio de expertos; Esto es lo que funcionó:

function my_fputcsv($handle, $fieldsarray, $delimiter = "~", $enclosure =''"''){ $glue = $enclosure . $delimiter . $enclosure; return fwrite($handle, $enclosure . implode($glue,$fieldsarray) . $enclosure.PHP_EOL); }

para ser utilizado en lugar de fputcsv estándar.


He estado lidiando con una situación similar. He aquí una solución que he encontrado que genera archivos CSV con finales de línea compatibles con Windows.

http://www.php.net/manual/en/function.fputcsv.php#90883

No pude usar el ya que estoy tratando de transmitir un archivo al cliente y no puedo usar los fseeks.


Usando la función php, fputcsv solo escribe / ny no se puede personalizar. Esto hace que la función no valga para el entorno de Microsoft, aunque algunos paquetes también detectarán la nueva línea de Linux.

Aún así, los beneficios de fputcsv me mantuvieron buscando una solución para reemplazar el carácter de nueva línea justo antes de enviarlo al archivo. Esto se puede hacer transmitiendo primero el fputcsv a la compilación en php temp stream. Luego, adapte los caracteres de nueva línea a lo que desee y luego guárdelos en un archivo. Me gusta esto:

function getcsvline($list, $seperator, $enclosure, $newline = "" ){ $fp = fopen(''php://temp'', ''r+''); fputcsv($fp, $list, $seperator, $enclosure ); rewind($fp); $line = fgets($fp); if( $newline and $newline != "/n" ) { if( $line[strlen($line)-2] != "/r" and $line[strlen($line)-1] == "/n") { $line = substr_replace($line,"",-1) . $newline; } else { // return the line as is (literal string) //die( ''original csv line is already /r/n style'' ); } } return $line; } /* to call the function with the array $row and save to file with filehandle $fp */ $line = getcsvline( $row, ",", "/"", "/r/n" ); fwrite( $fp, $line);


Windows necesita /r/n como la combinación de retorno de carro / salto de línea para mostrar líneas separadas.


como alternativa, puede generar en formato UNIX nativo (solo / n) y luego ejecutar Unix2dos en el archivo resultante para convertir a / r / n en los lugares apropiados. Solo tenga cuidado de que sus datos no contengan datos de / n. Además, veo que estás usando un separador predeterminado de ~. intente un separador predeterminado de / t.


// Writes an array to an open CSV file with a custom end of line. // // $fp: a seekable file pointer. Most file pointers are seekable, // but some are not. example: fopen(''php://output'', ''w'') is not seekable. // $eol: probably one of "/r/n", "/n", or for super old macs: "/r" function fputcsv_eol($fp, $array, $eol) { fputcsv($fp, $array); if("/n" != $eol && 0 === fseek($fp, -1, SEEK_CUR)) { fwrite($fp, $eol); } }