【问题标题】:Retrieve multiple lines within same cell from CSV file从 CSV 文件中检索同一单元格中的多行
【发布时间】:2015-06-15 09:38:10
【问题描述】:

我正在尝试从 CSV 文件中检索一些数据。我使用以下代码通过 CSV:

//create array for csv file
$array_data = array();
$row = 0;
if (($handle = fopen("import/pdf_data.csv", "r")) !== FALSE) {
    // read the CSV from root folder "web/interval/import"
    while (($data = fgetcsv($handle, 0, ";")) !== FALSE) {
        if ($row > 0) {
            $array_data[$row] = $data;
        }
        $row++;
    }
    fclose($handle);
}

//loop through all the feature data array
foreach ($array_data as $entry_value => $array_column) {
    foreach( $array_column as $value )
    {       
       //split data
       list($col1,$col2,$col3) = explode( ',', $value );

       echo "Name: ".$col1.", Surname: ".$col2.", Text: ".$col3."<br/>";

当我打印列时... col1 和 col2 很好,因为它们的单元格中只有一个值。 col3 可能包含多行。比方说(见下面 col3 的一个单元格):

col3
::::::::::::::
Text-a in line 1
Text-a in line 2
Text-a in line 3

如果一个单元格中有多行,则 CSV 输出将如下所示: "第 1 行中的文本-a 第 2 行中的文本-a 第 3 行中的文本-a"

并使用我在上面使用的代码打印第一行 "第 1 行中的文字-a 然后在一个新条目中的第二行等。

我想要实现的是如下格式

echo "Name: ".$col1.", Surname: ".$col2.", Text: ".$col3."<br/>";

当我得到这个时,这不适用于多行:

  • 姓名:Test,姓氏:Test2,文本:“第 1 行中的文本-a
  • 姓名:,姓氏:,文字:第 2 行中的文字-a

如有任何建议,将不胜感激,谢谢

【问题讨论】:

  • 你有很多未定义的变量和代码,这里没有给我们展示!
  • 你到底想让我展示什么? csv 内容?
  • 是的,请提供一整行 CSV 内容,只要它们在引用的单元格中,fgetcsv 就应该从内存中处理换行符
  • 好的,我刚刚上传了内容 :) 检查 ID:例如 91 或 58。您可以看到换行符将信息移动到具有空 ID 的新行。它们应该在同一行。我尝试使用 str_replace 并用空格替换 /n 或 /r 但仍然没有运气
  • 在 excel 中是文本 1,然后是换行和文本 2。当我将它转换为 CSV 并用记事本打开它时,它是用引号引起来的......就像没有空格的“text1text2”。您可以在我发布的屏幕截图中看到它在 PHP 中的外观。

标签: php csv


【解决方案1】:

CSV 文件的单元格中可能包含多行值。但它需要用引号括起来。 Excel 正确执行此操作 - 创建一个测试文件并保存为 CSV。 PHP 函数 fgetcsv 也可以正确读取此类文件。

示例文件:

"col1","col2","col3"
"test1","test2.1
test2.2
test2.3","test3"

第二行的第二列包含多行值,这是一个完全有效的 CSV 文件。


这是正确的代码:

$array_data = array();
$row = 0;
if (($handle = fopen("import/pdf_data.csv", "r")) !== FALSE) {
    // read the CSV from root folder "web/interval/import"
    while (($data = fgetcsv($handle, 0, ",")) !== FALSE) {
        if ($row > 0) {
            $array_data[$row] = $data;
        }
        $row++;
    }
    fclose($handle);
}

//loop through all the feature data array
foreach ($array_data as $row) {
   list($col1,$col2,$col3) = $row;

   echo "Name: ".$col1.", Surname: ".$col2.", Text: ".$col3."<br/>";
}

【讨论】:

  • 是的,这是正确的。在 CSV 中,带引号等看起来没问题。但是当我回显它时,您可以从屏幕截图中看到它进入了一个新行。它用第一个文本打印一个引号,然后用第二个文本进入第二行。或者我试图将数据插入数据库。同样,它转到新行而不是一个字段。
  • 这可能与使用奇怪的 CSV 格式的 Excel 相关(它实际上取决于语言环境)。我注意到您将分号指定为字段分隔符,这表明 Excel 已将其保存为不带引号。您可以将文件保存为 CSV,然后在记事本中打开。它有引号吗?请将其发布到您的问题中。
  • 是的,在 CSV 中它显示它应该是怎样的。用引号和逗号作为分隔符。现在我只是想找到一种方法来删除那些断线,并将 column3 与其余列放在一行中
  • 我想我知道出了什么问题。您的 CSV 文件实际上使用逗号,但您指定了分号。所以 fgetcsv 只是从文件中读取一行而不是解析 CSV 格式。这就是为什么你必须在之后放置explode()。更改 fgetcsv 调用以使用逗号作为分隔符并删除爆炸
  • 我认为您确实找到了解决方案。现在它似乎工作了,这很棒!我花了这么多小时。感谢您的帮助
【解决方案2】:

我可以通过另一个简单的解决方案为您提供建议。它正在使用fgets()explode()

$handle = fopen("inputfile.txt", "r");
$out = array();
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        $arr = explode(',' $line);
        $out[] = trim($arr[2]); // Supposing you want to get the third cell.
    }

    fclose($handle);
} else {
    // error opening the file.
}
print_r($out); 

参考How to read a file line by line in php

【讨论】:

  • 使用explode() 正是导致问题的原因,因此必须避免。它不能正确处理带引号和多行字符串。
  • 当字符串本身包含分隔符时,explode 可能导致的唯一问题。即,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
  • 1970-01-01
  • 2016-01-04
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多