当我尝试使用FromQuery
选项导出时,我收到了Allowed memory size of 134217728 bytes exhausted
预期行为:
我想解决我的问题:)
实际行为:
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']);
}
}
谁能帮我?
4天。 没有答案 :-(
你期待谁的回答?
我们的软件是免费和开源的,这意味着我们软件的使用是可选的。 我们不承担任何责任,也没有义务支持。 我们将尽最大努力提供支持。
如果您在商业上使用该软件并需要精心支持或迫切需要它,我们可以在商业基础上提供。 请联系[email protected]或通过电话 +31 (0)10 744 9312。
好的,所以请不要关闭这个问题。 也许有人可以解决这个问题。
谢谢
我认为是php内存的问题,可能是数据太多导致内存溢出……和库没有关系。
@jlcarpioe我有将近 20 万行。 将行附加到工作表时出现问题
您是否尝试在 php.ini 中最大化 memory_limit?
@ bagana89这不是一个好的解决方案
我无法重现您的问题。 我可以使用您共享的代码导出 30 万行的用户表。 请注意,每项作业的内存使用量都会增加,因为 PhpSpreadsheet 必须打开每次都变大的工作簿。 为这个进程分配更多的内存并没有错。 似乎您没有分配很多内存,这就是它溢出如此之快的原因。
最好删除ShouldAutoSize
因为这将重新计算每个作业中的工作簿列尺寸。 这比不使用它需要更多的内存。
我分配了 1 GB 的内存,但结果仍然与 saeedvaziry 相同。
刚刚从 v2.1 迁移到 v3.1。 v2.1 也有同样的问题,这促使我迁移,但没有解决问题。 Excel::create 在 v2.1 中也更容易设置输出样式。
似乎在导出(使用 FromQuery)时分块效果不佳(使用大量内存 - 对我来说最多 3 Gigs 大约 200k 记录)。 但是使用分块导入可以正常工作。 (内存不超过 50MB)
我只有 15,000 条记录并给了我同样的错误。 我能做什么?
这是错误:
[2019-11-24 22:39:59] local.ERROR: 允许的内存大小为 134217728 字节已用完(尝试分配 18874368 字节){"exception":"[object] (Symfony\Component\Debug\Exception\FatalErrorException(代码:1):在 C:\wamp64\www\.....\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Collection\Cells.php:421 中允许的内存大小为 134217728 字节(试图分配 18874368 字节) )
[堆栈跟踪]
"}
您需要增加 php.ini 中允许的内存限制或使用 ini_set 动态设置
我有,我有 1G 但它不起作用
运行进程时,php-cli进程消耗了多少内存? 那么它必须超过1Gig
内存限制绝对不是问题。 根据 phpinfo 设置为 4GB,我仍然有这个问题。
我有同样的问题
“解决方案”会将您的文件拆分为多个文件,释放它们之间的内存,然后合并所有文件并将合并的文件作为响应发送。
缺点:
优点:
同样的问题,内存限制为 512 MB,4K 行
最终解决方案
这是旧的,但现在阅读本文的人应该知道
如果您正在导入或导出 ToModel 或 ToCollection,则该过程需要大量内存分配才能转换
将数据转换为可用的形式,如集合或数组。
在这种情况下,不要实现 ToModel 或 ToCollect,您需要绕过流程并通过实现 OnEachRow 手动执行操作
它允许您实现将传入 Excel Row 对象的 onRow 方法。 您可以实现 WithHeadingRow 以将其结构化为关联数组。
使用此 $row->toArray() 获取您的数据并根据需要对其进行处理。 这是快速且易于操作的。
PS:如果仍然出现内存限制错误,只需像这样在最后一行添加一个return语句
返回;
谢谢你
我遇到了同样的问题,根据@MoFoLuWaSo的建议,我将 +128Mb 的内存使用量减少到 54Mb。
1) 实施 DTO。 这减少了最多的内存使用量。
2) 对 DTO 的属性进行排序并删除withMapping
3)删除ShouldAutoSize
在@saeedvz 的情况下,它应该是这样的:
namespace App\DataTransferObjects;
class OldDepositRow
{
public int $id;
public string $created_at;
}
和
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;
}
);
}
}
最有用的评论
你期待谁的回答?
我们的软件是免费和开源的,这意味着我们软件的使用是可选的。 我们不承担任何责任,也没有义务支持。 我们将尽最大努力提供支持。
如果您在商业上使用该软件并需要精心支持或迫切需要它,我们可以在商业基础上提供。 请联系[email protected]或通过电话 +31 (0)10 744 9312。