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导出结果:

希望对你有所帮助!

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