js 前端合成excel(ThinkPHP5+html+js:比纯后端合成来的快,而且超级简单。)

思路:

因为岗位是PHP,框架用的TP5,所以想用PHPExcel插件生成excel,无赖折腾了半个小时,不想折腾了。所以用js+html做算了(最终花费20分钟,又快又好做)。

1. 后端返回查询的数据集:

/*
     * 利用js合成excel接口
     * */
    public function out_excel(){

        $login_name = input("login_name");
        $pwd = input("pwd"); // 前端md5,后端再base64

        $check = $this->user_check($login_name, $pwd); // 安全校验

        if($check){

            $res = Db::name("wx_account")->field("id, wx_name, wx_login, wx_property, close_days, open_date, close_reason, fans_num, manager, add_fans, add_wx_time, flow_income, add_fans_time, add_fans_way, ad_owner, ad_owner_spend, ad_income, migration, migration_add_fans, login_email, fans_property, original_id, migration_remark, body_company, body_company_num, qr, today_income, today_first_news_amount")->select();

            $back = [
                "state"=>1,
                "msg"=>"查询完成",
                "content"=>$res,
            ];

        }else{
            $back = [
                "state"=>0,
                "msg"=>"安全校验失败",
                "content"=>null,
            ];
        }
        return json_encode($back, JSON_UNESCAPED_UNICODE);
    }

2. 然后前端把数据渲染成<table id=""><tr><th></th></tr><tr><td  scope="row"></td><td></td></tr><tr><td  scope="row"></td><td></td></tr><table>合适,然后利用js整体输出excel即可。

-

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
    <title>excel by js生成器</title>
    <script src="file/js/jquery-1.11.3.min.js" type="text/javascript"></script>
    <script src="http://cdnaliyun.oss-cn-hangzhou.aliyuncs.com/js/common.js" type="text/javascript"></script>
    <link href="file/css/com-page.css" rel="stylesheet"/>
    <script src="file/js/public.js" type="text/javascript"></script>
    <link href="file/css/common.css" rel="stylesheet"/>
    <link href="file/css/public.css" rel="stylesheet"/>
</head>
<body>

<script>
    var api_url = "https://www.djfans.net/wxmanage/public/?s=/";
    var web_url = "https://www.djfans.net/wxmanage/view/";
</script>

==================================开始====================================
<div class="excel-div hide">
    <!--开始-表格体-->
    <table id="backViewTable" class="append-table-tr">
        <!--头-->
        <tr>
            <th>id(数据记录id)</th>
            <th>主公众号名</th>
            <th>账号id</th>
            <th>账号属性</th>
            <th>封号天数</th>

            <th>解封时间</th>
            <th>封号原因</th>
            <th>实时粉丝</th>
            <th>运营者</th>
            <th>出号粉丝</th>

            <th>出号时间</th>
            <th>流量主收益</th>

            <th>今日流量主收益</th>
            <th>头条阅读量</th>

            <th>加粉时间</th>
            <th>加粉渠道</th>
            <th>是否过广告主</th>

            <th>广告主消耗</th>
            <th>广告收益</th>
            <th>是否迁移</th>
            <th>迁移加粉</th>
            <th>注册邮箱</th>

            <th>用户属性</th>
            <th>原始id</th>
            <th>迁移备注</th>
            <th>主体</th>
            <th>主体账号数量</th>

            <th>二维码</th>
        </tr>
        <!--体-->
        <!--<tr>
            <td scope="row"></td>
            <td></td>

            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>

            <td></td>
            <td></td>
        </tr>-->


    </table>
    <!--结束-表格体-->
</div>

<!--开始-合成函数-->
<script>
    var tablesToExcel = (function() { /*js生成excel*/

        var uri = 'data:application/vnd.ms-excel;base64,';
        var tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
            + '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>'
            + '<Styles>'
            + '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
            + '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
            + '</Styles>'
            + '{worksheets}</Workbook>';
        var tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table>{rows}</Table></Worksheet>';
        var tmplCellXML = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>';
        var base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) };
        var format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) };

        return function(tables, wsnames, wbname, appname) {
            var ctx = "";
            var workbookXML = "";
            var worksheetsXML = "";
            var rowsXML = "";

            for (var i = 0; i < tables.length; i++) {
                if (!tables[i].nodeType) tables[i] = document.getElementById(tables[i]);

                //  控制要导出的行数
                for (var j = 0; j < tables[i].rows.length; j++) {
                    rowsXML += '<Row>';

                    //  控制导出的列数(在本例中,最后一列为button,导出的文件会出错,所以导出到倒数第二列
                    for (var k = 0; k < tables[i].rows[j].cells.length-1; k++) {
                        var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
                        var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
                        var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
                        dataValue = (dataValue)?dataValue:tables[i].rows[j].cells[k].innerHTML;
                        var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
                        dataFormula = (dataFormula)?dataFormula:(appname=='Calc' && dataType=='DateTime')?dataValue:null;
                        ctx = {  attributeStyleID: (dataStyle=='Currency' || dataStyle=='Date')?' ss:StyleID="'+dataStyle+'"':''
                            , nameType: (dataType=='Number' || dataType=='DateTime' || dataType=='Boolean' || dataType=='Error')?dataType:'String'
                            , data: (dataFormula)?'':dataValue
                            , attributeFormula: (dataFormula)?' ss:Formula="'+dataFormula+'"':''
                        };
                        rowsXML += format(tmplCellXML, ctx);
                    }
                    rowsXML += '</Row>'
                }
                ctx = {rows: rowsXML, nameWS: wsnames[i] || 'Sheet' + i};
                worksheetsXML += format(tmplWorksheetXML, ctx);
                rowsXML = "";
            }

            ctx = {created: (new Date()).getTime(), worksheets: worksheetsXML};
            workbookXML = format(tmplWorkbookXML, ctx);

            //  查看后台的打印输出
            console.log(workbookXML);

            var link = document.createElement("A");
            link.href = uri + base64(workbookXML);
            link.download = wbname || 'Workbook.xls';
            link.target = '_blank';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);

            // 其他
            alert_txt("合成完成!自动下载xls完成!", 5000);
            setTimeout(function () {
                $(".excel-div").remove();
                setTimeout(function () {
                    //完成后的操作
                    window.close();

                }, 2500)
            }, 200);

        }

    })();

    function make_excel(name) { // 开始执行合成excel
        if (!name){name="未命名表格"}
        tablesToExcel(['backViewTable'], ['ProductDay1'], name+'.xls', 'Excel');
    }
    // make_excel("test");

</script>
<!--结束-合成函数-->
========================================结束===============================

<script src="file/js/com-page.js" type="text/javascript"></script>
<script>

    function get_excel_data() { // 渲染excel HTML排版原始数据

        (function () { // 登录状态自检

            // 请求数据
            $.ajax({
                url: api_url+"admin/statistic/out_excel",
                type: "POST",
                dataType: "json",
                async: true,
                data: { // 字典数据
                    login_name: login_name,
                    pwd: pwd,
                },
                success: function(data, status){
                    console_log("返回数据="+data);
                    if(typeof data === "string"){datas = JSON.parse(data);}else {datas = data;}

                    if (datas.state===0){
                        console_log(datas.msg)

                    }else if (datas.state===1) {
                        console_log(datas.msg);
                        var list = datas.content;

                        for (var x=0; x<list.length; x++){

                            var id = list[x]["id"];
                            var wx_name = list[x]["wx_name"];
                            var wx_login = list[x]["wx_login"];
                            var wx_property = list[x]["wx_property"];
                            var close_days = list[x]["close_days"]; //5

                            var open_date = list[x]["open_date"];
                            var close_reason = list[x]["close_reason"];
                            var fans_num = list[x]["fans_num"];
                            var manager = list[x]["manager"];
                            var add_fans = list[x]["add_fans"]; //10

                            var add_wx_time = list[x]["add_wx_time"];
                            var flow_income = list[x]["flow_income"];
                            var add_fans_time = list[x]["add_fans_time"];
                            var add_fans_way = list[x]["add_fans_way"];
                            var ad_owner = list[x]["ad_owner"]; //15

                            var ad_owner_spend = list[x]["ad_owner_spend"];
                            var ad_income = list[x]["ad_income"];
                            var migration = list[x]["migration"];
                            var migration_add_fans = list[x]["migration_add_fans"];
                            var login_email = list[x]["login_email"]; //20

                            var fans_property = list[x]["fans_property"];
                            var original_id = list[x]["original_id"];
                            var migration_remark = list[x]["migration_remark"];
                            var body_company = list[x]["body_company"];
                            var body_company_num = list[x]["body_company_num"]; // 25

                            var qr = list[x]["qr"];

                            var today_income = list[x]["today_income"];
                            var today_first_news_amount = list[x]["today_first_news_amount"];
                            if(today_first_news_amount===null){today_first_news_amount="暂无";}

                            $(".append-table-tr").append('<tr>' +
                                '<th scope="row">'+id+'</th>' +
                                '<td>'+wx_name+'</td>' +
                                '<td>'+wx_login+'</td>' +
                                '<td>'+wx_property+'</td>' +
                                '<td>'+close_days+'</td>' +

                                '<td>'+open_date+'</td>' +
                                '<td>'+close_reason+'</td>' +
                                '<td>'+fans_num+'</td>' +
                                '<td>'+manager+'</td>' +
                                '<td>'+add_fans+'</td>' +

                                '<td>'+add_wx_time+'</td>' +
                                '<td>'+flow_income+'</td>' +

                                '<td>'+today_income+'</td>' +
                                '<td>'+today_first_news_amount+'</td>' +

                                '<td>'+add_fans_time+'</td>' +
                                '<td>'+add_fans_way+'</td>' +
                                '<td>'+ad_owner+'</td>' +

                                '<td>'+ad_owner_spend+'</td>' +
                                '<td>'+ad_income+'</td>' +
                                '<td>'+migration+'</td>' +
                                '<td>'+migration_add_fans+'</td>' +
                                '<td>'+login_email+'</td>' +

                                '<td>'+fans_property+'</td>' +
                                '<td>'+original_id+'</td>' +
                                '<td>'+migration_remark+'</td>' +
                                '<td>'+body_company+'</td>' +
                                '<td>'+body_company_num+'</td>' +

                                '<td>'+(web_url+qr)+'</td>' +
                                '</tr>');
                        } // end-for

                        alert_txt("正在生成Excel文件...", "long");
                        setTimeout(function () {
                            make_excel("主公众号信息"+getNowDate()[0]+""+getNowDate()[2]+""+getNowDate()[1]);
                        }, 200);
                    }
                },
                error: function (xhr) {
                    console.log(xhr);
                    alert_txt("接口请求错误或者网络不通", 2500);
                }
            });
        })();

    }

</script>

<script>

    var login_name = getCookie(cookie_pre+"login_name");
    var pwd = getCookie(cookie_pre+"pwd");

    var url_page = getThisUrlParam("", "page")*1;
    if(url_page<1){url_page=1;}

    (function () { // 登录状态自检

        // 请求数据
        $.ajax({
            url: api_url+"admin/login/login",
            type: "POST",
            dataType: "json",
            async: true,
            data: { // 字典数据
                login_name: login_name,
                pwd: pwd,
            },
            success: function(data, status){
                console_log("post返回数据:" + data+";status:"+status+";返回数据的类型:"+typeof data);
                if(typeof data === "string"){datas = JSON.parse(data);}else {datas = data;}

                if (datas.state===0){
                    console_log("未登录");

                }else if (datas.state===1) {
                    console_log("已登录");
                    get_excel_data();
                }
            },
            error: function (xhr) {
                console.log(xhr);
                alert_txt("接口请求错误或者网络不通", 2500);
            }
        });
    })();

</script>

</body>
</html>

-进入html页面即可完成渲染-合成-下载

-office2019打开文件正常。

js 前端合成excel(ThinkPHP5+html+js:比纯后端合成来的快,而且超级简单。)

-