2010-09-28 13 views
10

Quindi, il mio codice genera un file CSV utilizzando la funzione integrata di PHP fputcsv.Wrap Valori CSV generati da PHP fputcsv() con ""

Per il delimitatore, utilizzo ',' (una virgola).
Per il contenitore, utilizzo '"' (una virgola doppia).

Tuttavia, quando provo qualcosa come

fputcsv($file,array('a','b',"long string, with commas",NULL,''),',','"'); 

emette

a,b,"long string, with commas",, 

ma vorrei che per l'uscita

"a","b","long string, with commas","","" 

C'è un modo semplice per affrontare questo , o dovrei scrivere un sostituto per fputcsv?

+1

L'output è valido CSV. Il tuo altro strumento è rotto. –

+0

Perché vuoi le virgolette su ogni campo? –

+1

@Ignacio, Andrew: Apparentemente, nascosto in un piccolo angolo della finestra di dialogo di importazione su software di foglio di calcolo è un'opzione per condensare più campi vuoti ('a ,,, = =' 'a,') e/o rimuoverli ('a ,,, '=>' a'). E a quanto pare alcuni utenti lo hanno verificato e non lo sanno, quindi la soluzione facile, a taglia unica, consiste nel forzare ogni campo vuoto ad essere una stringa vuota ('a," "," "," "'). –

risposta

9

Questo di solito non è un problema per i file CSV.

fputcsv inserisce virgolette attorno al valore se sarebbe ambiguo. Ad esempio,

a,b,"long string, with commas",, 

non è ambigua, ma,

a,b,long string, with commas,, 

è e sarà in più (leggi: tutti) i casi essere interpretati dal lettore CSV come aventi più di 5 campi.

I parser CSV accettano letterali stringa anche senza virgolette attorno a loro.

Se si desidera quotazioni attorno ai valori in ogni caso, lo snippet seguente lo farebbe. Non sfugge citazioni all'interno della stringa - che l'esercizio fisico è lasciata al lettore:

$row = '"' . implode('", "', $rowitems) . '"'; 

Si consiglia di mettere questo in un ciclo per tutte le righe.

+0

Sì, conosco l'ambiguità, ma sono davvero le parti vuote di cui ho bisogno racchiuse tra virgolette. Posso vivere senza che le parti non vuote siano avvolte (eccetto quelle ambigue, ovviamente). –

+0

Il tuo commento è confuso. Vuoi le parti vuote racchiuse tra virgolette ma le parti non vuote potrebbero andare senza avvolgimento? Cosa intendi. Lo snippet pubblicato racchiuderà tutte le virgolette che dovrebbero funzionare con tutti i parser CSV. –

+0

Non importa. Ero un po 'confuso. Sì, dovrebbe funzionare. Grazie. –

0

Qualsiasi motivo non è possibile str_replace (',,', ', "",', $ output); ? Faresti anche Bisogna vedere se l'ultimo o il primo carattere è una virgola e, in caso affermativo, sostituire la virgola con ""

+0

Questo era in realtà il mio primo pensiero, ma poi avrei dovuto intercettare il file-scrivere in una stringa. D: –

+1

Ah sì. Completamente dimenticato di pensare a cosa ha effettivamente fputcsv hah. Si sta meglio scrivendo la propria funzione che sfugge ai dati e li emette usando fput o fwrite. – methodin

2

Credo che la soluzione sarà così,

$order_header_arr = array("Item1", "Item2","This is Item3"); 
fputcsv($fp, $order_header_arr,',',' '); 

ricordare " " [Spazio ] Tra il terzo parametro di fputcsv

+0

Questa è la risposta più pulita e rapida – RafaSashi

8

Ho lavorato su questo inserendo alcuni caratteri di stringa falsi, con uno spazio, # @ @ #, e quindi rimuovendoli. Ecco un esempio di implementazione:

//$exported is our array of data to export 
$filename = 'myfile.csv'; 
$fp = fopen($filename, 'w'); 
foreach ($exported as $line => $row) { 
    if ($line > 0) { 
     foreach ($row as $key => $value) { 
       $row[$key] = $value."#@ @#"; 
     } 
    } 
    fputcsv($fp, $row); 
} 

fclose($fp); 
$contents = file_get_contents($filename); 
$contents = str_replace("#@ @#", "", $contents); 
file_put_contents($filename, $contents); 

Questo racchiude tutti i campi di virgolette doppie, comprese quelle vuote

+0

Sebbene ciò implichi l'apertura e la chiusura del file, un tempo extra funziona correttamente. – iamjonesy

+0

Ciò consente anche di impostarlo per un campo specifico anziché per tutte le colonne +1 – input

+0

un po 'lento, ma l'unico modo per farlo funzionare correttamente, grazie! – Damian

0

fputcsv non racchiudere tutte le variabili di matrice tra virgolette. Avere un valore numerico dell'array senza virgolette può essere corretto ma presenta un problema quando un programma di etichette o indirizzi incontra un codice postale statunitense numerico definito in quanto rimuoverà gli zeri iniziali durante la stampa. Quindi 05123-0019 diventa 5123-19.

per racchiudere tutti i valori, sia che esistano o meno, tra virgolette ho letto il file di input con fgetsrc e scrivo una versione corretta usando fwrite. fgetsrc legge il record in variabili di array. Dato che fwrite scrive una variabile, devi stringare le variabili dell'array, racchiuderle tra virgolette e separare la variabile dell'array con una virgola. Quindi aggiungere il separatore del record.

<?php 
// fgetcsv - read array with fgetcsv and string into output variable 
// then write with fwrite 
// $ar is the array populated from fgetcsv and $arc is the variable strung 
// with array variables enclosed in quotes and written using fwrite. 
$file_in = fopen("reinOCp.csv","r") or die("Unable to open input file 
reinOCp.csv!"); 
$file_out = fopen("printLABEL.csv", "w") or die("Unable to open output file 
prtLABEL!"); 
while (!feof($file_in)) { //loop through each record of the input file 
    $ar=fgetcsv($file_in); //read the record into array $ar 
    if (is_array($ar)){ //this loop will string all the array values plus 
// the end of record into variable $arc and then write the variable 
     $arc = ""; //clear variable $arc 
     foreach ($ar as $value) {  
      $arc .= '"' . $value . '",'; // add the array values, enclose in 
// quotes with comma separator and store in variable $arc 
     } 
     $arc .= "\n"; //add end of record to variable $arc 
     fwrite($file_out, $arc) or die ("ERROR: Cannot write the file"); 
//write the record using variable $arc 
    } 
} 
echo "end of job"; 
fclose($file_in); 
fclose($file_out); 
?>