如何在Laravel中将Eloquent导出到Excel时包含列标题?

26

我想让用户下载包含产品信息的Excel文件,使用Laravel Excel。我的当前Web路由如下:

Route::get('/excel/release', 'ExcelController@create')->name('Create Excel');

我的当前导出文件看起来像这样:

class ProductExport implements FromQuery
{
    use Exportable;

    public function __construct(int $id)
    {
        $this->id = $id;
    }

    public function query()
    {
        return ProductList::query()->where('id', $this->id);
    }
}

我的当前控制器长这样:

public function create(Request $request) {

    # Only alowed tables
    $alias = [
        'product_list' => ProductExport::class
    ];

    # Ensure request has properties
    if(!$request->has('alias') || !$request->has('id'))
        return Redirect::back()->withErrors(['Please fill in the required fields.'])->withInput();

    # Ensure they can use this
    if(!in_array($request->alias, array_keys($alias)))
        return Redirect::back()->withErrors(['Alias ' . $request->alias . ' is not supported'])->withInput();

    # Download
    return (new ProductExport((int) $request->id))->download('iezon_solutions_' . $request->alias . '_' . $request->id . '.xlsx');
}

当我转到https://example.com/excel/release?alias=product_list&id=1时,它能够正确执行并返回一个Excel文件。但是,行没有列标题。数据的输出如下:

1   150 1   3       2019-01-16 16:37:25 2019-01-16 16:37:25     10

然而,这应该包含列标题,如ID、成本等...我如何在输出中包含列标题?

7个回答

49
根据文档,您可以将您的类更改为使用WithHeadings接口,然后定义headings函数返回一组列标题数组。
<?php
namespace App;

use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;

class ProductExport implements FromQuery, WithHeadings
{
    use Exportable;

    public function __construct(int $id)
    {
        $this->id = $id;
    }

    public function query()
    {
        return ProductList::query()->where('id', $this->id);
    }

    public function headings(): array
    {
        return ["your", "headings", "here"];
    }
}

这适用于所有导出类型(FromQueryFromCollection等)。


谢谢!我能否使用Eloquent动态获取数据库中的列?我会尽快接受! - Jaquarh
2
如果您要导出表的所有列:https://dev59.com/CFoU5IYBdhLWcg3wvIup#37157879 - miken32
我该如何在控制器中调用headings方法? - Luis Alfredo Serrano Díaz
@miken32 有没有办法从“query”函数中传递数组到标题,或者至少在那里更新它并使其在标题中可用。实际上,如果该列中有数据,我只需要添加标题。那么,有没有解决方法? - Saroj Shrestha
这是一个函数。你可以随心所欲地使用它,@SarojShrestha。看一下类的代码,很可能数据是一个你可以获取的属性。 - miken32
使用 Exportable; 似乎是不必要的。 - Farhan Ibn Wahid

22
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use DB;
class LocationTypeExport implements FromCollection,WithHeadings
{
    public function collection()
    {
        $type = DB::table('location_type')->select('id','name')->get();
        return $type ;
    }
     public function headings(): array
    {
        return [
            'id',
            'name',
        ];
    }
}

1
对我来说,它只适用于:array,可能是因为版本较新。 - rafael.js

8
你可以结合array_keys动态获取列头信息:
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;

class ProductExport implements FromQuery, WithHeadings
{
    use Exportable;

    public function __construct(int $id)
    {
        $this->id = $id;
    }

    public function query()
    {
        return ProductList::query()->where('id', $this->id);
    }

    public function headings(): array
    {
        return array_keys($this->query()->first()->toArray());
    }
}

如果您正在与集合一起使用它,可以按照以下方式操作:
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;

class ProductExport implements FromCollection, WithHeadings
{
    /**
    * @return \Illuminate\Support\Collection
    */
    public function collection()
    {
        // for selecting specific fields
        //return ProductList::select('id', 'product_name', 'product_price')->get();
        // for selecting all fields
        return ProductList::all();
    }

    public function headings(): array
    {
        return $this->collection()->first()->keys()->toArray();
    }
}

2
在导出用户表时,我需要使用以下代码:array_keys($this->collection()->first()->toArray()); 即使它是一个模型集合,也要使用 FromCollection - Ric

1
<?php
    
    namespace App\Exports;
    
    use App\Models\StudentRegister;
    use Maatwebsite\Excel\Concerns\FromCollection;
    use Maatwebsite\Excel\Concerns\WithHeadings;
    
    class StudentExport implements FromCollection, WithHeadings
    {
        /**
        * @return \Illuminate\Support\Collection
        */
        public function collection()
        {
           
            return StudentRegister::select('name','fname','mname','gender','language','address')->get();
        }
    
        public function headings(): array
        {
            //Put Here Header Name That you want in your excel sheet 
            return [
                'Name',
                'Father Name',
                'Mother Name',
                'Gender',
                'Opted Language',
                'Corresponding Address'
            ];
        }
    }

3
尽管这段代码可能解决问题,但是加入关于如何以及为什么解决问题的解释会有助于提高你的文章质量,并可能导致更多点赞。请记住,你的答案是为未来读者回答问题,而不仅仅是为了现在提问的人。 - cursorrux
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

1
<?php

namespace App\Exports;

use App\Models\UserDetails;
use Maatwebsite\Excel\Concerns\FromCollection;

use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;

class CustomerExport implements FromCollection, WithHeadings
{
   
    public function collection()
    {
        return UserDetails::whereNull('business_name')
        ->select('first_name','last_name','mobile_number','dob','gender')
        ->get();
    }

   
    public function headings() :array
    {
        return ["First Name", "Last Name", "Mobile","DOB", "Gender"];
    }
}

0
我正在从集合中导出数据,并且希望能够根据列名自动生成标题。下面的代码对我很有用!
public function headings(): array
{
    return array_keys($this->collection()->first()->toArray());
}

如果你想手动编写列名,请返回一个包含列名的数组。
而且别忘了实现WithHeadings接口。
感谢@Ric的评论。

-1

这段代码对我有效

use App\Newsletter;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;

class NewsletterExport implements FromCollection, WithHeadings
{
    public function headings(): array
    {
        return [
            'Subscriber Id',
            'Name',
            'Email',
            'Created_at',
        ];
    }

    public function collection()
    {
        return Newsletter::where('isSubscribed', true)->get(['id','name','email','created_at']);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接