Laravel-excel: Стартовый ряд (2) находится за самым верхним рядом (1)

Созданный на 12 нояб. 2018  ·  25Комментарии  ·  Источник: Maatwebsite/Laravel-Excel

Версии

Версия PHP: 7.2
Версия Laravel: 5.7
Версия пакета: 3.1

Описание

Я получаю сообщение об ошибке: «Начальная строка (2) выходит за пределы самой высокой строки (1)» из /Users/administrator/Sites/blog/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowIterator.php

Электронная таблица имеет заголовки в первой строке и представляет собой один лист. Вторая строка пуста, но разве это не должно быть нормально? Я не уверен, как объяснить этот сценарий. Любая помощь приветствуется. Спасибо.

Приложение\Импорт\PoliciesImport.php

<?php

namespace App\Imports;

use App\Policy;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Auth;


class PoliciesImport implements ToModel, WithValidation, WithHeadingRow, WithMultipleSheets
{

    use Importable;

    /**
    * <strong i="14">@param</strong> array $row
    *
    * <strong i="15">@return</strong> \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new Policy([
          'user_id'     => Auth::user()->id,
          'policy_name' => $row['name'],
          'phone'       => $row['phone'],
          'street'      => $row['address'],
          'city'        => $row['city'],
          'state'       => $row['state'],
          'postal_code' => $row['postal_code'],
        ]);
    }

    public function sheets(): array
    {
        return [
            // Select by sheet index
            0 => new PoliciesImport(),
        ];
    }

    public function rules(): array
    {
        return [
            'policy_name' => 'required|string',
             '*.policy_name' => 'required|string',
        ];
    }

}

Политикконтроллер.php

public function import(Request $request)
  {
    if ($request->hasFile('file')) {

      // validate incoming request
      $this->validate($request, [
        'file' => 'required|file|mimes:xls,xlsx,csv|max:10240', //max 10Mb
      ]);

          if ($request->file('file')->isValid()) {

              $file = $request->file('file');
              $path = $file->store('uploads/policy');
              $fileHeaders = current((new HeadingRowImport)->toArray($path)[0]);
              $validHeaders = [
                'name','phone','address','state','city','postal_code'
              ];
              sort($fileHeaders);
              sort($validHeaders);

              // Check the File Headers
              if ($fileHeaders == $validHeaders) {
                  // Import the saved excel file
                  (new PoliciesImport)->import($path);
              }

              Storage::delete($path);
          }
      }

      return back();

  }

Самый полезный комментарий

у меня такая же ошибка!

но после удаления листа 2, 3 решено !!

для этой ситуации вам нужно определить индекс листа с помощью

    public function sheets(): array
    {
        return [
            // Select by sheet index
            0 => new pricelist_items(),
        ];
    }

Все 25 Комментарий

Можете ли вы опубликовать полную трассировку стека? Теперь трудно понять, какой импорт вызывает это.

screen shot 2018-11-12 at 8 02 38 am 2

/Пользователи/администратор/Сайты/блог/поставщик/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/RowIterator.php

     *
     * <strong i="8">@param</strong> int $startRow The row number at which to start iterating
     *
     * <strong i="9">@throws</strong> PhpSpreadsheetException
     *
     * <strong i="10">@return</strong> RowIterator
     */
    public function resetStart($startRow = 1)
    {
        if ($startRow > $this->subject->getHighestRow()) {
            throw new PhpSpreadsheetException("Start row ({$startRow}) is beyond highest row ({$this->subject->getHighestRow()})");
        }

        $this->startRow = $startRow;
        if ($this->endRow < $this->startRow) {
            $this->endRow = $this->startRow;
        }
        $this->seek($startRow);

        return $this;
    }

    /**
     * (Re)Set the end row.
     *

Извини за это. Это помогает?

Спасибо!

Здесь такая же проблема!

Согласно трассировке стека, в вашем файле есть только 1 строка (строка заголовка), при попытке импортировать каждую строку PhpSpreadsheet жалуется, что нет 2-й строки (и нет строк дальше 2-й строки)

@patrickbrouwers В моем случае определенно есть строки и значения после строки 1. Кажется, мне нужно убедиться, что я реализовал ОБЕ проблемы WithChunkReading и WithCustomChunkSize , чтобы решить проблему. Сказав это, я также создал новый файл Excel и скопировал значения из старого файла.

Похоже, с вашим файлом что-то не так, если он работает после копирования значений в новый файл.
В случае, если это CSV, возможно, не используется правильный разделитель?

Ага. Вполне возможно. Я вернусь сюда, если он снова появится, так как скоро я буду обрабатывать несколько разных файлов. Все они в формате XLSX.

Конечно, дайте мне знать!

@patrickbrouwers да, это правда. В этом случае я пытаюсь предотвратить ошибку сервера, и я изо всех сил пытаюсь ее поймать и остановить выполнение метода модели импорта.

Я на правильном пути, используя RegistersEventListeners в App\Imports\PoliciesImport.php? Я понял, как получить самую высокую строку, но не могу понять, как передать это значение или куда идти дальше.

    public static function beforeImport(BeforeImport $event)
    {
        $worksheet = $event->reader->getActiveSheet();
        $highestRow = $worksheet->getHighestRow(); // e.g. 10

        dd($highestRow);
    }

@abbylovesdon лучше всего создать исключение в beforeImport и попытаться перехватить его в контроллере. Вы можете передать самую высокую строку через исключение.

@patrickbrouwers Большое спасибо за помощь! Я новичок в PHP/Laravel/This Package, поэтому, если кто-то еще на моем месте, вот что я сделал:

В моем классе импорта: App\Imports\PoliciesImport.php

<?php

namespace App\Imports;

use App\Policy;
use Auth;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Validators\Failure;
use Maatwebsite\Excel\Validators\ValidationException;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Events\BeforeImport;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;

class PoliciesImport implements ToModel, WithValidation, WithHeadingRow, WithMultipleSheets, WithEvents
{
    use Importable, RegistersEventListeners;

    public static function beforeImport(BeforeImport $event)
    {
        $worksheet = $event->reader->getActiveSheet();
        $highestRow = $worksheet->getHighestRow(); // e.g. 10

        if ($highestRow < 2) {
            $error = \Illuminate\Validation\ValidationException::withMessages([]);
            $failure = new Failure(1, 'rows', [0 => 'Now enough rows!']);
            $failures = [0 => $failure];
            throw new ValidationException($error, $failures);
        }
    }

    /**
    * <strong i="8">@param</strong> array $row
    *
    * <strong i="9">@return</strong> \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new Policy([
          'user_id'     => Auth::user()->id,
          'policy_name' => $row['name'],
          'phone'       => $row['phone'],
          'street'      => $row['address'],
          'city'        => $row['city'],
          'state'       => $row['state'],
          'postal_code' => $row['postal_code'],
        ]);
    }

    public function sheets(): array
    {
        return [
            // Select by sheet index
            0 => new PoliciesImport(),
        ];
    }

    public function rules(): array
    {
        return [
            'name' => 'required|string',
             '*.name' => 'required|string',
        ];
    }

}

Теперь в моем контроллере я могу использовать:

                  try {
                        (new PoliciesImport)->import($path);
                  } catch (\Exception $e) {
                        $failures = $e->failures();
                        dd($failures[0]);
                  }

Здесь такая же проблема! :((

Здесь такая же проблема! :((

Если вы не можете решить проблему, используя приведенные выше предложения и примеры, я прошу вас открыть для нее новую проблему, используя шаблон проблемы. Спасибо!

у меня такая же ошибка!

но после удаления листа 2, 3 решено !!

для этой ситуации вам нужно определить индекс листа с помощью

    public function sheets(): array
    {
        return [
            // Select by sheet index
            0 => new pricelist_items(),
        ];
    }

Тот же случай произошел со мной, но я понял, что это связано с тем, что в файле Excel существует несколько листов.

У меня была такая же проблема. После некоторого разочарования мое подозрение подтвердилось. Это было вызвано расколом в электронной таблице. После «неразбиения» первой строки это сработало.
image

Согласно трассировке стека, в вашем файле есть только 1 строка (строка заголовка), при попытке импортировать каждую строку PhpSpreadsheet жалуется, что нет 2-й строки (и нет строк дальше 2-й строки)

Как справиться, если в Excel есть только строка заголовка. я хочу показать правильное сообщение об ошибке клиенту

Привет, я знаю, что эта тема уже закрыта, но у меня такая же проблема, и ничего в этой теме не помогает с моей проблемой.

Я загружаю 10 тысяч строк одновременно и получаю эту ошибку Start row (2) is beyond highest row (1) . Но когда я разбиваю его на 5k, это работает как по волшебству.

В чем здесь проблема?
Заранее спасибо!

Привет, я знаю, что эта тема уже закрыта, но у меня такая же проблема, и ничего в этой теме не помогает с моей проблемой.

Я загружаю 10 тысяч строк одновременно и получаю эту ошибку Start row (2) is beyond highest row (1) . Но когда я разбиваю его на 5k, это работает как по волшебству.

В чем здесь проблема?
Заранее спасибо!

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

Только что это случилось со мной. Происходит, когда размер файла превышает директиву PHP «upload_max_filesize». Я использовал фрагментацию 500 для файла размером 5 МБ с 40 тыс. строк, в то время как мой максимальный «upload_max_filesize» на AWS AMI составлял 2 МБ. Могу ли я предложить авторам реализовать проверку максимального размера загрузки и вывести эту ошибку вместо того, чтобы сбивать с толку Start row (2) is beyond highest row (1) . Когда я увеличил предел «upload_max_filesize», ошибка исчезла, и загрузка файла прошла успешно.

Скорее всего, существует больше причин, по которым phpspreadsheet может вызывать эту ошибку. Вы всегда можете попытаться PR там.

@GlennM спасибо за ответ!
Я сделал обходной путь для этого, и на данный момент он уже соответствует потребностям моего проекта. Рассмотрю ваше предложение, если у меня возникнет эта проблема в будущем.

@patrickbrouwers В моем случае определенно есть строки и значения после строки 1. Кажется, мне нужно убедиться, что я реализовал ОБЕ проблемы WithChunkReading и WithCustomChunkSize , чтобы решить проблему. Сказав это, я также создал новый файл Excel и скопировал значения из старого файла.

это помогает мне. все еще есть та же проблема

удалить рабочие листы пусты

удалить рабочие листы пусты

Это был мой случай, если в вашем файле есть пустые рабочие листы, и вы используете «WithHeadingRow», эта проблема возникает.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги