【问题标题】:How to get a better export for a Laravel project using collections and the map function如何使用集合和地图功能更好地导出 Laravel 项目
【发布时间】:2021-07-07 12:32:11
【问题描述】:

在我的项目中,我使用 Maatwebsite/Excel 功能将排序的集合导出到 Excel。目前运行良好。

结果是通过不同任务在汽车上工作的汽车集合。一辆车可以有 1+ 个任务/次。

<?php

namespace App\Exports;

use App\Time;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;

use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;

class Times2Export implements FromCollection, WithMapping, WithHeadings, ShouldAutoSize, WithColumnFormatting
{

    public function collection()
    {
        return Time::all()->sortBy("car_id");
    }

   public function headings(): array
    {
        return [
            'Dossiernummer',            
            'Auto',
            'Taak',
            'Werknemer',
            'Starttijd',
            'Stoptijd',
            'Duur',
        ];
    }

    /**
    * @var Time $time
    */
    public function map($time): array
    {
       $dt = Carbon::parse($time->stop)->diffInSeconds(Carbon::parse($time->start));
        $duur = (is_null($time->stop)) ? 0 : $dt;

        return [
            $time->car->dossiernr,
            $time->car->brand . " " . $time->car->type . " (" . $time->car->license . ")",
            $time->task->name,
            $time->employee->name,
            $time->start,
            $time->stop,
            '=' . $duur . '/86400',
        ];

        return $time;
    }


    public function columnFormats(): array
    {
        return [
            'G' => NumberFormat::FORMAT_DATE_TIME4,
        ];
    }

}

我的愿望是,在每辆车之后,我希望有一个空行,其中包含在汽车上工作的 COUNT 时间,因此计算每辆车 G 列中的时间(基于每辆车的 x 行,其中 x 不是提前知道)。

我已经测试了很多,但我可能误解了地图功能(我还是初学者)。

有人告诉我应该使用 GroupBy 遍历集合 - 对吗?我想就像this site 中描述的那样。

我不知道从哪里开始创建我的收藏。接下来我可以尝试什么?

更新

非常感谢您的努力,尤其是优化。

让我尝试展示我想要实现的目标。

目前我的输出是这样的(出于用户数据的原因,我已经模糊了一些项目):

这就是我想要的方式:

更新 15/04

【问题讨论】:

    标签: excel laravel dictionary collections


    【解决方案1】:

    我从来没有使用过那个包,但是根据文档,你应该有这样的类:

    namespace App\Exports;
    
    use App\Time;
    use Carbon\Carbon;
    use Maatwebsite\Excel\Concerns\FromCollection;
    use Maatwebsite\Excel\Concerns\ShouldAutoSize;
    use Maatwebsite\Excel\Concerns\WithColumnFormatting;
    use Maatwebsite\Excel\Concerns\WithHeadings;
    use Maatwebsite\Excel\Concerns\WithMapping;
    use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
    
    class Times2Export implements FromCollection, WithMapping, WithHeadings, ShouldAutoSize, WithColumnFormatting
    {
        public function collection()
        {
            return Time::orderBy('car_id')->get();
        }
    
        public function headings(): array
        {
            return [
                'Dossiernummer',            
                'Auto',
                'Taak',
                'Werknemer',
                'Starttijd',
                'Stoptijd',
                'Duur',
            ];
        }
    
        public function map(Time $time): array
        {
            $duur = is_null($time->stop)
                ? 0
                : Carbon::parse($time->stop)->diffInSeconds(Carbon::parse($time->start));
    
            return [
                [
                    $time->car->dossiernr,
                    $time->car->brand . " " . $time->car->type . " (" . $time->car->license .     ")",
                    $time->task->name,
                    $time->employee->name,
                    $time->start,
                    $time->stop,
                    '=' . $duur . '/86400',
                ],
                [
                    $time
                ],
            ];
        }
    
        public function columnFormats(): array
        {
            return [
                'G' => NumberFormat::FORMAT_DATE_TIME4,
            ];
        }
    }
    
    • 看到我改变了collection方法。如果您执行Time::all()-&gt;sortBy('car_id'),它将从 0 向上排序,但首先会从数据库中获取项目,然后对其进行排序。如果我们执行Time::orderBy('car_id')-&gt;get(),我们将从数据库中获取按car_id 升序排列的数据,然后将其作为collection 提供。这需要更少的时间和内存,所以总是让数据库来做这些事情。
    • 那么,如果您正在使用 is_null($time-&gt;stop) ? 0 : XXXXXX,请不要计算依赖于 $time-&gt;stopXXXXXX,因为这可能会导致问题,或者更糟的是,浪费时间计算您不会使用的东西...
    • 最后,正如documentation 所说,如果要返回多于 1 行,则必须返回一个数组数组,因此每个数组(来自主数组)都是一行。

    我想我仍然没有回答你的问题,我不能 100% 确定你是否想展示一辆车然后一次又一次地展示另一辆车,或者如果你想做一些不同的事情(所以请添加一个示例不清楚)。

    【讨论】:

    • 感谢 Matias 的努力和优化。我已通过 Answer 添加信息。
    • 那我问你,你怎么知道什么时候显示时间?这背后的逻辑是什么?显示时间后你怎么知道有多少辆车?
    • 嗨,马蒂亚斯,这是每辆车和车牌的。因此,在示例图像中,您会看到三行是同一辆车。然后一行另一辆车。在现实生活中,这可能是 20 辆车偏离路线。 GroupBy "car_id" 是您知道总行数和总计数的组。
    • 我正在阅读文档,但看起来它没有遵循我的地图功能。您是否在使用我的地图功能(对于您向我们展示当前行为的图像?)我需要您向我展示我的功能实际返回的内容,因为我想我知道如何做到这一点。
    • Matias,我取出了 [ $time ] 部分,因为它返回了每一行的完整集合。我在更新版本中的第一张图片现在是如何返回的。
    猜你喜欢
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    相关资源
    最近更新 更多