web-dev-qa-db-fra.com

Convertir un tableau en csv

Comment convertir un tableau en fichier CSV?

Voici mon tableau:

stdClass Object
(

    [OrderList_RetrieveByContactResult] => stdClass Object
        (
            [OrderDetails] => stdClass Object
                (
                    [entityId] => 1025298
                    [orderId] => 10952
                    [orderName] => testing
                    [statusTypeId] => 4652
                    [countryCode] => AU
                    [orderType] => 1
                    [invoiceNumber] => 0
                    [invoiceDate] => 0001-01-01T00:00:00
                    [userID_AssignedTo] => 11711
                    [shippingAmount] => 8.95
                    [shippingTaxRate] => 0
                    [shippingAttention] => 
                    [shippingInstructions] => 
                    [shippingOptionId] => 50161
                    [discountCodeId] => 0
                    [discountRate] => 0
                    [totalOrderAmount] => 408.45
                    [directDebitTypeId] => 0
                    [directDebitDays] => 0
                    [isRecur] => 
                    [nextInvoiceDate] => 0001-01-01T00:00:00
                    [endRecurDate] => 0001-01-01T00:00:00
                    [cycleTypeID] => 1
                    [createDate] => 2010-10-08T18:40:00
                    [lastUpdateDate] => 2010-10-08T18:40:00
                    [deleted] => 
                    [products] => stdClass Object
                        (
                            [Product] => stdClass Object
                                (
                                    [productId] => 674975
                                    [productCode] => 
                                    [productDescription] => 
                                    [units] => 10
                                    [unitPrice] => 39.95
                                    [unitTaxRate] => 0
                                    [totalProductPrice] => 399.5
                                    [productName] => Acne Clearing Gel
                                )

                        )

                    [addresses] => stdClass Object
                        (
                            [Address] => stdClass Object
                                (
                                    [addressTypeID] => 8
                                    [addressLine1] => Cebu City
                                    [city] => Cebu
                                    [zipcode] => 6000
                                    [state] => 
                                    [countryCode] => PH
                                )

                        )

                )

        )

)
37
rayss

J'utilise la fonction suivante pour cela; c'est une adaptation de l'une des entrées man dans les commentaires fputscsv. Et vous voudrez probablement aplatir ce tableau; je ne sais pas ce qui se passe si vous passez dans un multi-dimensionnel.

/**
  * Formats a line (passed as a fields  array) as CSV and returns the CSV as a string.
  * Adapted from http://us3.php.net/manual/en/function.fputcsv.php#87120
  */
function arrayToCsv( array &$fields, $delimiter = ';', $Enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
    $delimiter_esc = preg_quote($delimiter, '/');
    $Enclosure_esc = preg_quote($Enclosure, '/');

    $output = array();
    foreach ( $fields as $field ) {
        if ($field === null && $nullToMysqlNull) {
            $output[] = 'NULL';
            continue;
        }

        // Enclose fields containing $delimiter, $Enclosure or whitespace
        if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${Enclosure_esc}|\s)/", $field ) ) {
            $output[] = $Enclosure . str_replace($Enclosure, $Enclosure . $Enclosure, $field) . $Enclosure;
        }
        else {
            $output[] = $field;
        }
    }

    return implode( $delimiter, $output );
}
74
Paul

Ma solution nécessite que le tableau soit formaté différemment de celui fourni dans la question:

<?
    $data = array(
        array( 'row_1_col_1', 'row_1_col_2', 'row_1_col_3' ),
        array( 'row_2_col_1', 'row_2_col_2', 'row_2_col_3' ),
        array( 'row_3_col_1', 'row_3_col_2', 'row_3_col_3' ),
    );
?>

Nous définissons notre fonction:

<?
    function outputCSV($data) {
        $outputBuffer = fopen("php://output", 'w');
        foreach($data as $val) {
            fputcsv($outputBuffer, $val);
        }
        fclose($outputBuffer);
    }
?>

Ensuite, nous sortons nos données au format CSV:

<?
    $filename = "example";

    header("Content-type: text/csv");
    header("Content-Disposition: attachment; filename={$filename}.csv");
    header("Pragma: no-cache");
    header("Expires: 0");

    outputCSV($data);
?>

Je l'ai utilisé avec plusieurs projets et cela fonctionne bien. Je dois noter que le code outputCSV est plus intelligent que moi, donc je suis sûr que je ne suis pas l'auteur original. Malheureusement, j'ai perdu la trace d'où je l'ai obtenu, donc je ne peux pas donner le crédit à qui il est dû.

43
kingjeffrey

Une légère adaptation à la solution ci-dessus par kingjeffrey pour quand vous voulez créer et faire écho au CSV dans un modèle (c'est-à-dire que la plupart des frameworks auront la mise en mémoire tampon de sortie activée et vous devez définir des en-têtes, etc. dans les contrôleurs.)

// Create Some data
<?php
    $data = array(
        array( 'row_1_col_1', 'row_1_col_2', 'row_1_col_3' ),
        array( 'row_2_col_1', 'row_2_col_2', 'row_2_col_3' ),
        array( 'row_3_col_1', 'row_3_col_2', 'row_3_col_3' ),
    );


// Create a stream opening it with read / write mode
$stream = fopen('data://text/plain,' . "", 'w+');

// Iterate over the data, writting each line to the text stream
foreach ($data as $val) {
    fputcsv($stream, $val);
}

// Rewind the stream
rewind($stream);

// You can now echo it's content
echo stream_get_contents($stream);

// Close the stream 
fclose($stream);

Mention à Kingjeffrey ci-dessus et aussi à cela article de blog où j'ai trouvé les informations sur la création de flux de texte.

15
Ben Waine
function array_2_csv($array) {
    $csv = array();
    foreach ($array as $item) {
        if (is_array($item)) {
            $csv[] = array_2_csv($item);
        } else {
            $csv[] = $item;
        }
    }
    return implode(',', $csv);
} 

$csv_data = array_2_csv($array);

echo "<pre>";
print_r($csv_data);
echo '</pre>'   ; 
14
Paulraj

La réponse acceptée de Paul est excellente. J'ai fait une petite extension à cela qui est très utile si vous avez un tableau multidimensionnel comme celui-ci (ce qui est assez courant):

Array
(
    [0] => Array
        (
            [a] => "a"
            [b] => "b"
        )

    [1] => Array
        (
            [a] => "a2"
            [b] => "b2"
        )

    [2] => Array
        (
            [a] => "a3"
            [b] => "b3"
        )

    [3] => Array
        (
            [a] => "a4"
            [b] => "b4"
        )

    [4] => Array
        (
            [a] => "a5"
            [b] => "b5"
        )

)

J'ai donc pris la fonction de Paul d'en haut:

/**
  * Formats a line (passed as a fields  array) as CSV and returns the CSV as a string.
  * Adapted from http://us3.php.net/manual/en/function.fputcsv.php#87120
  */
function arrayToCsv( array &$fields, $delimiter = ';', $Enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
    $delimiter_esc = preg_quote($delimiter, '/');
    $Enclosure_esc = preg_quote($Enclosure, '/');

    $output = array();
    foreach ( $fields as $field ) {
        if ($field === null && $nullToMysqlNull) {
            $output[] = 'NULL';
            continue;
        }

        // Enclose fields containing $delimiter, $Enclosure or whitespace
        if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${Enclosure_esc}|\s)/", $field ) ) {
            $output[] = $Enclosure . str_replace($Enclosure, $Enclosure . $Enclosure, $field) . $Enclosure;
        }
        else {
            $output[] = $field;
        }
    }

    return implode( $delimiter, $output );
}

Et ajouté ceci:

function a2c($array, $glue = "\n")
{
    $ret = [];
    foreach ($array as $item) {
        $ret[] = arrayToCsv($item);
    }
    return implode($glue, $ret);
}

Vous pouvez donc simplement appeler:

$csv = a2c($array);

Si vous voulez une fin de ligne spéciale, vous pouvez utiliser le paramètre facultatif "colle" pour cela.

0
Marco