Tablica PHP do CSV


105

Próbuję przekonwertować szereg produktów do pliku CSV, ale wydaje mi się, że to nie jest plan. Plik CSV to jedna długa linia, oto mój kod:

for($i=0;$i<count($prods);$i++) {
$sql = "SELECT * FROM products WHERE id = '".$prods[$i]."'";
$result = $mysqli->query($sql);
$info = $result->fetch_array(); 
}

$header = '';

for($i=0;$i<count($info);$i++)  
  {
    $row = $info[$i];

    $line = '';
    for($b=0;$b<count($row);$b++)
    { 
    $value = $row[$b];                                      
        if ( ( !isset( $value ) ) || ( $value == "" ) )
        {
            $value = "\t";
        }
        else
        {
            $value = str_replace( '"' , '""' , $value );
            $value = '"' . $value . '"' . "\t";
        }
         $line .= $value;
        }
    $data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );

if ( $data == "" )
{
$data = "\n(0) Records Found!\n";                        
}

header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=your_desired_name.xls");
header("Pragma: no-cache");
header("Expires: 0");

array_to_CSV($data);


function array_to_CSV($data)
    {
        $outstream = fopen("php://output", 'r+');
        fputcsv($outstream, $data, ',', '"');
        rewind($outstream);
        $csv = fgets($outstream);
        fclose($outstream);
        return $csv;
    }

Ponadto nagłówek nie wymusza pobierania. Kopiowałem i wklejałem wynik i zapisałem jako .csv

EDYTOWAĆ

PROBLEM ROZWIĄZANY:

Jeśli ktoś szukał tego samego, znalazł lepszy sposób na zrobienie tego:

$num = 0;
$sql = "SELECT id, name, description FROM products";
if($result = $mysqli->query($sql)) {
     while($p = $result->fetch_array()) {
         $prod[$num]['id']          = $p['id'];
         $prod[$num]['name']        = $p['name'];
         $prod[$num]['description'] = $p['description'];
         $num++;        
    }
 }
$output = fopen("php://output",'w') or die("Can't open php://output");
header("Content-Type:application/csv"); 
header("Content-Disposition:attachment;filename=pressurecsv.csv"); 
fputcsv($output, array('id','name','description'));
foreach($prod as $product) {
    fputcsv($output, $product);
}
fclose($output) or die("Can't close php://output");

Użyj $ info [] = $ result-> fetch_array (); w przeciwnym razie będzie miał ostatnie szczegóły produktu
GBD

@JohnnyFaldo: Dzięki stary! Właśnie tego potrzebowałem.
Cesar

Hej! Wiem, że to stare pytanie, ale możesz odpowiedzieć na swoje własne pytanie. Może pomóc ludziom znaleźć rozwiązanie podobnego problemu.
Gustavo Straube

czy ktoś inny otrzymuje pierwszą linię i pierwsze dwa bloki drugiej linii puste?
mach2

Odpowiedzi:


97

Zamiast wypisywać wartości rozważ użycie fputcsv().

Może to natychmiast rozwiązać problem.


1
Powinienem wspomnieć, że spowoduje to utworzenie pliku na twoim serwerze, więc będziesz musiał przeczytać zawartość tego pliku przed wyprowadzeniem go, również jeśli nie chcesz zapisywać kopii, będziesz musiał ù odłączyć` plik, gdy gotowe.
Martin Lyne

Dzięki za edycję Vyktor, moje dzisiejsze pisanie jest okropne! Zwykle jestem taka ostrożna.
Martin Lyne

czy mogę edytować kod, który mam powyżej, aby to zrobić? ponieważ wypisuje wszystkie pola i używając przykładów fputcsv w podręczniku, nie mogę tego zrobić
JohnnyFaldo

7
tablica_to_CSV (dane $); function array_to_CSV ($ data) {$ outstream = fopen ("php: // wyjście", 'r +'); fputcsv ($ outstream, $ data, ',', '"'); rewind ($ outstream); $ csv = fgets ($ outstream); fclose ($ outstream); return $ csv;}
JohnnyFaldo

tak, to rozwiązałem dziękuję, dodałem rozwiązanie w pierwotnym pytaniu
JohnnyFaldo

16

To jest proste rozwiązanie, które eksportuje tablicę do łańcucha csv:

function array2csv($data, $delimiter = ',', $enclosure = '"', $escape_char = "\\")
{
    $f = fopen('php://memory', 'r+');
    foreach ($data as $item) {
        fputcsv($f, $item, $delimiter, $enclosure, $escape_char);
    }
    rewind($f);
    return stream_get_contents($f);
}

$list = array (
    array('aaa', 'bbb', 'ccc', 'dddd'),
    array('123', '456', '789'),
    array('"aaa"', '"bbb"')
);
var_dump(array2csv($list));

5

Spróbuj użyć;

PHP_EOL

Aby zakończyć każdy nowy wiersz w pliku wyjściowym CSV.

Zakładam, że tekst jest ogranicznikiem, ale nie przechodzi do następnego wiersza?

To stała PHP. To określi właściwy koniec linii, którego potrzebujesz.

Na przykład Windows używa "\ r \ n". Niszczyłem sobie tym mózgiem, gdy moje wyniki nie wychodziły na nowy poziom.

jak napisać ujednoliconą nową linię w PHP?


2

Wiem, że to jest stare, miałem przypadek, w którym potrzebowałem klucza tablicy, który również powinien być uwzględniony w pliku CSV, więc zaktualizowałem skrypt Jesse Q, aby to zrobić. Użyłem łańcucha jako wyjścia, ponieważ implode nie może dodać nowej linii (nowa linia to coś, co dodałem i naprawdę powinno tam być).

Należy pamiętać, że działa to tylko z tablicami o pojedynczej wartości (key, value). ale można go łatwo zaktualizować, aby obsługiwał wiele wymiarów (key, array()).

function arrayToCsv( array &$fields, $delimiter = ',', $enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
    $delimiter_esc = preg_quote($delimiter, '/');
    $enclosure_esc = preg_quote($enclosure, '/');

    $output = '';
    foreach ( $fields as $key => $field ) {
        if ($field === null && $nullToMysqlNull) {
            $output = '';
            continue;
        }

        // Enclose fields containing $delimiter, $enclosure or whitespace
        if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field ) ) {
            $output .= $key;
            $output .= $delimiter;
            $output .= $enclosure . str_replace($enclosure, $enclosure . $enclosure,     $field) . $enclosure;
            $output .= PHP_EOL;
        }
        else {
            $output .= $key;
            $output .= $delimiter;
            $output .= $field;
            $output .= PHP_EOL;
        }
    }

    return  $output ;
}

1

W moim przypadku moja tablica była wielowymiarowa, potencjalnie z tablicami jako wartościami. Utworzyłem więc tę funkcję rekurencyjną, aby całkowicie rozerwać tablicę:

function array2csv($array, &$title, &$data) {
    foreach($array as $key => $value) {      
        if(is_array($value)) {
            $title .= $key . ",";
            $data .= "" . ",";
            array2csv($value, $title, $data);
        } else {
            $title .= $key . ",";
            $data .= '"' . $value . '",';
        }
    }
}

Ponieważ różne poziomy mojej tablicy nie nadawały się dobrze do płaskiego formatu CSV, utworzyłem pustą kolumnę z kluczem podtablicy, aby służyć jako opisowe „wprowadzenie” do następnego poziomu danych. Przykładowe dane wyjściowe:

agentid     fname           lname      empid    totals  sales   leads   dish    dishnet top200_plus top120  latino  base_packages
G-adriana   ADRIANA EUGENIA PALOMO PAIZ 886                0    19              0         0         0         0      0

Możesz łatwo usunąć tę kolumnę "intro" (opisową), ale w moim przypadku miałem powtarzające się nagłówki kolumn, tj. Inbound_leads, w każdej podtablicy, dzięki czemu otrzymałem przerwę / tytuł poprzedzający następną sekcję. Usunąć:

$title .= $key . ",";
$data .= "" . ",";

po is_array (), aby dalej kompaktować kod i usunąć dodatkową kolumnę.

Ponieważ chciałem zarówno wiersz tytułu, jak i wiersz danych, przekazuję dwie zmienne do funkcji i po zakończeniu wywołania funkcji kończę oba za pomocą PHP_EOL:

$title .= PHP_EOL;
$data .= PHP_EOL;

Tak, wiem, że zostawiam dodatkowy przecinek, ale ze względu na zwięzłość nie poradziłem sobie z tym tutaj.


Wydaje się, że jest to konkretna odpowiedź na bardzo ogólne pytanie i trzeba przyznać, że zostawiłeś dodatkowe przecinki (ze względu na rzeczywisty problem z używaniem ciągów znaków zamiast tablic), a także nie zacytowałeś wiersza nagłówka i miałeś kilka dodatkowych niepotrzebnych wywołań. Przekształciłem to wszystko w odpowiedzi na inne pytanie .
LWC

1

Tablice danych są konwertowane do formatu csv „text / csv” przez wbudowaną funkcję php fputcsv dba o przecinki, cudzysłowy itp.
Patrz
https://coderwall.com/p/zvzwwa/array-to-comma-separated -string-in-php
http://www.php.net/manual/en/function.fputcsv.php


Link do rozwiązania jest mile widziany, ale upewnij się, że Twoja odpowiedź jest przydatna bez niego: dodaj kontekst wokół linku, aby inni użytkownicy mieli pojęcie, co to jest i dlaczego się tam znajduje, a następnie zacytuj najbardziej odpowiednią część strony, którą podałeś. ponowne łącze w przypadku, gdy strona docelowa jest niedostępna. Odpowiedzi, które są niewiele więcej niż linkiem, mogą zostać usunięte.
geisterfurz007

0

U mnie to zadziałało.

 $f=fopen('php://memory','w');
 $header=array("asdf ","asdf","asd","Calasdflee","Start Time","End Time" );      
 fputcsv($f,$header);
 fputcsv($f,$header);
 fputcsv($f,$header); 
 fseek($f,0);
 header('content-type:text/csv'); 
 header('Content-Disposition: attachment; filename="' . $filename . '";');
 fpassthru($f);```
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.