使用PHP导出到CSV文件

时间:2012-04-25 12:07:17

标签: php mysql

我正在使用此代码使用PHP将选定的数据从MySQL导出到CSV,我遇到一个小问题,当数据导出到csv文件时,它看起来如下所示:

第一行在正确的位置,但从第二行数据开始向右移动一个空格,如果我在Excel中打开csv文件,我可以在第一行为空后看到最左边的单元格。

parts   destination 
===================     
1   9.71504E+11 
1   9.71504E+11
1   96656587662
1   9.71504E+11

这是我的代码:

$values =mysql_query( "SELECT parts,destination from log");

$rown = 0;
$row = array();
$row[] = 'parts';
$row[] = 'destination'."\n";
$data .= join(',', $row)."\n";

while( $row_select = mysql_fetch_assoc($values) ) {
  if($rown++==0)
    $row = array();

  $row[] = $row_select['parts'];
  $row[] = $row_select['destination']."\n";
}
$data .= join(',', $row)."\n";

$filename = $file."_".date("Y-m-d_H-i",time());
header("Content-type: text/csv");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header( "Content-disposition: filename=".$filename.".csv");
print $data;
exit();
你能帮忙吗?

此致

3 个答案:

答案 0 :(得分:3)

  

第一行在正确的位置,但从第二行数据开始向右移动一个空格,如果我在Excel中打开csv文件,我可以在第一行为空后看到最左边的单元格。

我发现写CSV的难度比人们想象的要复杂得多。例如,转义值,以便在值内部正确转义分隔符。我创建了一个使用fwritecsv()而不是尝试自己呈现CSV的简单类:

编辑:我已将示例更改为您的使用方案。

<?php
/**
 * Simple class to write CSV files with.
 * 
 * @author Berry Langerak <berry@ayavo.nl>
 */
class CsvWriter {
    /**
     * The delimiter used. Default is semi-colon, because Microsoft Excel is an asshole.
     * 
     * @var string
     */
    protected $delimiter = ";";

    /**
     * Enclose values in the following character, if necessary.
     * 
     * @var string
     */
    protected $enclosure = '"';

    /**
     * Constructs the CsvWriter.
     */
    public function __construct( ) {
        $this->buffer = fopen( 'php://temp', 'w+' );
    }

    /**
     * Writes the values of $line to the CSV file.
     * 
     * @param array $line 
     * @return CsvWriter $this
     */
    public function write( array $line ) {
        fputcsv( $this->buffer, $line, $this->delimiter, $this->enclosure );
        return $this;
    }

    /**
     * Returns the parsed CSV.
     * 
     * @return string
     */
    public function output( ) {
        rewind( $this->buffer );
        $output = $this->readBuffer( );
        fclose( $this->buffer );

        return $output;
    }

    /**
     * Reads the buffer.
     * @return type 
     */
    protected function readBuffer( ) {
        $output = '';
        while( ( $line = fgets( $this->buffer ) ) !== false ) {
            $output .= $line;
        }
        return $output;
    }
}


/**
 * Example usage, in your scenario:
 */
$values = mysql_query( "SELECT parts,destination from log" );

$csv = new CsvWriter( );
$csv->write( array( 'parts', 'destination' ) ); // write header.

while( $line = mysql_fetch_assoc( $values ) ) {
    $csv->write( $line );
}

$filename = $file."_".date("Y-m-d_H-i",time());
header("Content-type: text/csv");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header( "Content-disposition: filename=".$filename.".csv");

print $csv->output( );

exit();

答案 1 :(得分:2)

就像@ChrisPatrick指出的那样,行

$data .= join(',', $row)."\n";

导致问题,您应该将其移至while循环内部,然后您将摆脱单元格跳过。

答案 2 :(得分:1)

问题出在以下一行

$data .= join(',', $row)."\n";

您使用逗号连接$row中的所有元素。因此,一行的目标与下一行的部分连接,中间有一个逗号,所以你得到这样的东西:

$data = $row_select['parts'] . ',' . $row_select['destination']."\n" . ',' . $row_select['parts'] etc...

换行符后面的逗号在行的开头创建一个空单元格。

更新它应该与以下

一起使用
while( $row_select = mysql_fetch_assoc($values)){
$row = array();
$row[] = $row_select['parts'];
$row[] = $row_select['destination']."\n";
$data .= join(',', $row);
}