【问题标题】:PHP How to handle/parse csv files that have missing columnsPHP如何处理/解析缺少列的csv文件
【发布时间】:2021-10-06 14:35:30
【问题描述】:

我有很多第三方生成的 csv 文件,对此我没有发言权或控制权。

所以我每天都要将这些csv数据导入mysql。

有些表的列数与标题匹配正确。

其他人没有。

即使我做了一个准备好的语句,它仍然没有导入。

我尝试创建一个修复 csv 函数,如果它们的列数小于标题列数,则为每一行添加额外的列。

作为这个项目的一部分,我正在使用 composer 包联盟 csv。

https://csv.thephpleague.com/

但这是我的功能代码:

public function repaircsv(string $filepath) {
    
    // make sure incoming file exists
    if (!file_exists($filepath)) {
        
        // return nothing
        return;
    }
    
    // setup variables
    $tempfile = pathinfo($filepath,PATHINFO_DIRNAME).'temp.csv';
    $counter = 0;
    $colcount = 0;
    $myline = '';
    
    // check if temp file exists if it does delete it
    if (file_exists($tempfile)) {
        
        // delete the temp file
        unlink($tempfile);
        
    }

    // C:\Users\admin\vendor\league\csv
    require('C:\Users\admin\vendor\league\csv\autoload.php');
    
    // step one get header column count
    $csv = Reader::createFromPath($filepath);
    
    // set the header offset
    $csv->setHeaderOffset(0);

    //returns the CSV header record
    $header = $csv->getHeader();

    // get the header column count
    $header_count = count($header);
    
    // check if greater than zero and not null
    if ($header_count < 1 || empty($header_count)) {
        
        // return nothing
        return $header_count;
        
    }
    
    // loop thru csv file
    // now read file line by line skipping line 1
    $file = fopen($filepath, 'r');
    $temp = fopen($tempfile, 'w');

    // loop thru each line
    while (($line = fgetcsv($file)) !== FALSE) {
        
        // if first row just straight append
        if ($counter = 0) {
            
            // append line to temp file
            fputcsv($temp, $line);
            
        }
        
        // if all other rows compare column count to header column count
        if ($counter > 0) {
            
            // get column count for normal rows
            $colcount = count($line);
            
            // compare to header column count
            $coldif = $header_count - $colcount;
            
            // loop til difference is zero
            while ($colcount != $header_count) {
            
                // add to line extra comma
                $line .= ',';
                
                // get new column count
                $colcount = count($line);
                
            }
            
            // append to temp file
            fputcsv($temp, $line);
            
            // show each line
            $myline .= 'Line: ['.$line.']<br/><br/>';
            
        }
        
        // increment counter
        $counter++;

    }
    
    // check file size of temp file
    $fs = filesize($tempfile);
    
    // if below 200 ignore and do not copy
    if ($fs > 200) {
    
        // copy temp to original filename
        copy($tempfile,$filepath);
        
    }
    
    return $myline;
}

逻辑是将原始 csv 文件复制到一个新的临时 csv 文件,并在缺少列的数据行中添加额外的逗号。

感谢您的帮助。

编辑:所以各种csv包含私人数据,所以我不能分享它们。

但是,例如,假设我每天为不同的数据下载多个 csv。

每个 csv 都有一个标题行和数据。

如果每行中的列数与标题中的列数不是 100% 相同,则会出错。

如果有特殊字符,会报错。

有 1000 行数据。

上面的代码是我第一次尝试修复缺少列的行。

这是一个例子 名:姓:电子邮箱 史蒂夫,乔布斯 ,约翰逊,sj@johns.com

只是一个很小的例子。

我无法控制 csv 的创建方式,我可以控制下载过程和导入过程。

然后我使用 csv 数据来更新 mysql 表。

我已经尝试过加载数据 infile,但也出现了错误。

所以我需要在下载 csv 文件后对其进行修复。

有什么想法吗?

【问题讨论】:

  • 不太清楚问题是什么:您是否有一个示例文件,其中您的代码没有给出您需要的结果?
  • CSV 是否有标题行?如果是这样,那会让事情变得更容易。如果没有,你会很头疼
  • 如果数据中的列数与标题的列数不匹配,则生成的 csv 文件有问题。文件中的各个行的列数是否不同,或者文件中所有数据行的列数是否一致?这可能是一个线索。
  • 它们确实变化很大,而且任何时候一行与列数不匹配,它都会停止整个导入过程。
  • "它会停止整个导入过程。" 否则您会发生什么?你怎么可能以编程方式知道哪些列“丢失”了?如果您要猜测或只是在文件末尾添加空白列,那么您将面临将数据本身从列标题中解构的极端风险。出现这些错误是有原因的,除了修复上游流程之外,没有可靠的方法来解决这个问题。

标签: php csv repair


【解决方案1】:

不要混合使用数组和字符串,而不是 $line .= ',';$Line[]= '';

同时修复:

$myline .= 'Line: ['.implode(',', $line).']<br/><br/>';

建议,您可以将 while 循环替换为:

$line = array_pad($line, $header_count, ''); // append missing items
$line = array_slice($line, 0, $header_count); // remove eventual excess items 

【讨论】:

    猜你喜欢
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 2011-04-25
    • 1970-01-01
    • 2012-08-12
    相关资源
    最近更新 更多