天天看點

Laravel-admin如何使用Maatwebsite/Laravel-Excel導出資料

在Laravel-admin中使用Laravel擴充包--Maatwebsite/Laravel-Excel導出資料

    • Maatwebsite/Laravel-Excel介紹
    • 使用3.1時遇到的問題

Maatwebsite/Laravel-Excel介紹

官方文檔

Laravel-Excel一共有三個版本,2.1====>3.0====>3.1。我們先來看下每個版本的跟Laravel架構以及PHP的相容情況,見下圖。

Laravel-admin如何使用Maatwebsite/Laravel-Excel導出資料

LZ用過了三個版本。。。如果你是剛剛開始使用這個擴充包,隻要環境支援就一定要用3.1版本。先不說3.1的設計更加優雅。首先3.0沒有導入功能,emm沒錯,當時好不容易等到新的版本釋出居然沒有導入。。and 3.8不向下相容2.*。so好像也沒什麼理由不選3.1了hhh

Laravel-admin如何使用Maatwebsite/Laravel-Excel導出資料

使用3.1時遇到的問題

class OrderExport extends ExcelExporter implements WithMapping, WithStrictNullComparison
{

    protected $fileName = '訂單清單.xlsx';

    protected $columns = [
        'product_id' => '産品名稱',
        'position_id' => '産品連結',
        'company_id' => '公司名稱',

        'recipient' => '收件人',
        'mobile' => '聯系電話',
        'province' => '詳細位址',
        'city' => '詳細位址',
        'county' => '詳細位址',
        'house_number' => '詳細位址',

        'order_begin_time' => '下單時間',
        'price' => '産品單價',
        'count' => '數量',
        'express_fee' => '快遞費',
//        'goods_type' => '物品類型',
        'order_close_time' => '訂單完成時間',
        'note' => '備注',
        'express_no' => '快遞單号',
        'express_company' => '快遞公司',
        'order_status' => '訂單狀态',
        'pay_method' => '付款方式',
        'safeguard_status' => '維權狀态',
        'address_valid' => '位址有效性',
        'created_at' => '建立時間',
    ];


    public function map($row): array
    {

        return [
            data_get($row, 'product.name'),
            data_get($row, 'position.link'),
            data_get($row, 'company.name'),
            $row->recipient,
            $row->mobile,
            $row->province . $row->city . $row->county . $row->house_number,
            $row->order_begin_time,
            $row->price,
            $row->count,
            $row->express_fee,
//            $row->goods_type,
            $row->order_close_time,
            $row->note,
            $row->express_no,
            $row->express_company,
            Tools::orderStatusMap()[$row->order_status ?: '0'],
            Tools::payMethodMap()[$row->pay_method ?: '0'],
            Tools::safeguardtSatusMap()[$row->safeguard_status ?: '0'],
            Tools::addressValidMap()[$row->address_valid ?: '0'],
            $row->created_at,
        ];
    }
}
           

這樣會導緻導出的表頭出現四個重複的詳細位址字段

Laravel-admin如何使用Maatwebsite/Laravel-Excel導出資料

有沒有很好奇這裡的表頭是怎麼設定出來。。然後看了一下生成的導出類會繼承ExcelExporter類

abstract class ExcelExporter extends AbstractExporter implements FromQuery, WithHeadings
{
    use Exportable;

    /**
     * @var string
     */
    protected $fileName;

    /**
     * @var array
     */
    protected $headings = [];

    /**
     * @var array
     */
    protected $columns = [];

    /**
     * @return array
     */
    public function headings(): array
    {
        if (!empty($this->columns)) {
            return array_values($this->columns);
        }

        return $this->headings;
    }
           

ExcelExporter類裡面的headings方法直接從的導出類裡擷取到columns變量,so外面可以在自己生成的導出類重寫一下headings方法

class OrderExport extends ExcelExporter implements WithMapping, WithStrictNullComparison, WithHeadings
{

   protected $fileName = '訂單清單.xlsx';
   // 添加headings方法,去重columns的值
   public function headings(): array
   {
       if (!empty($this->columns)) {
           return array_values(array_unique($this->columns));
       }
       
       return parent::headings();
   }
   // 設定需要從庫中檢索出的字段
   protected $columns = [
       'product_id' => '産品名稱',
       'position_id' => '産品連結',
       'company_id' => '公司名稱',
       'recipient' => '收件人',
       'mobile' => '聯系電話',
       'province' => '詳細位址',
       'city' => '詳細位址',
       'county' => '詳細位址',
       'house_number' => '詳細位址',
       'order_begin_time' => '下單時間',
       'price' => '産品單價',
       'count' => '數量',
       'express_fee' => '快遞費',
       'order_close_time' => '訂單完成時間',
       'note' => '備注',
       'express_no' => '快遞單号',
       'express_company' => '快遞公司',
       'order_status' => '訂單狀态',
       'pay_method' => '付款方式',
       'safeguard_status' => '維權狀态',
       'address_valid' => '位址有效性',
       'created_at' => '建立時間',
   ];
  // 設定映射字段
   public function map($row): array
   {
       return [
           data_get($row, 'product.name'),
           data_get($row, 'position.link'),
           data_get($row, 'company.name'),
           $row->recipient,
           $row->mobile,
           $row->province . $row->city . $row->county . $row->house_number,
           $row->order_begin_time,
           $row->price,
           $row->count,
           $row->express_fee,
           $row->order_close_time,
           $row->note,
           $row->express_no,
           $row->express_company,
           Tools::orderStatusMap()[$row->order_status ?: '0'],
           Tools::payMethodMap()[$row->pay_method ?: '0'],
           Tools::safeguardtSatusMap()[$row->safeguard_status ?: '0'],
           Tools::addressValidMap()[$row->address_valid ?: '0'],
           $row->created_at,
       ];
   }
}
           

進行如下修改後就可以正常導出了。。。

今天先寫到這裡了。。下班啦啦啦