通过productid将CSV数据垂直转换为水平

时间:2014-05-29 21:08:16

标签: php csv transpose

我有一个在线的csv文件,需要通过php进行转换,因为这需要每小时完成一次(cronjobs)。

我使用此csv将产品导入opencart,并使用karapuz的'csv-import'模块。

我目前的csv看起来像这样:

ProductID;ImageUrl;Sequence;LastUpdate
6867;[urllink0];0;19-08-2013
6867;[urllink1];1;19-08-2013
6867;[urllink2];2;20-03-2012
6867;[urllink3];0;19-08-2013
6867;[urllink4];1;19-08-2013
6867;[urllink5];2;19-08-2013
6867;[urllink6];3;20-03-2012
6867;[urllink7];4;20-03-2012
6867;[urllink8];2;20-03-2012
6867;[urllink9];0;19-08-2013
6867;[urllink10];1;20-03-2012
8352;[urllink11];0;19-03-2013
8352;[urllink12];1;20-03-2012
9970;[urllink13];0;19-08-2013
9970;[urllink14];1;20-03-2012
9970;[urllink15];0;19-08-2013
9970;[urllink16];1;19-08-2013
9970;[urllink17];2;20-03-2012
9970;[urllink18];3;20-03-2012
9970;[urllink19];0;19-03-2013
9970;[urllink20];0;19-08-2013
9970;[urllink21];1;19-08-2013
9970;[urllink22];2;20-03-2012
9970;[urllink23];3;20-03-2012
9970;[urllink24];5;20-03-2012
9970;[urllink25];6;20-03-2012

...................... 19000行

因此,某个产品的每个图像都会排成行。

对于我的导入脚本,csv应如下所示:(每行1个产品)

productid;main image;additional images;
6867;[urllink0];[urllink1]:::[urllink2]:::.........;
8352;[urllink11];[urllink12];
9970;[urllink13];[urllink14]:::[urllink15]:::[urllink16]..........;

其他图片位于1个单元格中,由“:::”分隔。

因此,行应转换为列,但图像的数量(序列)是可变的。

提前致谢。

3 个答案:

答案 0 :(得分:1)

如果我正确理解了这个问题,那么您要做的就是更改CSV文件的格式,以便将其导入到karapuz的'csv-import'模块的导入友好格式中。

您需要解析CSV,然后以其他格式重写它。尝试将其解析为CSV文件并将值放入数组中。从这里开始,您需要做的就是以新格式重写CSV文件。希望这会有所帮助:

 $pid,$prods =array();
 $file = fopen('remove.csv', 'r');
 while (($line = fgetcsv($file)) !== FALSE) {
     print_r($line);
     $pid =  explode(";",$line[0]);
     $prods[$pid[0]][] = $pid[1];
 }
 fclose($file);


 print_r($prods) // outputs below:
 [6867] => Array
    (
        [0] => [urllink0]
        [1] => [urllink1]
        [2] => [urllink2]
        [3] => [urllink3]
        [4] => [urllink4]
        [5] => [urllink5]
        [6] => [urllink6]
        [7] => [urllink7]
        [8] => [urllink8]
        [9] => [urllink9]
        [10] => [urllink10]
    )

[8352] => Array
    (
        [0] => [urllink11]
        [1] => [urllink12]
    )

[9970] => Array
    (
        [0] => [urllink13]
        [1] => [urllink14]
        [2] => [urllink15]
        [3] => [urllink16]
        [4] => [urllink17]
        [5] => [urllink18]
        [6] => [urllink19]
        [7] => [urllink20]
        [8] => [urllink21]
        [9] => [urllink22]
        [10] => [urllink23]
        [11] => [urllink24]
        [12] => [urllink25]
    )

答案 1 :(得分:0)

好的,谢谢Ricky!我快到了。

现在我正在尝试这个

$filename1='basimage1.csv';
$filename2='basimage2.csv';

//$fp = fopen($filename2, 'w'); 

$pid = array();
$prods = array();
$file = fopen($filename1, 'r');
    while (($line = fgetcsv($file)) !== FALSE) {
        $pid =  explode(";",$line[0]);
        $prods[$pid[0]][] = $pid[1];
    }
fclose($file);

$delimiter=';';
$devider=':::';

foreach ($prods as $line) {

    //If 5 images -> 1 main image + 4 additional images devided by ':::'
    if ($line[4]) {
        $csvline = $line[0] . $delimiter . $line[1] . $devider . $line[2] . $devider . $line[3] . $devider . $line[4] . $delimiter;     
    }

    //If 4 images -> 1 main image + 3 additional images devided by ':::'
    elseif ($line[3]) {
        $csvline = $line[0] . $delimiter . $line[1] . $devider . $line[2] . $devider . $line[3] . $delimiter;       
    }

    //If 3 images -> 1 main image + 2 additional images devided by ':::'
    elseif ($line[2]) {
        $csvline = $line[0] . $delimiter . $line[1] . $devider . $line[2] . $delimiter;     
    }

    //If 2 images -> 1 main image + 1 additional image
    elseif ($line[1]) {
        $csvline = $line[0] . $delimiter . $line[1] . $delimiter;       
    }

    //If 1 images -> 1 main image 
    elseif ($line[3]) {
        $csvline = $line[0] . $delimiter;       
    }

echo $csvline . '<br>';

}

我需要的是从数组中获取productid(在示例6867中),这是子键。现在创建的数组是:

Array
 (
[6867] => Array
  (
    [0] => [urllink1] ....
  )
 .............
)

答案 2 :(得分:0)

我已通过以下代码实现了目标:

//include settings for url and credentials
include 'config.php';

//Rico Computers Download script for BAS
$filename1='basimage1.csv';
$filename2='basimage2.csv';
$delimiter=';';
$devider=':::';

echo 'Downloading Bas CSV ... ';
file_put_contents ($filename1, file_get_contents($basurlimage));

echo 'OK<br>';
echo filesize($filename1) . ' bytes.<br>';

echo '<br>';

echo 'Editing Downloaded CSV ...<br>';

//open the destination file
$fp = fopen($filename2, 'w'); 

//for counting processed lines
$i=1;

//Output to Screen Table
echo '<table colspan=3 border=1>'; 

$pid = array();
$prods = array();
$file = fopen($filename1, 'r');
    while (($line = fgetcsv($file)) !== FALSE) {
        $pid =  explode(";",$line[0]);
        $prods[$pid[0]][] = $pid[1];


    }
fclose($file);

 foreach ($prods as $product_id => $line) {

//If 5 images -> 1 main image + 4 additional images devided by ':::'
if ($line[4]) {
    $mainimage = $line[0];
    $additionalimages = $line[1] . $devider . $line[2] . $devider . $line[3] . $devider . $line[4];     
}

//If 4 images -> 1 main image + 3 additional images devided by ':::'
elseif ($line[3]) {
    $mainimage = $line[0];
    $additionalimages = $line[1] . $devider . $line[2] . $devider . $line[3];       
}

//If 3 images -> 1 main image + 2 additional images devided by ':::'
elseif ($line[2]) {
    $mainimage = $line[0];
    $additionalimages = $line[1] . $devider . $line[2];     
}

//If 2 images -> 1 main image + 1 additional image
elseif ($line[1]) {
    $mainimage = $line[0];
    $additionalimages = $line[1];       
}

//If 1 images -> 1 main image 
elseif ($line[0]) {
    $mainimage = $line[0];
        //Add Extra Header for new Column  
        if ($product_id == 'ProductID') { 
           $additionalimages = 'Additional Images'; 
           } else {
            $additionalimages = ''; 
        }   
}



fputcsv($fp,array($product_id, $mainimage, $additionalimages),$delimiter);

//Create Output 
echo '<tr>';    
echo '<td>' . $product_id . '</td>';
echo '<td>' . $mainimage . '</td>';
echo '<td>' . $additionalimages . '</td>';
echo '</tr>';   

flush();
ob_flush();
ob_end_flush();

$i++;

}

//close source and destination files
fclose($fp);

?>

</table>

<br>
<?php
echo '<br>Processed ' . $filename2 . ' to ' . filesize($filename2) . ' bytes.</td></tr>';
echo 'Lines processed: ' . $i . '</br>';
?>