如何在每个字段中添加双引号并在下一行打印新行 - PHP CSV

时间:2016-07-22 03:20:49

标签: php csv fputcsv

我有一个手动创建CSV文件的文件数据。

然后我解析该文件并选择必要的数据并从中创建新的CSV文件。

直到那一步事情很好并且有效但问题是当我在文本文件中打开新文件时,它会错过每个字段周围的双引号,并且每行的结尾都没有新行。

以下是CSV文件的数据:

TransactionNumber   CustomerName    ReferenceNumber PurchaseOrderNumber ShipCarrier ShipService ShipBilling ShipAccount EarliestShipDate    CancelDate  Notes   ShipToName  ShipToCompany   ShipToAddress1  ShipToAddress2  ShipToCity  ShipToState ShipToZip   ShipToCountry   ShipToPhone ShipToFax   ShipToEmail ShipToCustomerName  ShipToDeptNumber    ShipToVendorID  TotalCartons    TotalPallets    TotalWeight TotalVolume BOLNum  TrackingNum TrailerNum  SealNum ShipDate    ItemNumber  ItemQuantityOrdered ItemQuantityShipped ItemLength  ItemWidth   ItemHeight  ItemWeight  FreightPP   WarehouseID LotNumber   SerialNumber    ExpirationDate  Supplier    Cost    FulfillInvShippingAndHandling   FulfillInvTax   FulfillInvDiscountCode  FulfillInvDiscountAmount    FulfillInvGiftMessage   SoldToName  SoldToCompany   SoldToAddress1  SoldToAddress2  SoldToCity  SoldToState SoldToZip   SoldToCountry   SoldToPhone SoldToFax   SoldToEmail SoldToCustomerID    SoldToDeptNumber    FulfillInvSalePrice FulfillInvDiscountPct   FulfillInvDiscountAmt
242328  PARADIGM TRENDS 123810  40-402849   CUSTOMER PICK UP    LTL FreightCollect                  HG BUYING- JEFFERSON DC 884 HG BUYING- JEFFERSON DC 884 125 LOGISTICS CENTER PKWY       JEFFERSON   AL  30549   US                          30  0   30  0.0174      22              DOV3S   64  64  4   1   1   4   22  1                       0   0       0                                                           0   0   0
222223      123812  40-402850                                                                                       12      3                           DOV3M   64  64  4   1   1   4   442                                                                                                 0   0   0
242423      1238120 40-402851                                                                                       33      67          3               BY3S    176 176 11  1   1   11  2                                                                                                   0   0   0
7868        1233810 40-402852                                                                                       44      55          33              BY3M    176 176 11  1   1   11  45                                                                                                  0   0   0
989879      1234810 40-402853                                                                                       53      442         7                                           6                                                                                                           
        1253810 40-402854                                                                                       66                  88                                                                                                                                                      
898     1263810 40-402855                                                                                       88      66                                                      6                                                                                                           
888     1273810 40-402856                                                                                       32      88                                                      33                                                                                                          
333     1235810 40-402857                                                                                       8       8           9                                           5                                                                                                           
55      1233810 40-402858                                                                                       8       33                                                      7                                                                                                           
99      3332223 40-402859                                                                                       8       7           96                                          5                                                                                                           
996     356666  40-402860                                                                                       8       65          44                                                                                                                                                      

这里是文件文件中新文件的输出:

123810,30,"CUSTOMER PICK UP",22,22,30123812,12,,,442,31238120,33,,3,2,67 1233810,44,,33,45,551234810,53,,7,6,4421263810,88,,,6,661273810,32,,,33,88
1235810,8,,9,5,81233810,8,,,7,333332223,8,,96,5,7356666,8,,44,,65

所需的输出是:

"123810","30","CUSTOMER PICK UP","22","22","30"
"123812","12","","","442","3"
...

PHP代码

<?php
set_time_limit(0);
ini_set("memory_limit", -1);

$realPath = realpath( dirname(__FILE__) );
$path     = glob($realPath.'/3pltracking/*.csv');
$UpdPath  = $realPath . '/3pltracking/';
$files    = scandir($UpdPath);
$date     = date('m-d-Y_his');
$result   = array();
$csvData  = array();



if (file_exists($path[0])) 
{
    if (($handle = fopen($path[0], "r")) !== FALSE) 
        {
            $i=0;
            while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) 
            {
                $i++;
                if($i==1) continue;
                if($data[2] != ""){
                        $csvData[] = $data[2].','.$data[25].','.$data[4].','.$data[30].','.$data[41].','.$data[27];
                    }
            }

        fclose($handle);
        $fp      = fopen($realPath.'/3pltracking/TrackingFiles/Tracking_File_'.$date.'.csv', 'w');
        foreach ($csvData as $line) {
            fputcsv($fp, explode(",", $line));
        }
        fclose($fp);
        echo "Your CSV File Has Been Created In Folder Name => 'TrackingFiles' On Your FTP";
        }
    } else {
        echo "Please Upload Your CSV File First";
        }

        copy($UpdPath.$files[2], $realPath.'/3pltracking/UsedFiles/'.date('Y-m-d').'_'.rand(111, 999).'-'.$files[2]);
        //unlink($path[0]);
?>

3 个答案:

答案 0 :(得分:2)

function alternative_fputcsv($handle, $fields, $delimiter = ",", $enclosure = '"', $newline = "\r\n") {
    $string = $enclosure . implode($enclosure . $delimiter . $enclosure, $fields) . $enclosure . $newline;
    return fwrite($handle, $string);
}

调用此函数而不是fputcsv。应该做同样的工作,但要给你客户的预期行为。

无关建议:如果任何字段中有逗号,此$data[2].','.$data[25].','.$data[4].','.$data[30].','.$data[41].','.$data[27]将为您提供无效的csv。为什么不将这些字段放入数组而不是字符串?

答案 1 :(得分:1)

试试这个:

<?php
set_time_limit(0);
ini_set("memory_limit", -1);

$realPath = realpath( dirname(__FILE__) );
$path     = glob($realPath.'/3pltracking/*.csv');
$UpdPath  = $realPath . '/3pltracking/';
$files    = scandir($UpdPath);
$date     = date('m-d-Y_his');
$result   = array();
$csvData  = array();



if (file_exists($path[0])) 
{
    if (($handle = fopen($path[0], "r")) !== FALSE) 
        {
            $i=0;
            while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) 
            {
                $i++;
                if($i==1) continue;
                if($data[2] != ""){
                        //Changed the line below
                        $csvData[] = '"'.$data[2].'","'.$data[25].'","'.$data[4].'","'.$data[30].'","'.$data[41].'","'.$data[27].'"'."\r\n";
                    }
            }

        fclose($handle);
        $fp      = fopen($realPath.'/3pltracking/TrackingFiles/Tracking_File_'.$date.'.csv', 'w');
        foreach ($csvData as $line) {
            fputcsv($fp, explode(",", $line));
        }
        fclose($fp);
        echo "Your CSV File Has Been Created In Folder Name => 'TrackingFiles' On Your FTP";
        }
    } else {
        echo "Please Upload Your CSV File First";
        }

        copy($UpdPath.$files[2], $realPath.'/3pltracking/UsedFiles/'.date('Y-m-d').'_'.rand(111, 999).'-'.$files[2]);
        //unlink($path[0]);
?>

答案 2 :(得分:1)

最好在构建csvData数组时构建矩阵,然后不需要为爆炸而烦恼。

while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {
    $i++;
    if($i==1) continue;
    if($data[2] != "") {
        $csvData[] = [$data[2], $data[25], $data[4], $data[30], $data[41], $data[27]];
    }
}

fclose($handle);
$fp = fopen($realPath.'/3pltracking/TrackingFiles/Tracking_File_'.$date.'.csv', 'w');
foreach ($csvData as $row) {
    fputcsv($fp, $row);
}

然后正如@SergeyEremin所提到的,当你使用fputcsv时,只需要包含的字段就是,即。带空格或特殊字符的字段等。

如果您绝对需要用引号括起每个字段,那么您可能不应该使用fputcsv,而是按照您想要的方式构建该行,并使用fputs

while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {
    $i++;
    if($i==1) continue;
    if($data[2] != "") {
        $csvData[] = '"' . $data[2] . '","' . $data[25] . '","' . $data[4] . '","' . $data[30] . '","' .  $data[41] . '","' . $data[27] . '"' . "\r\n";
    }
}

fclose($handle);
$fp = fopen($realPath.'/3pltracking/TrackingFiles/Tracking_File_'.$date.'.csv', 'w');
foreach ($csvData as $row) {
    fputs($fp, $row);
}