phpoffice/phpspreadsheet Excel導出輸出流亂碼

1、亂碼截圖

我是用的Ajax請求,附上解決辦法:

header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $name . '.xlsx"');
header('Cache-Control: max-age=0');
$writer = new Xlsx($spreadsheet);
ob_start(); //打開緩衝區
$writer->save('php://output'); //這裏就是亂碼
// 接收並處理
$xlsData = ob_get_contents();
ob_end_clean(); // 清除緩衝
$response =  array(
    'code' => '1',
    'file' => "data:application/vnd.ms-excel;base64,".base64_encode($xlsData),
    'msg'=>'導出成功'
);
return json_encode($response);

附上全部代碼:

1、html部分:

<div class="center mb10">
    <form class="layui-form " method="post">
        <div class="layui-input-inline w150">
            <select name="status" id="sel">
                <option value="">選擇狀態</option>
                <option value="0" {if condition="$param['status'] eq '0'"}selected {/if}>未審覈</option>
                <option value="1" {if condition="$param['status'] eq '1'"}selected {/if}>已審覈</option>
            </select>
        </div>
        <div class="layui-input-inline w150">
            <select name="group" id="group">
                <option value="">選擇會員組</option>
                {volist name="group_list" id="vo"}
                <option value="{$vo.group_id}" {if condition="$param['group'] eq $vo.group_id"}selected {/if}>{$vo.group_name}</option>
                {/volist}
            </select>
        </div>

        <div class="layui-input-inline">
            <input type="text" autocomplete="off" value="{$start_time}" id="datetimeStart" readonly class="form_datetime layui-input" name="start_time" placeholder="請選擇開始時間" />
        </div>
        -
        <div class="layui-input-inline">
            <input type="text" autocomplete="off" value="{$end_time}" id="datetimeEnd" readonly class="form_datetime layui-input" name="end_time" placeholder="請選擇結束時間" />
        </div>

        <div class="layui-input-inline">
            <input type="text" autocomplete="off" placeholder="請輸入搜索條件" class="layui-input" name="wd" value="{$param['wd']}">
        </div>
        <button class="layui-btn mgl-20 j-search" >查詢</button>
        <button class="layui-btn mgl-20" type="button" id="btnExport" onclick="excel()">導出</button>
    </form>
</div>

2、JS部分:

//Excel導出事件
function excel()
{
    var status = $("#sel option:selected").val();
    var group = $("#group option:selected").val();
    var start_time = $('#datetimeStart').val();
    var end_time = $('#datetimeEnd').val();
    $.ajax({
        url: "{:url('admin/user/export')}",
        data: {
            status:status,
            group:group,
            start_time:start_time,
            end_time:end_time
        },
        type: 'post',
        dataType: 'json',
        success: function (ret) {
            var $a = $("<a>");
            $a.attr("href",ret.file);
            $("body").append($a);
            $a.attr("download","file.xls");
            $a[0].click();
            $a.remove();
            if (ret.code == -1) {
                alert(ret.msg);
            } else if (ret.code == 1) {
                window.location.href = "{:url('admin/user/data')}";
            }
        },
        error: function () {
            alert('請求失敗,請刷新重試!');
        }
    })
}

3、封裝部分Excel導出:

<?php
namespace app\admin\controller;
use think\Db;
use app\common;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

class User extends Base
{
    public function __construct()
    {
        parent::__construct();
    }
/**
 * Excel導出會員表
 * @throws \PHPExcel_Exception
 * @throws \PHPExcel_Reader_Exception
 * @throws \PHPExcel_Writer_Exception
 */
public function export()
{
    if(Request()->isAjax()){
        $param = input('post.');
        $res = $this->call($param);
        // Excel導出部分
        $name = '會員表'.date('YmdHis');
        $head  = ['用戶名稱','狀態','積分','上次登錄時間','上次登錄IP','登錄次數'];
        $key = ['user_name','user_status','user_points','user_login_time','user_last_login_ip','user_login_num'];
        foreach($res['list'] as $k=>$v){
            $arr = [
                'user_name'             => $v['user_name'],
                'user_status'           => $v['user_status'],
                'user_points'           => $v['user_points'],
                'user_login_time'       => date('Y-m-d H:i:s',$v['user_login_time']),
                'user_last_login_ip'    => long2ip($v['user_last_login_ip']),   //將IP整型轉換成IP格式
                'user_login_num'        => $v['user_login_num']
            ];
            $data[] = $arr;
        }
        $result = $this->exportExcel($name,$data,$head,$key);
        die($result);
    }else{
        die(json_encode(array('code'=>-1,'msg'=>'導出失敗,請刷新重試')));
    }
}
/**
 * 導出excel表方法封裝
 * $data:要導出excel表的數據,接受一個二維數組
 * $name:excel表的表名
 * $head:excel表的表頭,接受一個一維數組
 * $key:$data中對應表頭的鍵的數組,接受一個一維數組
 * 備註:此函數缺點是,表頭(對應列數)不能超過26;
 *循環不夠靈活,一個單元格中不方便存放兩個數據庫字段的值
 */
public function exportExcel($name, $data=[], $head=[], $keys=[]){
    $count = count($head);  //計算表頭數量
    $spreadsheet = new Spreadsheet();

    $sheet = $spreadsheet->getActiveSheet();

    for ($i = 65; $i < $count + 65; $i++) {     //數字轉字母從65開始,循環設置表頭:
        $sheet->setCellValue(strtoupper(chr($i)) . '1', $head[$i - 65]);
    }

    /*--------------開始從數據庫提取信息插入Excel表中------------------*/
    foreach ($data as $key => $item) {             //循環設置單元格:
        //$key+2,因爲第一行是表頭,所以寫到表格時   從第二行開始寫

        for ($i = 65; $i < $count + 65; $i++) {     //數字轉字母從65開始:
            $sheet->setCellValue(strtoupper(chr($i)) . ($key + 2), $item[$keys[$i - 65]]);
            $spreadsheet->getActiveSheet()->getColumnDimension(strtoupper(chr($i)))->setWidth(20); //固定列寬
        }

    }

    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment;filename="' . $name . '.xlsx"');
    header('Cache-Control: max-age=0');
    $writer = new Xlsx($spreadsheet);
    ob_start(); //打開緩衝區
    $writer->save('php://output'); //這裏就是亂碼
    $xlsData = ob_get_contents();
    ob_end_clean(); // 清除緩衝
    // 接收$writer->save('php://output')
    $response =  array(
        'code' => '1',
        'file' => "data:application/vnd.ms-excel;base64,".base64_encode($xlsData),
        'msg'=>'導出成功'
    );
    return json_encode($response);
}

4、Excel導出結果:

希望對你有所幫助!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章