xiaofeilin

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); }

 

分类:

技术点:

相关文章:

  • 2021-07-03
  • 2021-10-17
  • 2021-12-28
  • 2021-12-12
  • 2021-12-19
  • 2021-09-19
  • 2021-08-20
猜你喜欢
  • 2021-12-02
  • 2021-11-05
  • 2021-10-21
  • 2021-12-08
  • 2021-10-16
  • 2021-11-09
  • 2021-12-16
相关资源
相似解决方案