使用PHP在CSV文件中用双引号括起每个字段?

时间:2015-07-22 09:29:17

标签: php codeigniter csv

我需要使用PHP将所有字符串和数字用双引号放在CSV文件中。

如何在双引号内的所有数据中从PHP创建CSV文件?

我正在使用此代码生成CSV - 我正在使用codeigniter框架

$array = array(
    array(
     (string)'XXX XX XX',
     (string)'3',
     (string)'68878353',
     (string)'',
     (string)'xxxx@xxxx.xxx.xx',
    ),
);

$this->load->helper('csv');
array_to_csv($array, 'blueform.csv'); 

我得到的输出:

"XXX XX XX",3,68878353,,xxxx@xxxx.xxx.xx

预期输出:

"XXX XX XX","3","68878353","","xxxx@xxxx.xxx.xx"

array_to_csv代码

if (!function_exists('array_to_csv')) {
    function array_to_csv($array, $download = "") {
        if ($download != "") {   
            header('Content-Type: application/csv');
            header('Content-Disposition: attachement; filename="' . $download . '"');
        }

        ob_start();
        $f = fopen('php://output', 'w') or show_error("Can't open php://output");
        $n = 0;
        foreach ($array as $line) {
            $n++;
            if (!fputcsv($f, $line)) {
                show_error("Can't write line $n: $line");
            }
        }
        fclose($f) or show_error("Can't close php://output");
        $str = ob_get_contents();
        ob_end_clean();

        if ($download == "") {
            return $str;
        } else {
            echo $str;
        }
    }
}

提前谢谢

10 个答案:

答案 0 :(得分:5)

在PHP中构建CSV时,您应该使用PHP 5中提供的fputcsv函数

从文档中可以得到以下参数:

你有:

  • 您正在写入
  • 的文件资源
  • 要放入CSV的数据
  • 分隔符(通常是逗号)
  • 字符串附件(这是您要引用的位)
  • 转义字符串(因此,如果您的数据包含机箱字符,则可以将其转义以避免它看起来像新字段)

由于分隔符的默认值为int fputcsv ( resource $handle , array $fields [, string $delimiter = "," [, string $enclosure = '"' [, string $escape_char = "\" ]]] ) ,而机箱的默认值为,,因此您无需添加更多内容。这将正确覆盖字符串。这些数字是另一回事。在this SO question上有一个解决方法,我在输入大部分内容之后找到了这个问题,然后仍然遇到数字问题:

  

对此解决方案不满意,但这是我所做的和工作的。这个想法   是在fputcsv上设置一个空字符作为外壳字符并添加一些   引用数组的每个元素。

"

答案 1 :(得分:2)

使用此'"""';

连接字符串

示例:'"""' . {{String}} . '"""';

这应该有效,对我有用。这是一种封装字符串的方法。

答案 2 :(得分:1)

我在这里使用CSV帮助器。

用于生成db查询的结果。

$sTable = "MY_TABLE_NAME";

$query = $this->db->get($sTable);

$this->load->helper('csv');

query_to_csv($query, TRUE, 'records.csv');

在CSV Helper onLine编号65中有query_to_csv的代码。

这里是 csv_helper.php

如果你想要所有的双重逗号,我在那里做了一个小编辑。

    <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

// ------------------------------------------------------------------------

/**
 * CSV Helpers
 * Inspiration from PHP Cookbook by David Sklar and Adam Trachtenberg
 * 
 * @author      Jérôme Jaglale
 * @link        http://maestric.com/en/doc/php/codeigniter_csv
 */

// ------------------------------------------------------------------------

/**
 * Array to CSV
 *
 * download == "" -> return CSV string
 * download == "toto.csv" -> download file toto.csv
 */
if ( ! function_exists('array_to_csv'))
{
    function array_to_csv($array, $download = "")
    {
        if ($download != "")
        {   
            header('Content-Type: application/csv');
            header('Content-Disposition: attachement; filename="' . $download . '"');
        }       

        ob_start();
        $f = fopen('php://output', 'w') or show_error("Can't open php://output");
        $n = 0;     
        foreach ($array as $line)
        {
            $n++;
            if ( ! fputcsv($f, $line))
            {
                show_error("Can't write line $n: $line");
            }
        }
        fclose($f) or show_error("Can't close php://output");
        $str = ob_get_contents();
        ob_end_clean();

        if ($download == "")
        {
            return $str;    
        }
        else
        {   
            echo $str;
        }       
    }
}

// ------------------------------------------------------------------------

/**
 * Query to CSV
 *
 * download == "" -> return CSV string
 * download == "toto.csv" -> download file toto.csv
 */
if ( ! function_exists('query_to_csv'))
{
    function query_to_csv($query, $headers = TRUE, $download = "")
    {
        if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
        {
            show_error('invalid query');
        }

        $array = array();

        if ($headers)
        {
            $line = array();
            foreach ($query->list_fields() as $name)
            {
                $line[] = '"'.$name.'"';
            }
            $array[] = $line;
        }

        foreach ($query->result_array() as $row)
        {
            $line = array();
            foreach ($row as $item)
            {
                $line[] = '"'.$item.'"';
            }
            $array[] = $line;
        }

        echo array_to_csv($array, $download);
    }
}

/* End of file csv_helper.php */
/* Location: ./system/helpers/csv_helper.php */

这将在列名和行中提供Insert双引号。 您也可以从列名中删除“”。

enter image description here

答案 3 :(得分:0)

稍微改变你的代码。

fputcsv($f, $line)

fputcsv($f,array_map('strval', $line), ',', '"')

希望这会对你有所帮助。

仅供参考:它在array_to_csv

答案 4 :(得分:0)

我可能只是用本土版本替换fputcsv。现在我把你的数据结构变成一个像传统的传播和CSV文件一样的网格。

function getQuotedString($arr){
    $buffer = "";
    foreach($arr as $line){
        $string = "";
        foreach($line as $data){
            // See if $string is no longer empty, meaning we need a comma to separate data
            if($string !== "") $string .= ',';
            $string .= '"' . $data . '"';
        }
        $buffer .= $string . PHP_EOL;
    }
    return $buffer;
}

现在在你的代码中使用它:

...
ob_start();
$f = fopen('php://output', 'w') or show_error("Can't open php://output");
$quotedData = getQuotedString($arr);

for ($written = 0; $written < strlen($data); $written += $fwrite) {
    $fwrite = fwrite($f, substr($data, $written));
    if ($fwrite === false) {
        return $written;
    }
}

fclose($f) or show_error("Can't close php://output");
$str = ob_get_contents();
ob_end_clean();
...

然后你可以使用$ written来查看写入的字节数,或者如果你想知道有多少行,你可以使用sizeof($ arr)。

希望这有帮助!

答案 5 :(得分:0)

内爆功能不会很好用吗?

$array = [ 
 (string)'XXX XX XX',
 (string)'3',
 (string)'68878353',
 (string)'',
 (string)'xxxx@xxxx.xxx.xx'
];
$csvData = '"' . implode('","', $array) . '"';

然后你可以把$ csvData写到你的文件中吗?

答案 6 :(得分:0)

当然还有其他方法可以处理它,但是使用fputcsv并适用于大多数情况。

if(!function_exists('array_to_csv')) {
    function array_to_csv($array, $download = "") {
        ob_start();
        $f = fopen('php://output', 'w') or die("Can't open php://output");
        $counter = count($array);
        for ($i = 0; $i < $counter; $i++) { 
            if(!fputcsv($f, array_map(function($value) {  return '"'.$value.'"';  }, $array[$i]), ",", "\"")) {
                die("Can't write line $i: ".print_r($array[$i], true));
            }
        }
        fclose($f) or die("Can't close php://output");
        $str = str_replace('"""', '"', ob_get_contents());
        ob_end_clean();

        if(strlen($download) > 0) {
            header('Content-Type: application/csv');
            header('Content-Disposition: attachment; filename="'.$download.'"');
            echo $str;
        } else {
            return $str;
        }
    }
}

答案 7 :(得分:0)

不要努力用双引号正确封闭每个字段。 内置php函数可用于完成工作而不会出错。

不仅需要双引号,还需要单引号('),双引号("),反斜杠(\)和NULL(NULL字节)。

使用fputcsv()撰写,fgetcsv()阅读,这将照顾所有人。

答案 8 :(得分:0)

您可以使用implode() function使上面的代码更简单:

$delimiter = ';';
$enclosure = '"';
$linefeed  = "\n";

$lines = array();
// traversing data, one row at a time
foreach ($data as $row) {
    $arr = array();
    // traversing row, col after col
    foreach ($row as $col => $val) {
        // MySQL-style escaping double quotes
        $val = str_replace('"','""',$val);
        // wrapping each value in double quotes
        $arr[] = sprintf('%s%s%s',$enclosure,$val,$enclosure);
    }
    // generating formatted line and storing it
    $lines[] = implode($delimiter,$arr);
}
// join each lines to have the final output
$output = implode($linefeed,$lines);
echo $output;

答案 9 :(得分:-1)

我有解决方案 此函数将多维数组转换为CSV,带双引号和

function arr_to_csv($arr)
  {
        $filePointer="export.csv";
        $delimiter=",";
        $enclosure='"';
        $dataArray =$arr;

        $string = "";

        // No leading delimiter
        $writeDelimiter = FALSE;
        //foreach($dataArray as $dataElement)
        foreach ($dataArray as $key1 => $value){
        foreach ($value as $key => $dataElement) 

         {
          // Replaces a double quote with two double quotes
          $dataElement=str_replace("\"", "\"\"", $dataElement);
          // Adds a delimiter before each field (except the first)
          // Encloses each field with $enclosure and adds it to the string
          if($writeDelimiter) $string .= $delimiter;
          // $new_string = $enclosure . $dataElement . $enclosure;
          $string .= $enclosure . $dataElement . $enclosure;
         // Delimiters are used every time except the first.
          $writeDelimiter = TRUE;
         } // end foreach($dataArray as $dataElement)

                $string .= "\n";

         }      
        // Append new line
        $string .= "\n";    
         //$string = "An infinite number of monkeys";
        print($newstring);
       // Write the string to the file
      // fwrite($filePointer,$string);
       header('Content-Type: application/csv');
      header('Content-Disposition: attachment; filename="'.$filePointer.'";');
  }