Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP电子表格读取CSV_Php_Csv_Spreadsheet - Fatal编程技术网

PHP电子表格读取CSV

PHP电子表格读取CSV,php,csv,spreadsheet,Php,Csv,Spreadsheet,我正在尝试用PHP电子表格库读取CSV文件 我成功地获取了数据,但是数组中的逗号分隔符弄错了 $reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv(); $spreadsheet = $reader->load('File.csv'); $sheetData = $spreadsheet->getActiveSheet()->toArray(); echo '<pre>'; print_r($sheetData

我正在尝试用PHP电子表格库读取CSV文件

我成功地获取了数据,但是数组中的逗号分隔符弄错了

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();

$spreadsheet = $reader->load('File.csv');
$sheetData   = $spreadsheet->getActiveSheet()->toArray();

echo '<pre>';
print_r($sheetData);
而不是:

ini_set('auto_detect_line_endings',TRUE)

提前谢谢。

您是否尝试过强制行尾保持一致?我以前遇到过这种情况,在解析CSV之前必须添加一个PHP ini设置:

<?php

use Exception;
use InvalidArgumentException;
use SplFileObject;
use NoRewindIterator;

class LargeFile {

const ERROR_UNABLE = 'ERROR: Unable to open file';
const ERROR_TYPE = 'ERROR: Type must be "ByLength", "ByLine", or "Csv"';

protected $file;
protected $allowed_types = [ 'ByLine', 'ByLength', 'Csv' ];

/**
 * LargeFile constructor.
 *
 * @param $filename
 * @param string $mode
 *
 * @throws Exception
 *
 * Populates $file with new SPL File object instance.
 */
public function __construct($filename, $mode = 'r') {
    if (!file_exists($filename)) {
        $message = __METHOD__ . ' : ' . self::ERROR_UNABLE . PHP_EOL;
        $message .= strip_tags($filename) . PHP_EOL;
        throw new Exception($message);
    }
    $this->file = new SplFileObject($filename, $mode);
}

/**
 * @return \Generator|int
 *
 * References SplFileObject method to read the file one line
 * at a time with fgets.
 *
 * Suitable for smaller text files like Csvs and / or
 * include line feeds.
 */
protected function fileIteratorByLine() {
    $count = 0;

    while (!$this->file->eof()) {
        yield $this->file->fgets();
        $count++;
    }
    return $count;
}

/**
 * @param $numBytes
 *
 * @return \Generator|int
 *
 * References SplFileObject method to read the file one line
 * at a time with freads.
 *
 * Suitable for larger binary files.
 */
protected function fileIteratorByLength($numBytes) {
    $count = 0;

    while (!$this->file->eof()) {
        yield $this->file->fread($numBytes);
        $count++;
    }
    return $count;
}

protected function fileIteratorCsv() {
    $count = 0;

    while (!$this->file->eof()) {
        yield $this->file->fgetcsv();
        $count++;
    }
    return $count;
}

/**
 * @param string $type
 * @param null $numBytes
 *
 * @return NoRewindIterator
 */
public function getIterator($type = 'ByLine', $numBytes = null) {
    if (!in_array($type, $this->allowed_types)) {
        $message = __METHOD__ . ' : ' . self::ERROR_TYPE . PHP_EOL;
        throw new InvalidArgumentException($message);
    }
    $iterator = 'fileIterator' . $type;
    return new NoRewindIterator($this->$iterator($numBytes));
}
}
把它放在$reader前面

在评论中通过请求进行编辑

这里是我用于CSV的类,假设您至少有PHP5.5:

$largeFile = new LargeFile($file);
// tell it use the CSV iterator
$iterator  = $largeFile->getIterator('Csv');

// start iterator and pull out header row as $rawHeaders
$rawHeaders = $iterator->current();

$headerIterator = new \ArrayIterator;
foreach ($rawHeaders as $header) {
    $headerIterator->append(strtolower("`$header`"));
}

$headers = $headerIterator->getArrayCopy();

// move pointer to the data rows
$iterator->next();

// loop through each row
foreach( $iterator as $row ) {
  // do stuff with each row
  print_r($row);
}

嗨,JDev,我试过了,也遇到了同样的问题,我认为这与文件或库有关,因为如果我使用fgetcsv(),它会正确地分割到数组中。好吧,听起来你是对的,我不熟悉这个特定的库,它可能有特定的分隔符设置。我有一个用于所有CSV解析的库,如果您对JDev感兴趣的话,它更适合于较大的文件。当然,为什么不呢!谢谢,我以前使用过PHPExcel,并且可以很好地处理同一个文件,今天我转到了他们推荐的新库(电子表格),因为PHPExcel不推荐使用,所以我遇到了这个问题。我更新了我的原始答案。代码是我从一组迭代器/生成器类中提取的一个类,我将这些类用于各种事情。我得到第一行(CSV文件头),在$iterator->next()之后,它只循环遍历数据。getArrayCopy()与->toArray方法基本相同。当然可以。我决定用PHP内置的SPL/Generator类编写我自己的更基于OOP的类。将CSV结果作为迭代器输入可以节省大量内存,而不是每次都转储一个巨大的数组。因此“LargeFile”类名为:请提供csv文件
<?php

use Exception;
use InvalidArgumentException;
use SplFileObject;
use NoRewindIterator;

class LargeFile {

const ERROR_UNABLE = 'ERROR: Unable to open file';
const ERROR_TYPE = 'ERROR: Type must be "ByLength", "ByLine", or "Csv"';

protected $file;
protected $allowed_types = [ 'ByLine', 'ByLength', 'Csv' ];

/**
 * LargeFile constructor.
 *
 * @param $filename
 * @param string $mode
 *
 * @throws Exception
 *
 * Populates $file with new SPL File object instance.
 */
public function __construct($filename, $mode = 'r') {
    if (!file_exists($filename)) {
        $message = __METHOD__ . ' : ' . self::ERROR_UNABLE . PHP_EOL;
        $message .= strip_tags($filename) . PHP_EOL;
        throw new Exception($message);
    }
    $this->file = new SplFileObject($filename, $mode);
}

/**
 * @return \Generator|int
 *
 * References SplFileObject method to read the file one line
 * at a time with fgets.
 *
 * Suitable for smaller text files like Csvs and / or
 * include line feeds.
 */
protected function fileIteratorByLine() {
    $count = 0;

    while (!$this->file->eof()) {
        yield $this->file->fgets();
        $count++;
    }
    return $count;
}

/**
 * @param $numBytes
 *
 * @return \Generator|int
 *
 * References SplFileObject method to read the file one line
 * at a time with freads.
 *
 * Suitable for larger binary files.
 */
protected function fileIteratorByLength($numBytes) {
    $count = 0;

    while (!$this->file->eof()) {
        yield $this->file->fread($numBytes);
        $count++;
    }
    return $count;
}

protected function fileIteratorCsv() {
    $count = 0;

    while (!$this->file->eof()) {
        yield $this->file->fgetcsv();
        $count++;
    }
    return $count;
}

/**
 * @param string $type
 * @param null $numBytes
 *
 * @return NoRewindIterator
 */
public function getIterator($type = 'ByLine', $numBytes = null) {
    if (!in_array($type, $this->allowed_types)) {
        $message = __METHOD__ . ' : ' . self::ERROR_TYPE . PHP_EOL;
        throw new InvalidArgumentException($message);
    }
    $iterator = 'fileIterator' . $type;
    return new NoRewindIterator($this->$iterator($numBytes));
}
}
$largeFile = new LargeFile($file);
// tell it use the CSV iterator
$iterator  = $largeFile->getIterator('Csv');

// start iterator and pull out header row as $rawHeaders
$rawHeaders = $iterator->current();

$headerIterator = new \ArrayIterator;
foreach ($rawHeaders as $header) {
    $headerIterator->append(strtolower("`$header`"));
}

$headers = $headerIterator->getArrayCopy();

// move pointer to the data rows
$iterator->next();

// loop through each row
foreach( $iterator as $row ) {
  // do stuff with each row
  print_r($row);
}