Laravel-excel: Tamaño de memoria permitido de 134217728 bytes agotado

Creado en 19 jul. 2018  ·  22Comentarios  ·  Fuente: Maatwebsite/Laravel-Excel

Prerrequisitos

  • [X] Capaz de reproducir el comportamiento fuera de su código, el problema está aislado en Laravel Excel.
  • [X] Verificó que su problema aún no se haya presentado.
  • [X] Se verificó si no se envió ningún RP que solucione este problema.

Versiones

  • Versión de PHP: 7.1.13
  • Versión de Laravel: 5.6
  • Versión del paquete: ^ 3.0

Descripción

Obtengo Allowed memory size of 134217728 bytes exhausted cuando intento exportar con la opción FromQuery

Pasos para reproducir

Comportamiento esperado:

Quiero solucionar mi problema :)

Comportamiento real:

información adicional

namespace App\Exports;

use App\OldTransaction;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Http\Request;
use jDate;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;

class OldDepositExport implements FromQuery, ShouldQueue, WithMapping, WithHeadings, ShouldAutoSize
{
    use Exportable;

    /**
     * DepositExport constructor.
     * <strong i="27">@param</strong> Request $request
     */
    public function __construct(Request $request)
    {
    }

    public function headings(): array
    {
        return [
            'ID',
        ];
    }


    public function map($transaction): array
    {
        return [
            $transaction->id,
        ];
    }

    public function query()
    {
        return User::query()
            ->where('status', '=', 1)
            ->select(['id']);
    }
}

Vea esta imagen https://i.imgur.com/yMgUqXP.jpg

Comentario más útil

¿De quién esperas una respuesta?

Nuestro software es gratuito y de código abierto, lo que significa que el uso de nuestro software es opcional. No asumimos ninguna responsabilidad y no tenemos la obligación de dar soporte. Brindaremos apoyo con el mejor esfuerzo posible.

Si utiliza el software comercialmente y necesita un soporte detallado o lo necesita con urgencia, podemos ofrecerlo de forma comercial. Póngase en contacto con [email protected] o por teléfono +31 (0) 10744 9312.

Todos 22 comentarios

¿Alguien puede ayudarme?

4 dias. sin respuesta :-(

¿De quién esperas una respuesta?

Nuestro software es gratuito y de código abierto, lo que significa que el uso de nuestro software es opcional. No asumimos ninguna responsabilidad y no tenemos la obligación de dar soporte. Brindaremos apoyo con el mejor esfuerzo posible.

Si utiliza el software comercialmente y necesita un soporte detallado o lo necesita con urgencia, podemos ofrecerlo de forma comercial. Póngase en contacto con [email protected] o por teléfono +31 (0) 10744 9312.

De acuerdo, por favor, no cierre este problema. tal vez alguien pueda arreglar esto.

Gracias

Creo que es un problema de memoria php, tal vez son demasiados datos y se desborda la memoria ... No tiene relación con la librería.

@jlcarpioe Tengo casi 200k filas. El problema ocurre al agregar filas a la hoja

¿Intentaste maximizar memory_limit en php.ini?

@ bagana89 Esa no es una buena solución

No puedo reproducir tu problema. Puedo exportar una tabla de usuarios de 300K filas usando el código que compartiste. Tenga en cuenta que el uso de la memoria aumentará en cada trabajo, ya que PhpSpreadsheet tiene que abrir el libro de trabajo que crece cada vez más. No hay nada de malo en asignar más memoria para este proceso. Parece que no tienes mucha memoria asignada, por eso se desborda tan rápido.

Es mejor eliminar ShouldAutoSize ya que volverá a calcular las dimensiones de la columna de los libros de trabajo en cada trabajo. Eso requiere mucha más memoria que sin usarla.

Tengo 1 GB de RAM asignado y todavía tengo el mismo resultado que saeedvaziry.
Recién migrado de v2.1 a v3.1. Estaba teniendo el mismo problema con v2.1 lo que me motivó a migrar, pero no resolvió el problema. Excel :: create en v2.1 fue mucho más fácil de diseñar la salida.

Parece que la fragmentación no funciona bien al exportar (usando FromQuery) (usa una gran cantidad de memoria, hasta 3 Gigs para mí para aproximadamente 200k registros). Pero la importación funciona bien usando fragmentación. (la memoria nunca supera los 50 MB)

Solo tengo 15 mil registros y me dio el mismo error. ¿Qué puedo hacer?

Este es el error:

[2019-11-24 22:39:59] local.ERROR: Se agotó el tamaño de memoria permitido de 134217728 bytes (se intentó asignar 18874368 bytes) {"excepción": "[objeto] (Symfony \ Component \ Debug \ Exception \ FatalErrorException ( código: 1): Se agotó el tamaño de memoria permitido de 134217728 bytes (intentó asignar 18874368 bytes) en C: \ wamp64 \ www \ ..... \ vendor \ phpoffice \ phpspreadsheet \ src \ PhpSpreadsheet \ Collection \ Cells.php: 421 )
[stacktrace]

0 {main}

"}

Deberá aumentar el límite de memoria permitido en su php.ini o configurarlo dinámicamente usando ini_set

Lo hice, tengo 1G pero no funciona

Cuando ejecuta el proceso, ¿cuánta memoria consume el proceso php-cli? Debe exceder 1Gig entonces

El límite de memoria definitivamente no es el problema. Está configurado en 4GB según phpinfo y todavía tengo este problema.

yo tengo el mismo problema

Una 'Solución' sería dividir su archivo en varios, liberar memoria entre ellos y luego fusionar todos los archivos y enviarlos fusionados como respuesta.

Contras.:

  • Más espacio para archivos temporales
  • Más tiempo dedicado (bucles no inteligentes)
  • Se requiere más código (no listo para usar)

Ventajas:

  • Funciona

el mismo problema, el límite de memoria es de 512 MB, filas de 4K

Solución final
Esto es antiguo, pero quienquiera que esté leyendo esto ahora debe saber que
si está importando o exportando ToModel o ToCollection, ese proceso requiere una gran asignación de memoria para convertir
los datos en formas utilizables como colección o matriz.

En ese caso, no implemente ToModel o ToCollect, debe omitir el proceso y realizar la operación manualmente implementando OnEachRow
que le permiten implementar el método onRow que pasará un objeto Row de Excel. También puede implementar WithHeadingRow para estructurarlo como una matriz asociativa.
Use este $ row-> toArray () para obtener sus datos y procesarlos como desee. Esto es rápido y fácil de manipular.

PD: Si aún obtiene el Error de límite de memoria, simplemente agregue una declaración de retorno a la última línea como esta
regreso;

Gracias

Tuve el mismo problema y con las sugerencias de @MoFoLuWaSo reduje mi uso de memoria de + 128Mb a 54Mb.

1) implementar un DTO. Eso redujo más el uso de memoria.
2) ordenar las propiedades del DTO y eliminar withMapping
3) eliminar ShouldAutoSize

En el caso de @saeedvz , debería verse así:

namespace App\DataTransferObjects;

class OldDepositRow
{
    public int $id;
    public string $created_at;
}

y

namespace App\Exports;

use App\DataTransferObjects\OldDepositRow;

class OldDepositExport implements FromCollection, ShouldQueue, WithHeadings
{
    use Exportable;

    public function headings(): array
    {
        return [
            'ID',
        ];
    }

    public function collection()
    {
        $users = User::query()
            ->where('status', '=', 1)
            ->select(['id']);

        return $users->map(
           function ($user) {
                $row = new OldDepositRow();
                $row->transaction_id = $user->transaction->id;

                // cast objects like Carbon or BigDecimal to string
                $row->created_at = $user->transaction->created_at->format('d-m-Y');

                return $row;
            }
        );
    }
}
¿Fue útil esta página
0 / 5 - 0 calificaciones