1

我正在使用此代码使用 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();

你能帮忙吗?

问候,

4

3 回答 3

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();
于 2012-04-25T12:16:56.057 回答
2

就像@ChrisPatrick 指出的那样,这条线

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

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

于 2012-04-25T12:21:20.047 回答
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);
}
于 2012-04-25T12:17:13.373 回答