Версии
Версия 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();
}
Можете ли вы опубликовать полную трассировку стека? Теперь трудно понять, какой импорт вызывает это.
/Пользователи/администратор/Сайты/блог/поставщик/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 существует несколько листов.
У меня была такая же проблема. После некоторого разочарования мое подозрение подтвердилось. Это было вызвано расколом в электронной таблице. После «неразбиения» первой строки это сработало.
Согласно трассировке стека, в вашем файле есть только 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», эта проблема возникает.
Самый полезный комментарий
у меня такая же ошибка!
но после удаления листа 2, 3 решено !!
для этой ситуации вам нужно определить индекс листа с помощью