网页table 表格 具有excel 单元格公式功能

 

姓名数学得分英语得分总得分总得分占比
张三100801800.6206896551724138
李四50601100.3793103448275862
合计1501402901

其中灰色部分需要计算,那可以用js处理,需引用JQuery。

行是从tbody开始算的,tbody标记要有的。

给需要公式的td加上 data-s="0:[1,2]+[1,3]" 就可以,数字0代表计算优先级(因为考虑到带有公式的单元格也要参加另外一组的运算,那么另外一组的单元格优先级排后就是1,依次往后排),[1,2]+[1,3]代表[行索引,了列索引]

行索引和列索引从1开始。

公式可以嵌套函数哟,比如data-s="0:([1,2]+[1,3]).toFixed(2)" 

data-total="true" 带有此标记的单元格的值是当前列汇总合计

 

后面优化了下算法,把单元格丢进Map里面,计算性能提升了100倍

 

                            <table class="calc-expression" style="width:500px;">
                                <thead>
                                    <tr>
                                        <th>姓名</th>
                                        <th>数学得分</th>
                                        <th>英语得分</th>
                                        <th>总得分</th>
                                        <th>总得分占比</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <td>张三</td>
                                        <td>100</td>
                                        <td>80</td>
                                        <td data-s="0:[1,2]+[1,3]"></td>
                                        <td data-s="1:[1,4]/([1,4]+[2,4])"></td>
                                    </tr>
                                    <tr>
                                        <td>李四</td>
                                        <td>50</td>
                                        <td>60</td>
                                        <td data-s="0:[2,2]+[2,3]"></td>
                                        <td data-s="1:[2,4]/([1,4]+[2,4])"></td>
                                    </tr>
                                    <tr>
                                        <td>合计</td>
                                        <td data-total="true"></td>
                                        <td data-total="true"></td>
                                        <td data-total="true"></td>
                                        <td data-total="true"></td>
                                    </tr>
                                </tbody>
                            </table>

 

 

$(function () {
    $(".calc-expression").each(function () {
        var mapcell = new Map;
        var re = /\[\d+(\,\d+)?\]/g;
        var map = [];
        var lmap = [];
        var tbody = $(this).find("tbody");
        var rows = tbody.find("tr");
        rows.each(function (r1) {
            var tds = $(this).find("td");
            tds.each(function (c1) {
                var key = "[" + (Number(r1) + 1) + "," + (Number(c1) + 1) + "]";
                if (!mapcell.has(key)) {
                    mapcell.set(key, $(this).text());
                }
                if ($(this).attr("data-s") != "" && $(this).attr("data-s") != undefined) {
                    map.push($(this).attr("data-s"));
                }
            });
        });
        var compare = function (x, y) {
            if (lmap.indexOf(x.split(':')[0]) < 0) {
                lmap.push(x.split(':')[0]);
            }
            var a = x.split(':')[0];
            var b = y.split(':')[0];
            if (a < b) {
                return -1;
            } else if (a > b) {
                return 1;
            } else {
                return 0;
            }
        }
        map = map.sort(compare);

        console.time("setvalue");

        for (var k = 0; k < lmap.length; k++) {
            rows.each(function (r1) {
                var tds = $(this).find("td");
                tds.each(function (c1) {
                    if ($(this).text() == "0" || $(this).text() == "") {
                        var datas = $(this).attr("data-s");
                        if (datas != "" && datas != undefined) {
                            var key = "[" + (Number(r1) + 1) + "," + (Number(c1) + 1) + "]";
                            var temp = datas.split(":")[1];
                            var result1 = temp.match(re);
                            for (var j = 0; j < result1.length; j++) {
                                var t1 = result1[j];
                                var v = mapcell.get(t1);
                                if (v == "") {
                                    var c1 = getCellValue(rows, t1);
                                    mapcell.set(t1, c1);
                                    v = c1;
                                }

                                if (v == "") {
                                    v = 0;
                                }
                                temp = temp.replace(t1, (isNaN(v) ? v : parseFloat(v)));
                            }

                            try {
                                var temp2 = eval(temp);
                                mapcell.set(key, temp2);
                                $(this).html(temp2);
                            }
                            catch (err) {
                                $(this).html("NaN");
                            }
                        }
                    }
                });
            });
        }


        console.log("setvalue ok.");
        console.timeEnd("setvalue");

        rows.each(function (rindex) {
            var tds = $(this).find("td");
            tds.each(function (cindex) {
                if ($(this).attr("data-total") != "" && $(this).attr("data-total") != undefined) {
                    if ($(this).attr("data-total") == "true") {
                        var total = 0.0;
                        rows.each(function (i) {
                            if (i == rindex) {
                                return false;
                            }
                            else {
                                var tds2 = $(this).find("td");
                                tds2.each(function (j) {
                                    if (j == cindex) {
                                        if ($(this).html() != "") {
                                            total += parseFloat($(this).html());
                                        }
                                    }
                                });
                            }
                        });
                        $(this).html(functoFixed(total));
                    }
                }
            });
        });

        rows.each(function (rindex) {
            var tds = $(this).find("td");
            tds.each(function (cindex) {
                if ($(this).attr("data-type") != "" && $(this).attr("data-type") != undefined) {
                    if ($(this).attr("data-type") == "Percent") {
                        $(this).html(toPercent($(this).html()));
                    }
                }
            });
        });
    });
});

//0:[1,11]+[1,2]
function getCellValue(rows, a) {
    a = a.replace("[", "");
    a = a.replace("]", "");
    var result = 0;
    var x = a.split(",")[0];
    var y = a.split(",")[1];

    var h = false;
    rows.each(function (i1) {
        if (h) {
            return false;
        }
        if ((i1 + 1) == x) {
            var tds = $(this).find("td");
            tds.each(function (i2) {
                if ((i2 + 1) == y) {
                    h = true;
                    result = $(this).text();
                    return false;
                }
            });
            return false;
        }
    });

    return result;
}

 

 

转载于:https://www.cnblogs.com/diose/p/8962252.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值