【问题标题】:Wrap CSV values generated by PHP fputcsv() with " "用 " " 包装 PHP fputcsv() 生成的 CSV 值
【发布时间】:2010-09-28 22:51:32
【问题描述】:

所以,我的代码使用 PHP 的内置 fputcsv 函数生成了一个 CSV 文件。

对于分隔符,我使用','(逗号)。
对于附件,我使用'"'(双引号)。

但是,当我尝试像

fputcsv($file,array('a','b',"long string, with commas",NULL,''),',','"');

输出

a,b,"long string, with commas",,

但我希望它输出

"a","b","long string, with commas","",""

有没有简单的方法来处理这个问题,或者我必须为fputcsv写一个替换?

【问题讨论】:

  • 输出是有效的 CSV。你的另一个工具坏了。
  • 为什么要在每个字段上加上引号?
  • @Ignacio, Andrew:显然,隐藏在电子表格软件导入对话框的一个小角落里的是一个压缩多个空字段 (a,,, => a,) 和/或删除它们的选项(a,,, => a)。显然有些用户已经检查了这一点,但并不知道,所以简单、一刀切的解决方案是强制每个空字段为空字符串 (a,"","","")。

标签: php csv


【解决方案1】:

这对于 CSV 文件通常不是问题。

如果值不明确,fputcsv 会在值周围加上引号。例如,

a,b,"long string, with commas",,

不是模棱两可的,但是,

a,b,long string, with commas,,

在大多数(阅读:全部)情况下,CSV 阅读器会将其解释为具有超过 5 个字段。

CSV 解析器将接受字符串文字,即使它们周围没有引号。

如果你想在值周围加上引号,下面的 sn-p 会这样做。它不会在字符串中转义引号 - 该练习留给读者:

$row = '"' . implode('", "', $rowitems) . '"';

您可能希望将其放入所有行的循环中。

【讨论】:

  • 是的,我知道模棱两可,但实际上我需要用引号括起来的空白部分。我可以不用包裹非空的部分(当然,模棱两可的部分除外)。
  • 您的评论令人困惑。您想要用引号括起来的空部分,但非空部分可以不用包装?你是什​​么意思。发布的 sn-p 将所有引号括起来,这应该适用于所有 CSV 解析器。
  • 没关系。我有点困惑。是的,这应该有效。谢谢。
【解决方案2】:

我通过插入一些带有空格的虚假字符串字符#@ @#,然后删除它们来解决这个问题。这是一个示例实现:

//$exported is our array of data to export
$filename = 'myfile.csv';
$fp = fopen($filename, 'w');
foreach ($exported as $line => $row) {
    if ($line > 0) {
        foreach ($row as $key => $value) {
                $row[$key] = $value."#@ @#";
        }
    }
    fputcsv($fp, $row);
}

fclose($fp);
$contents = file_get_contents($filename);
$contents = str_replace("#@ @#", "", $contents);
file_put_contents($filename, $contents);

这会将所有字段括在双引号中,包括空字段

【讨论】:

  • 虽然这涉及打开和关闭文件的额外时间,但效果很好。
  • 这也让您可以为特定字段设置它,而不是为所有列 +1
  • 有点慢,但这是正常工作的唯一方法,谢谢!
【解决方案3】:

我认为解决方案是这样的,

$order_header_arr = array("Item1", "Item2","This is Item3");
fputcsv($fp, $order_header_arr,',',' ');

记住" "[空格] fputcsv第三个参数之间

【讨论】:

  • 这是最干净最快的答案
【解决方案4】:

任何你不能 str_replace(',,',',"",',$output); ?您还必须查看最后一个字符还是第一个字符是逗号,如果是,请将逗号替换为 ,""

【讨论】:

  • 这实际上是我的第一个想法,但后来我不得不截取文件写入字符串。 D:
  • 啊,是的。完全忘了考虑 fputcsv 实际上做了什么哈哈。您最好编写自己的函数来转义数据并使用 fputs 或 fwrite 输出数据。
【解决方案5】:

fputcsv 不会将所有数组变量括在引号中。没有引号的数字数组值可能是正确的,但当标签或地址程序遇到数字定义的美国邮政编码时会出现问题,因为它会在打印时去除前导零。因此 05123-0019 变为 5123-19。

为了将所有值(无论它们是否存在)括在引号中,我使用 fgetsrc 读取输入文件并使用 fwrite 编写更正版本。 fgetsrc 将记录读入数组变量。由于 fwrite 写入一个变量,因此您必须将数组变量串起来,用引号将它们括起来并用逗号分隔数组变量。然后添加记录分隔符。

<?php
// fgetcsv - read array with fgetcsv and string into output variable 
// then write with fwrite
// $ar is the array populated from fgetcsv and $arc is the variable strung 
// with array variables enclosed in quotes and written using fwrite.
$file_in = fopen("reinOCp.csv","r") or die("Unable to open input file 
reinOCp.csv!"); 
$file_out = fopen("printLABEL.csv", "w") or die("Unable to open output file 
prtLABEL!");
while (!feof($file_in)) {  //loop through each record of the input file
    $ar=fgetcsv($file_in); //read the record into array $ar   
    if (is_array($ar)){ //this loop will string all the array values plus 
// the end of record into variable $arc and then write the variable 
        $arc = ""; //clear variable $arc  
        foreach ($ar as $value) {      
            $arc .= '"' . $value . '",'; // add the array values, enclose in 
// quotes with comma separator and store in variable $arc
        }   
        $arc .= "\n"; //add end of record to variable $arc
        fwrite($file_out, $arc) or die ("ERROR: Cannot write the file"); 
//write the record using variable $arc
    }
}
echo "end of job";
fclose($file_in);
fclose($file_out);
?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    相关资源
    最近更新 更多