Таблица PHP для чтения CSV

Я пытаюсь прочитать файл 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
        )
)

Заранее спасибо.

предоставьте файл csv

Geomorillo 01.05.2018 05:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
1
4 930
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы пытались сделать так, чтобы окончания строк были последовательными? Я сталкивался с этим раньше, и мне пришлось добавить настройку 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 (), он правильно разбивается на массив.

user3216926 01.05.2018 05:18

Хорошо, похоже, вы правы, я не знаком с этой конкретной библиотекой, у нее могут быть определенные настройки разделителя. У меня есть библиотека, которую я использую для всего анализа CSV, которая лучше подходит для больших файлов, если вам интересно

JDev518 01.05.2018 05:27

Конечно, JDev, почему бы и нет! спасибо, я раньше использовал PHPExcel и отлично работал с тем же файлом, сегодня я перешел на новую библиотеку, которую они рекомендуют (Таблица), поскольку PHPExcel устарел, тогда я столкнулся с этой проблемой.

user3216926 01.05.2018 05:37

Я обновил свой исходный ответ. Код - это класс, который я извлек из набора классов Iterator / Generator, которые я использую для различных целей. Я получаю первую строку (заголовки файлов CSV), а после $ iterator-> next () она перебирает только данные. getArrayCopy () по сути то же самое, что и метод -> toArray.

JDev518 01.05.2018 06:11

Конечно. Я решил написать свой собственный, более основанный на ООП, со встроенными в PHP классами SPL / Generator. Получение результатов CSV в качестве итератора экономит много памяти вместо того, чтобы каждый раз выгружать огромный массив. Отсюда и название класса "LargeFile": D

JDev518 01.05.2018 18:33

Да, я видел, очень приятно использовать итераторы, отличная работа, JDev! Идеально подходит для меня.

user3216926 03.05.2018 04:39

Другие вопросы по теме