獲取數據庫數據生成excel文件方法


1.使用插件的方式

https://docs.laravel-excel.com/3.1/imports/batch-inserts.html

   1.安裝插件

composer require maatwebsite/excel
2.創建一個操作導出表的類
php artisan make:export UsersExport   在app/Exports文件夾中生成UsersExport.php
<?php

namespace App\Exports;

use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
class SellExport implements FromCollection, WithMapping, WithHeadings
{
    public function __construct(){
        //傳參數時可以在構造函數中初始化
    }
    /**
    * @return \Illuminate\Support\Collection
    */
    public function collection()
    {
        //跨數據庫操作表
        $db = \DB::connection('old_mysql');
            $result = $db->table('student as s')->select([
                \DB::raw("sum(s.score) as total"),
                's.number',
                's.name',
                'g.phone',
            ])->leftJoin('gift as g', 'g.sid', '=', 's.gid')
                ->groupBy('s.number')
                ->orderBy('total')->get();
        return $result;
//同時也可以用模型操作比如:return User::all();
    }
    //生成excel表的字段名
    public function headings(): array
    {
        return [
            'total',
            'sales',
            'goods_code',
            'goods_barcode',
            'store_code',
            'date',
            'cn_name',
            'retail_price',
            'cost_price',
            'package_qty',
            'price',
        ];
    }
//返回每個字段的值,$sell是collection中return 后遍歷的值
    public function map($sell): array
    {
        return [
            $sell->total,
            $sell->sales,
            is_numeric($sell->goods_code) ? $sell->goods_code . "\t" : $sell->goods_code,
            is_numeric($sell->goods_barcode) ? $sell->goods_barcode . "\t" : $sell->goods_barcode,
            $sell->store_code,
            $sell->date,
            $sell->cn_name,
            $sell->retail_price,
            $sell->cost_price,
            $sell->package_qty,
            $sell->price,
        ];
    }
}
          //這里只是一個例子,其它的操作可以查看文檔   
在控制器中調用下載
use Maatwebsite\Excel\Facades\Excel;
$file = 'public/sell/'.$year.'-'.$month.'.xlsx';//默認是根目錄下的storage/app
Excel::store(new SellExport(), $file);//store有多個參數,詳細可以子在文檔中找
 
        

 

 
 

2.使用php的csv方式,結合php生成器(yield),減少內存的占用,(生成csv文件后,可以在桌面保存為excel文件),原生操作數據庫

private function generateCsv(){
        $file = storage_path().'/app/public/sell/'.date('Y-m',strtotime('-1 month')).'.csv'; //生成的csv文件路徑
    //鏈接數據庫參數
$url='localhost';//主機 $username='root';//用戶名 $pwd='root';//用戶密碼 $database='database_name';//數據庫名 $charset='utf8';//字符集 $name='user';//數據表名 $fp = fopen($file, 'a+');//存在打開文件資源,不存在就創建(追加方式)
      //csv文件內容頭部
        $csv_header = ['id','name','age'];
        fputcsv($fp,$csv_header);//使用fputcsv寫入csv文件
        foreach($this->select($url,$username,$pwd,$database,$charset,$name) as $value){
            fputcsv($fp,$value);//使用yield每次獲取一條數據寫入到csv文件
        }
        fclose($fp);
    }
    
    private function select($url='',$username='',$pwd='',$database='',$charset='',$name=''){
        $link = mysqli_connect($url,$username,$pwd);
        if(mysqli_connect_errno($link)>0){
            die(mysqli_connect_error($link));
        }
        mysqli_set_charset($link,$charset);
        mysqli_select_db($link,$database);
        $sql = "select id,name,age from user";$res = mysqli_query($link,trim($sql));//成功返回true否則false
    //
mysqli_fetch_assoc($res)逐條獲取,每次都是一條關聯數組數據
    while($result = mysqli_fetch_assoc($res)){ 
      yield
$result;
    }
    mysqli_close($link);
}

 3.laravelDB類操作數據庫

使用DB類獲取數據生成csv
//生成指定時間段表數據的csv文件
private function select()
    {
        $start_date = date('Y-m', strtotime('-1 month'));
        $end_date = date('Y-m');
        $file = storage_path().'/app/public/sell/'.date('Y-m', strtotime('-1 month')).'.csv';
        $fp = fopen($file, 'a+');//打開csv文件,沒有就自動創建
        $csv_header = ['total','sales','goods_code','goods_barcode','store_code','date','cn_name','retail_price','cost_price','package_qty','price'];
        fputcsv($fp, $csv_header);//插入字段名
    //獲取某時間段的所有數據,使用生成器yield返回單條數據
function getData($start_date, $end_date) {
        //$dataname是數據庫名,也可以在/config/database.php設置
$db = DB::connection($dataname); $result = $db->table('user as s')->select([ DB::raw("sum(s.count) as total"), DB::raw("sum(s.price) as sales"), 's.name', 'p.cn_name', ])->leftJoin('phone as p', 'g.user_id', '=', 's.id') ->where('s.date', '>=', $start_date) ->where('s.date', '<', $end_date) ->groupBy('s.goods_code', 's.store_code', 's.date') ->orderBy('total')->get()->map(function ($item) { return (array)$item;//通過get()獲取到的是集合對象,將內存對象通過map返回數組,內層對象就轉為數組, }); foreach ($result as $item) {
            //如果在csv表中字段值以科學計數法顯示加上這個"\t"
          $item['goods_barcode'] = is_numeric($item['goods_barcode']) ?  $item['goods_barcode'] . "\t" : $item['goods_barcode'];

                yield $item;//生成器返回的是一維數組
            }
        };
    //調用函數,獲取生成器的數據,通過遍歷獲取
foreach (getData($start_date, $end_date) as $data) { fputcsv($fp, $data);//$data要是一維數組才行 } fclose($fp); }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM