Я пытаюсь прочитать файл CSV с помощью библиотеки электронных таблиц PHP.
Я успешно получил данные, но они нарушают запятую, разделенную в массиве.
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$spreadsheet = $reader->load('File.csv');
$sheetData = $spreadsheet->getActiveSheet()->toArray();
echo '<pre>';
print_r($sheetData);
Когда я вижу результат, он выглядит так:
Array
(
[0] => Array
(
[0] => Id,Record,Book,Description,Date,Action
[1] =>
[2] =>
)
[1] => Array
(
[0] => 1306,5466,84,Item,04-05-2018 06
[1] => 26
[2] => 28,Auto Show
)
)
Вместо:
Array
(
[0] => Array
(
[0] => Id
[1] => Record
[2] => Book
[3] => Description
[4] => Date
[5] => Action
)
[1] => Array
(
[0] => 1306
[1] => 5466
[2] => 84
[3] => Item
[4] => 04-05-2018 06:26:28
[5] => Auto Show
)
)
Заранее спасибо.






Вы пытались сделать так, чтобы окончания строк были последовательными? Я сталкивался с этим раньше, и мне пришлось добавить настройку PHP ini перед синтаксическим анализом CSV:
ini_set('auto_detect_line_endings',TRUE)
Поместите это перед $ reader
Edit via request in comments
Вот класс, который я использую для CSV, если у вас как минимум PHP 5.5:
<?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);
}
Привет, JDev, я попробовал и получил ту же проблему, я думаю, что-то связано с файлом или библиотекой, поскольку, если я использую fgetcsv (), он правильно разбивается на массив.
Хорошо, похоже, вы правы, я не знаком с этой конкретной библиотекой, у нее могут быть определенные настройки разделителя. У меня есть библиотека, которую я использую для всего анализа CSV, которая лучше подходит для больших файлов, если вам интересно
Конечно, JDev, почему бы и нет! спасибо, я раньше использовал PHPExcel и отлично работал с тем же файлом, сегодня я перешел на новую библиотеку, которую они рекомендуют (Таблица), поскольку PHPExcel устарел, тогда я столкнулся с этой проблемой.
Я обновил свой исходный ответ. Код - это класс, который я извлек из набора классов Iterator / Generator, которые я использую для различных целей. Я получаю первую строку (заголовки файлов CSV), а после $ iterator-> next () она перебирает только данные. getArrayCopy () по сути то же самое, что и метод -> toArray.
Конечно. Я решил написать свой собственный, более основанный на ООП, со встроенными в PHP классами SPL / Generator. Получение результатов CSV в качестве итератора экономит много памяти вместо того, чтобы каждый раз выгружать огромный массив. Отсюда и название класса "LargeFile": D
Да, я видел, очень приятно использовать итераторы, отличная работа, JDev! Идеально подходит для меня.
предоставьте файл csv