thinkphp5.1导出csv表格

CrazyMing 2019-08-15
0条评论 181 次浏览
CrazyMing 2019-08-150条评论 181 次浏览

网上看了很多 导出csv的方法,但是我在项目里运用是总是 出现一些问题,所以结合网上找的方法做了一些修改 以供参考.
项目框架:tp5.1

新建一个ExportCsv类

<?php


namespace app\common\utils;


class ExportCsv
{

    /**
     * 导出CSV
     * @param $list
     * @param $title
     * @param string $fileName
     */
    public static function put_csv($list, $title, $fileName = 'default')
    {
        $file_name = "kys_data_" . $fileName . time() . ".csv";
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename=' . $file_name);
        header('Cache-Control: max-age=0');
        $file = fopen('php://output', "a");
        $limit = 1000;
        $calc = 0;

        $tit = array();

        //标题
        foreach ($title as $v) {
//            array_push($tit, iconv('UTF-8', 'GB2312//IGNORE', $v));
            array_push($tit, $v);
        }
        fputcsv($file, $tit);//可以理解为将$tit 数组作为表格中的一行数据 写入 $file

        //数据记录
        foreach ($list as $k => $v) {
            $calc++;
            if ($limit == $calc) {
                ob_flush();
                flush();
                $calc = 0;
            }

            $tarr = [];
            foreach ($v as $value) {
                array_push($tarr, $value);
//                array_push($tarr, iconv('UTF-8', 'GB2312//IGNORE', $value));
            }
            fputcsv($file, $tarr);//可以理解为 将$tarr 数组 做为表格中的一行数据 写入$file

        }


        fclose($file);
        exit();
    }


}

在需要使用的地方直接调用这个put_csv这个静态方法就可以了,我是建了一个ExportToCsv的控制器,用来专门处理项目中 所有的 导出csv 请求,根据 请求url 中的 type 去实例化 对应的 控制器,执行对应控制器中的 导出csv方法. 例如:导出所有的 玩家信息,,路由这样配置:Route::get(‘export_csv’, ‘api/ExportToCsv/index’); 然后我们访问http://www.example.com/export_csv?type=player 就可导出了

ExportToCsv控制器代码:

<?php

namespace app\api\controller;

use app\common\utils\AjaxReturn;
use app\common\utils\ExportCsv;
use think\Controller;
use think\Request;

class ExportToCsv extends Controller
{

    public function index($type = '')
    {


        switch ($type) {
            case "player":
                $player = controller('Player');//实例化 Player 控制器
                $arr = $player->exportCsv();
                $list = $arr['list'];
                $title = $arr['title'];
                ExportCsv::put_csv($list, $title, $type);
                break;
            case "wechat":
                //忽略
                break;
            default:
                return json(AjaxReturn::jsonPack([], AjaxReturn::ERROR_RESPONSE_DATA_VALIDATE_FAIL));

        }

    }

}


use 前面 写的 app\common\utils\ExportCsv 类,(app\common\utils\AjaxReturn是我封装的一个ajax返回通用格式,删掉就好),

$player = controller(‘Player’);//实例化 Player 控制器
$arr = $player->exportCsv();//执行Player 控制器的exportCsv()

player控制器 exportCsv()方法 代码如下:

    /**
     * 导出csv
     */
    public function exportCsv()
    {

        $data = KysPlayer::where([])
            ->alias('p')
            ->join('kys_user u', 'p . user_id = u . user_id')
            ->leftJoin('kys_user_vip v', 'p . user_id = v . user_id')
            ->field([])
            ->select()->toArray();


        $title = ['玩家id', '玩家名称', '玩家头像', '玩家性别', '玩家签名'];
        return ['list' => $data, 'title' => $title];

    }
这里有个坑 tp 链式操作select()后一定要用toArray()转成标准数组,否则 导出的 csv 是只有标题 没有数据的

$arr = $player->exportCsv();//接收 player控制器 exportCsv 返回的结果
$list = $arr[‘list’];
$title = $arr[‘title’];
ExportCsv::put_csv($list, $title,$type);//执行导出 put_csv 静态方法

这样就ok了 前端 访问http://www.example.com/export_csv?type=player 就可以导出了

前端代码:

  downloadFn(){
        this.ele_notify('稍等 表格开始导出');
        window.location.href=window.API_server.API_ADDRESS+'/export_csv?type=player';
      },
3+

发表评论

电子邮件地址不会被公开。

隐藏
变装