2010-09-28 19 views
10

Tak więc, mój kod generuje plik CSV za pomocą wbudowanej w PHP funkcji fputcsv.Wrap Wartości CSV generowane przez PHP fputcsv() z ""

Dla ogranicznika używam ',' (przecinek).
Do obudowy używam '"' (podwójny cytat).

Jednak, gdy próbuję coś

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

wyprowadza

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

ale chciałbym go do wyjścia

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

Czy istnieje prosty sposób na radzenie sobie z tym , czy musiałbym napisać zamiennik dla fputcsv?

+1

Dane wyjściowe są prawidłowe CSV. Twoje inne narzędzie jest zepsute. –

+0

Dlaczego chcesz cytaty na każdym polu? –

+1

@Ignacio, Andrew: Wygląda na to, że ukryty w małym rogu okna dialogowego importu na arkuszu kalkulacyjnym oprogramowanie jest opcją do skondensowania wielu pustych pól ('a ,,,' => 'a,') i/lub ich usunięcia ('a ,,, '=>' a'). I najwyraźniej niektórzy użytkownicy mają to sprawdzone i nie znają tego, więc proste, uniwersalne rozwiązanie polega na wymuszeniu, by każde puste pole było pustym łańcuchem ("a," "," "," "). –

Odpowiedz

9

Zazwyczaj nie stanowi to problemu w przypadku plików CSV.

fputcsv umieszcza cytaty dotyczące wartości, jeśli byłyby niejednoznaczne. Na przykład,

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

nie jest niejednoznaczny, ale

a,b,long string, with commas,, 

jest i będzie w większości (czytaj: wszystkich) przypadkach być interpretowane przez czytnik CSV jako posiadające więcej niż 5 pól.

Analizatory składni CSV będą akceptować ciągi liter, nawet bez cytatów wokół nich.

Jeśli chcesz mimo wszystko cytować wartości, to zrobi to poniższy fragment. Nie usuwa cytatów z ciągu znaków - to ćwiczenie pozostawiono czytelnikowi:

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

Chciałbyś umieścić to w pętli dla wszystkich swoich wierszy.

+0

Tak, wiem o niejasności, ale to naprawdę puste części, które muszę zawijać w cudzysłowy. Mogę żyć bez zapakowanych niepustych części (oczywiście z wyjątkiem tych dwuznacznych). –

+0

Twój komentarz jest mylący. Czy chcesz, aby puste części były zawijane w cudzysłów, ale niepuste części mogły się obejść bez owijania? Co masz na myśli. Opublikowany fragment zostanie zawinięty w cudzysłów, który powinien działać ze wszystkimi parserami CSV. –

+0

Nieważne. Byłem trochę zdezorientowany. Tak, to powinno działać. Dzięki. –

0

Dowolny powód, dla którego nie można str_replace (",,", "", ", $ output); ? Można by też trzeba sprawdzić, czy ostatni czy pierwszy znak jest przecinek, a jeśli tak, to zastąpić przecinek z „”

+0

To była moja pierwsza myśl, ale musiałem przechwycić zapis pliku na ciąg. D: –

+1

Ah tak. Całkowicie zapomniałem pomyśleć o tym, co faktycznie robi fputcsv. Lepiej jest pisać własną funkcję, która wymyka się danym i wyprowadza je za pomocą fputs lub fwrite. – methodin

2

myślę rozwiązaniem będzie tak,

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

zapamiętania " " [spacja ] Między trzecim parametrem fputcsv

+0

To jest najczystsza i najszybsza odpowiedź. – RafaSashi

8

Pracowałem nad tym, wstawiając pewne fałszywe ciągi znaków, z spacją, # @ @ #, a następnie usuwając je. Oto próbka realizacja:

//$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); 

ten zamyka wszystkie pola w cudzysłowach, w tym pustych

+0

Mimo że wymaga to otwarcia i zamknięcia pliku, dodatkowy czas działa dobrze. – iamjonesy

+0

Umożliwia to ustawienie go dla konkretnego pola zamiast wszystkich kolumn +1 – input

+0

trochę powolny, ale jedyny sposób, aby to działało poprawnie, dzięki! – Damian

0

fputcsv nie będzie załączenie wszystkich zmiennych tablicowych w cudzysłowach. Posiadanie wartości tablic numerycznych bez cudzysłowów może być poprawne, ale stanowi problem, gdy program etykiety lub adresu napotka zdefiniowany numerycznie amerykański kod pocztowy, ponieważ usunie początkowe zera podczas drukowania. Tak więc 05123-0019 staje się 5123-19.

Aby zawrzeć wszystkie wartości, niezależnie od tego, czy istnieją, czy nie, w cudzysłowie odczytuję plik wejściowy za pomocą fgetsrc i zapisuję poprawioną wersję za pomocą fwrite. fgetsrc odczytuje rekord do zmiennych tablicowych. Ponieważ fwrite zapisuje zmienną, należy napisać zmienne tablicowe, ująć je w cudzysłowy i oddzielić zmienną tablicową przecinkiem. Następnie dodaj separator rekordów.

<?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); 
?>