zoukankan      html  css  js  c++  java
  • 网页table 表格 具有excel 单元格公式功能

    姓名数学得分英语得分总得分总得分占比
    张三 100 80 180 0.6206896551724138
    李四 50 60 110 0.3793103448275862
    合计 150 140 290 1

    其中灰色部分需要计算,那可以用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="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;
    }

  • 相关阅读:
    linux基础_第一篇_IT运维介绍
    Java实现文件分割和文件合并实例
    dotweb——go语言的一个微型web框架(三)路由注册
    dotweb——go语言的一个微型web框架(二)启动dotweb
    dotweb——go语言的一个微型web框架(一)
    Linq的查询操作符
    dsfgdfg
    .NET Entity Framework (with Oracle ODP.NET) -Code First
    .NET Entity Framework (with Oracle ODP.NET)
    ODP.NET 之 ExecuteNoQuery 执行 Merge into 返回值
  • 原文地址:https://www.cnblogs.com/diose/p/8962252.html
Copyright © 2011-2022 走看看