网页在线编辑表格|仿Excel|特定表头后超级爽

最近公司开发的EMIS系统有个模块需要按excel格式写,原先有个estartable插件,我们经理写的,在原来的模块上面很好用,由于我水平有限,我在短期内不能清晰的修改或扩展它,最近掌握了angularJS,突发奇想,自己写了这套,没有写的太高深,但效果很满意哦。,废话、又是废话一堆,那么咱们上截图看看啥样的效果吧:
理想的样子、也是最终的效果
这里写图片描述

基于angularJS 强大的数据绑定实现的实时计算功能
这里写图片描述

异常受我喜爱的各大优势
这里写图片描述

有点脑残了,光把优势写在图片上了,忘记拷贝到这里了。…..

简单罗列使用优势:
外观:
1、简单、美丽、看着就舒服…..醉了

操作:
1、新增一行,方便快捷,缺点:暂时不能在指定位置插入一行,需要优化功能
2、删除按钮:每行最前方有删除按钮,根据本行索引自动删除,同时也会传入本行id,会触发到数据库同步删除数据
3、保存:一行一个对象,存在json数据,逐行存储方式,避免服务器压力
4、强大的自动计算:可根据需要指定某些单元格的计算结果显示在某个单元格内,目前适用于本行内,不适用于异行操作
5、强大的编辑功能:随时随地,点谁编辑谁,即编即存,这全基于angular的双向数据绑定功能,不多解释。
6、自动显示序号功能,无需写代码,自己会展示。
…..
时间原因,不多解析;先上一部分代码看看喽

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="birdApp">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="../../../../../../js/jquery-1.10.2.min.js"></script>
    <script src="../../../../../../js/jquery.query.js"></script>
    <link href="../../../../../../js/bootstrap-3.2.0/css/bootstrap.css" rel="stylesheet" />
    <script src="../../../../../../js/angular/angular.js"></script>
    <link href="css/edit.css" rel="stylesheet" />
</head>
<body ng-controller="birdCtrl">
    <div class="panel">
        <span class="btn btn-success" ng-click="save()">保存填写</span>
        <button type="button" class="btn btn-danger" ng-click="addRow()">新增一行</button>
        <small>单元格提示:<span style="background: #CBCBCB">灰色区域</span>为禁填,白色区域为选填内容,直接点击白色区域即可编辑</small>
    </div>
    <table>
        <thead>
            <tr>
                <th rowspan="3" width="23">操作</th>
                <th colspan="20" style="background-color: white">  填报人:<input type="text" ng-model="username" />                                                联系方式: <input type="text" ng-model="tel" />       </th>
                <th colspan="2" style="background-color: #CC99FF ;">{{getData(-1)}}鸟巢处理情况</th>
                <th colspan="6" style="background-color: #99CCFF">{{getData(0)}}鸟巢位置统计分析</th>
                <th colspan="3" style="background-color: #CCFFCC">{{getData(1)}}登乘巡视计划</th>
            </tr>
            <tr>
                <th rowspan="2" style="width:20px;">序号</th>
                <th rowspan="2" style="width:60px;">线别</th>
                <th rowspan="2" style="width:60px;">区段</th>
                <th rowspan="2" style="width:60px;">段/车间/工区</th>
                <th rowspan="2" style="width:50px;">登乘人员(或巡视人员)</th>
                <th rowspan="2" style="width:50px;">登乘车次(或巡视时间)</th>
                <th rowspan="2" style="background-color: #CCFFFF;width:80px;">{{getData(0)}}当日登乘发现鸟巢处所</th>
                <th colspan="3" style="width:100px;">当日发现鸟巢数量</th>

                <th rowspan="2" style="background-color: #CCFFFF;width:30px;">本周累计发现鸟巢数量</th>

                <th colspan="3" style="width:40px;">本周已处理鸟巢数量</th>

                <th rowspan="2" style="background-color: #CCFFFF;width:30px">本月累计发现鸟巢数量</th>
                <th colspan="3">本月已处理鸟巢数量</th>

                <th rowspan="2" style="width:30px;">目前遗留问题数量</th>
                <th rowspan="2">目前遗留问题处所</th>

                <th rowspan="2" style="background-color: #CC99FF;width:30px;">处理鸟巢数量</th>
                <th rowspan="2" style="background-color: #CC99FF">鸟巢处理处所 </th>

                <th rowspan="2" style="background-color: #99CCFF;width:20px;">补偿装置</th>
                <th rowspan="2" style="background-color: #99CCFF; width: 20px; ">隔离开关底座</th>
                <th rowspan="2" style="background-color: #99CCFF; width: 20px; ">腕臂底座</th>
                <th rowspan="2" style="background-color: #99CCFF; width: 20px; ">硬横梁</th>
                <th rowspan="2" style="background-color: #99CCFF; width: 20px; ">跳线肩架</th>
                <th rowspan="2" style="background-color: #99CCFF; width: 20px; ">其它</th>

                <th rowspan="2" style="background-color: #CCFFCC; width: 60px; ">段/车间/工区</th>
                <th rowspan="2" style="background-color: #CCFFCC; width: 60px; ">登乘人员(巡视人员)</th>
                <th rowspan="2" style="background-color: #CCFFCC; width: 60px; ">登乘车次(或巡视时间)</th>
            </tr>
            <tr>
                <th style="width:35px;">合计</th>
                <th style="width:30px;">需临时要点处理</th>
                <th style="width:30px;">需纳入天窗处理</th>
                <th style="width:35px;">合计</th>
                <th style="width:30px;">临时要点处理</th>
                <th style="width:30px;">纳入天窗计划</th>
                <th style="width:35px;">合计</th>
                <th style="width:30px;">临时要点处理</th>
                <th style="width:30px;">纳入天窗计划</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="item in todo.items ">
                <td><button class="deletes" title="删除" ng-click='deleteRow({{$index}},item.id)'>x</button></td>
                <td>{{$index+1}}</td>
                <td>
                    <select ng-model="item.RAILWAYID">
                        <option value="idlong">陇海线</option>
                        <option value="idjing">京广线</option>
                        <option value="idlx">龙线</option>
                        <option value="idfeiguang">飞光线</option>
                        <option value="idsanjing">三经线</option>
                    </select>
                </td>
                <td>
                    <select ng-model="item.SECTIONID">
                        <option value="idlong">陇海线</option>
                        <option value="idjing">京广线</option>
                        <option value="idlx">龙线</option>
                        <option value="idfeiguang">飞光线</option>
                        <option value="idsanjing">三经线</option>
                    </select>
                </td>
                <td><input type="text" ng-model="item.JGNAME" /></td>
                <td><input type="text" ng-model="item.CARPERSON" /></td>
                <td><input type="text" ng-model="item.CARTIMES" /></td>
                <td><input type="text" ng-model="item.LOCATION" /></td>

                <td>{{(item.TODAYTEMP*1)+(1*item.TODAYADD)}}</td>
                <td><input type="text" ng-model="item.TODAYTEMP" /></td>
                <td><input type="text" ng-model="item.TODAYADD" /></td>

                <td style="background-color: #CBCBCB">{{item.weekTotal}}</td>
                <td style="background-color: #CBCBCB">{{item.weekCount}}</td>
                <td style="background-color: #CBCBCB">{{item.weekDeul}}</td>
                <td style="background-color: #CBCBCB">{{item.weekNaru}}</td>

                <td style="background-color: #CBCBCB">{{item.monthTotal}}</td>
                <td style="background-color: #CBCBCB">{{item.monthCount}}</td>
                <td style="background-color: #CBCBCB">{{item.monthDeul}}</td>
                <td style="background-color: #CBCBCB">{{item.monthNaru}}</td>

                <td><input type="text" ng-model="item.yiliu" /></td>
                <td><input type="text" ng-model="item.yiliuchusuo" /></td>

                <td style="background-color: #CBCBCB">{{item.LEAVECOUNT}}</td>
                <td style="background-color: #CBCBCB">{{item.LEAVELOCATION}}</td>

                <td><input ng-model="item.TOTAL1" /></td>
                <td><input ng-model="item.TOTAL2" /></td>
                <td><input ng-model="item.TOTAL3" /></td>
                <td><input ng-model="item.TOTAL4" /></td>
                <td><input ng-model="item.TOTAL5" /></td>
                <td><input ng-model="item.TOTAL6" /></td>

                <td><input ng-model="item.PLANJGNAME" /></td>
                <td><input ng-model="item.PLANCARPERSON" /></td>
                <td><input ng-model="item.PLANCARTIMES" /></td>

            </tr>
        </tbody>
    </table>
    {{todo.tips}}
    <div style="position:absolute;bottom:5px;left:10px;">

        <button type="button" class="btn btn-danger" onclick="top.closewin()">关闭</button>
        <button type="button" class="btn btn-danger" ng-click="length()">显示数据</button>
    </div>
    <script type="text/javascript">
        //获取必要信息
        var today = $.query.get('time');
        var planid = $.query.get('id');
        //绑定一个存在的应用模型
        var birdApp = angular.module('birdApp', []);
        //绑定控制器
        birdApp.controller("birdCtrl", function ($scope, $http) {
            //总信息存储对象
            $scope.todo = {
                items: [],
                data: today.length > 6 ? today : '2016-01-01',
                tips: '正在加载数据...'
            };

            //首次加载数据|Bug:不能立即展示数据,需要手动点击显示|原因很难查
            $scope.load = function () {
                $.get('/Bureau/1power/catenary/specialplan/yearplan/bird_special/ashx/edit.ashx?r=' + Math.random(),
                         { act: 'list', planid: planid, createtime: today },
                         function (ret) {
                             if (ret.flag) {
                                 if (ret.datas.length > 0) {
                                     for (var i = 0; i < ret.datas.length; i++) {
                                         $scope.todo.items.push(ret.datas[i]);
                                     }
                                     $scope.username = ret.username;
                                     $scope.tel = ret.tel;
                                     $scope.todo.tips = '加载完毕';
                                 }
                             }
                             else {
                                 $scope.todo.tips = '暂无数据,请新增一行进行填写';
                             }
                         });
            };
            $scope.load();

            //得到日期
            $scope.getData = function (tag) {
                var temp = $scope.todo.data.split('-');
                if (temp.length != 3) {
                    return $scope.todo.data;
                }
                var year = temp[0];
                var month = temp[1];
                var day = temp[2];
                switch (tag) {
                    case 0://当天
                        break;
                    case 1://下一天
                        if (day == DayNumOfMonth(year, month)) {
                            month = Number(month) + 1;
                            month = (month == 13) ? 1 : month;
                            day = 1;
                        }
                        else
                            day = Number(day) + 1;
                        break;
                    case -1://上一天
                        if (day == 1) {
                            month = Number(month) - 1;
                            year = (month == 0) ? Number(year) - 1 : year;
                            month = (month == 0) ? 12 : month;
                            day = DayNumOfMonth(year, month);
                        }
                        else
                            day = Number(day) - 1;
                        break;
                }
                return month + "月" + day + "日";
            }
            //添加一行
            $scope.addRow = function () {
                var o = {
                    "id": newguid(), "no": "", "RAILWAYID": "", "SECTIONID": '', "JGNAME": "",
                    "CARPERSON": "", "CARTIMES": "", "LOCATION": "无",
                    "dayCount": 0, "TODAYTEMP": 0, "TODAYADD": 0,
                    "weekTotal": "", "weekCount": "", "weekDeul": "", "weekNaru": "",
                    "monthTotal": "", "monthCount": "", "monthDeul": "", "monthNaru": "",
                    "LEAVECOUNT": "", "LEAVELOCATION": "",
                    "TOTAL1": "", "TOTAL2": "", "TOTAL3": "", "TOTAL4": "", "TOTAL5": "", "TOTAL6": "",
                    "PLANJGNAME": "", "PLANCARPERSON": "", "PLANCARTIMES": "", "planid": planid, "CREATETIME": today
                };
                $scope.todo.items.push(o);
            }
            //保存
            $scope.save = function () {
                var flag = 0;
                for (var i = 0; i < $scope.todo.items.length; i++) {
                    $.get('/Bureau/1power/catenary/specialplan/yearplan/bird_special/ashx/edit.ashx?r=' + Math.random(),
                        { act: 'save', data: $scope.todo.items[i], username: $scope.username, tel: $scope.tel },
                        function (data) {
                            if (data.flag) { flag++; }
                            else { alert('第' + i + '条,保存失败,' + data.msg); }
                            if (flag >= $scope.todo.items.length) { alert('保存成功'); }
                        });
                }
            }
            //删除当前行
            $scope.deleteRow = function (index, rowid) {
                var tempArray = $scope.todo.items;
                $.get('/Bureau/1power/catenary/specialplan/yearplan/bird_special/ashx/edit.ashx?r=' + Math.random(),
                      { act: 'deleteRow', id: rowid },
                      function (data) {
                          alert('删除成功');
                      });
                tempArray.splice(index, 1);
                if (tempArray.length > 0) {
                    $scope.todo.items = tempArray;
                }
                else {
                    $scope.todo.items = [];
                }
            }
            //长度测试
            $scope.length = function () {
                //alert($scope.username);
            }
        });
        //GUID
        function newguid() {
            return ('xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx').replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : r & 0x3 | 0x8; return v.toString(16); });
        }
        //某月的天数
        function DayNumOfMonth(Year, Month) {
            return ((new Date(Year, Month, 0).getDate()));
        }
    </script>
</body>

</html>

css

 table {
            font-size: 0.7em;
        }

            table th {
                background-color: #c0c0c0;
            }

            table th, td {
                text-align: center;
                border: 1px solid gray;
            }

           table td input, table td textarea {
                width: 100%;
                height: 100%;
                border: none;
                background-color: none;
            }

                table td input:hover {
                    background-color: #EDEDED;
                }
            table th input{border:none;}
            .deletes {
                border-radius: 5px;
                border: 1px solid #ff6a00;
            }

            .deletes:hover {
                border: 2px solid #ff0000;
                background-color: #f00;
                color: white;
            }

服务器端:

<%@ WebHandler Language="C#" Class="edit" %>

using System;
using System.Web;
using Newtonsoft.Json;
using System.Web.SessionState;
using System.Text;
using System.Data;

public class edit : IHttpHandler, IRequiresSessionState
{
    xxx.Model.WJX_SPECIALPLAN_BIRD model = new xxx.Model.WJX_SPECIALPLAN_BIRD();
    xxx.BLL.WJX_SPECIALPLAN_BIRD bll = new xxx.BLL.WJX_SPECIALPLAN_BIRD();
    PageBase p = new PageBase();
    public void ProcessRequest(HttpContext context)
    {
        string act = context.Request.Params["act"];
        switch (act)
        {
            case "save":
                SaveOrUpdate(context);
                break;
            case "list":
                GetTodayList(context);
                break;
            case "deleteRow":
                DeleteRow(context);
                break;
            default:
                break;
        }
    }
    /// <summary>
    /// 逐条保存填写或更新填写
    /// </summary>
    /// <param name="context"></param>
    private void SaveOrUpdate(HttpContext context)
    {
        string temp = "{\"flag\":";
        context.Response.ContentType = "text/json";
        try
        {
            //获取数据
            model.ID = context.Request.Params["data[id]"];
            model.JGID = p.of_GetUser().ORGANIZATIONGID2;
            model.RAILWAYID = context.Request.Params["data[RAILWAYID]"];
            model.SECTIONID = context.Request.Params["data[SECTIONID]"];
            model.JGNAME = context.Request.Params["data[JGNAME]"];
            model.CARPERSON = context.Request.Params["data[CARPERSON]"];
            model.CARTIMES = context.Request.Params["data[CARTIMES]"];
            model.LOCATION = context.Request.Params["data[LOCATION]"];
            model.TODAYTEMP = p.ext_int(context.Request.Params["data[TODAYTEMP]"]);
            model.TODAYADD = p.ext_int(context.Request.Params["data[TODAYADD]"]);

            model.LEAVECOUNT = context.Request.Params["data[LEAVECOUNT]"];
            model.LEAVELOCATION = context.Request.Params["data[LEAVELOCATION]"];

            model.TOTAL1 = context.Request.Params["data[TOTAL1]"];
            model.TOTAL2 = context.Request.Params["data[TOTAL2]"];
            model.TOTAL3 = context.Request.Params["data[TOTAL3]"];
            model.TOTAL4 = context.Request.Params["data[TOTAL4]"];
            model.TOTAL5 = context.Request.Params["data[TOTAL5]"];
            model.TOTAL6 = context.Request.Params["data[TOTAL6]"];

            model.PLANJGNAME = context.Request.Params["data[PLANJGNAME]"];
            model.PLANCARPERSON = context.Request.Params["data[PLANCARPERSON]"];
            model.PLANCARTIMES = context.Request.Params["data[PLANCARTIMES]"];
            model.CREATETIME = p.ext_date(context.Request.Params["data[CREATETIME]"]);

            model.PLANID = context.Request.Params["data[planid]"];
            model.USERNAME = context.Request.Params["username"];
            model.TEL = context.Request.Params["tel"];

            Maticsoft.DBUtility.DbHelperOra.connectionString = p.getconfig("DB1");//调用其他数据库
            //判断是否存在
            if (bll.Exists(model.ID))//更新
            {
                Maticsoft.DBUtility.DbHelperOra.connectionString = p.getconfig("DB1");//调用其他数据库
                bll.Update(model);
            }
            else//添加
            {

                bll.Add(model);
            }
            temp += "true}";

        }
        catch (Exception ex)
        {
            context.Response.Write(temp + "false,\"msg\":\"" + ex.Message + "\"}");
            context.Response.End();
        }
        context.Response.Write(temp);
        context.Response.End();
    }

    /// <summary>
    /// 得到当天的填写记录
    /// </summary>
    /// <param name="context"></param>
    private void GetTodayList(HttpContext context)
    {
        string planid = context.Request.Params["planid"];//XX-ID
        DateTime createtime = Convert.ToDateTime(p.ext_date(context.Request.Params["createtime"]));//想得到哪日数据
        string jgid =XXX;//当前XX

        string datatime = createtime.Year + "/" + createtime.Month + "/" + createtime.Day;
        DataSet ds = bll.GetList(" 1=1 and planid='" + planid + "' and jgid='" + jgid +
            "' and createtime = to_date('" + datatime + "','yyyy-mm-dd') ");

        StringBuilder row = new StringBuilder();
        if (ds.Tables[0].Rows.Count > 0)
            row.Append("{\"flag\":true,\"datas\":[");
        else
            row.Append("{\"flag\":false,\"datas\":[");
        foreach (DataRow rows in ds.Tables[0].Rows)
        {
            row.Append("{\"id\":\"" + rows["id"] + "\",");
            row.Append("\"no\":\"\",");
            row.Append("\"RAILWAYID\":\"" + rows["RAILWAYID"] + "\",");
            row.Append("\"SECTIONID\":\"" + rows["SECTIONID"] + "\",");
            row.Append("\"JGNAME\":\"" + rows["JGNAME"] + "\",");

            row.Append("\"CARPERSON\":\"" + rows["CARPERSON"] + "\",");
            row.Append("\"CARTIMES\":\"" + rows["CARTIMES"] + "\",");
            row.Append("\"LOCATION\":\"" + rows["LOCATION"] + "\",");

            int dayCount = p.ext_int(rows["TODAYTEMP"]) + p.ext_int(rows["TODAYADD"]);
            row.Append("\"dayCount\":\"" + dayCount + "\",");
            row.Append("\"TODAYTEMP\":" + rows["TODAYTEMP"] + ",");
            row.Append("\"TODAYADD\":" + rows["TODAYADD"] + ",");

            row.Append("\"weekTotal\":\"\",");
            row.Append("\"weekCount\":\"\",");
            row.Append("\"weekDeul\":\"\",");
            row.Append("\"weekNaru\":\"\",");

            row.Append("\"monthTotal\":\"\",");
            row.Append("\"monthCount\":\"\",");
            row.Append("\"monthDeul\":\"\",");
            row.Append("\"monthNaru\":\"\",");

            row.Append("\"LEAVECOUNT\":\"" + rows["leaveCount"] + "\",");
            row.Append("\"LEAVELOCATION\":\"" + rows["leaveLocation"] + "\",");

            row.Append("\"TOTAL1\":\"" + rows["TOTAL1"] + "\",");
            row.Append("\"TOTAL2\":\"" + rows["TOTAL2"] + "\",");
            row.Append("\"TOTAL3\":\"" + rows["TOTAL3"] + "\",");
            row.Append("\"TOTAL4\":\"" + rows["TOTAL4"] + "\",");
            row.Append("\"TOTAL5\":\"" + rows["TOTAL5"] + "\",");
            row.Append("\"TOTAL6\":\"" + rows["TOTAL6"] + "\",");

            row.Append("\"PLANJGNAME\":\"" + rows["PLANJGNAME"] + "\",");
            row.Append("\"PLANCARPERSON\":\"" + rows["PLANCARPERSON"] + "\",");
            row.Append("\"PLANCARTIMES\":\"" + rows["PLANCARTIMES"] + "\",");
            row.Append("\"planid\":\"" + rows["planid"] + "\",");
            row.Append("\"CREATETIME\":\"" + rows["CREATETIME"] + "\"},");
        }
        if (ds.Tables[0].Rows.Count > 0)
        {
            context.Response.Write(row.ToString().Substring(0, row.ToString().Length - 1) + "],\"username\":\"" + ds.Tables[0].Rows[0]["username"] + "\",\"tel\":\"" +
                ds.Tables[0].Rows[0]["tel"] + "\"}");
            context.Response.ContentType = "text/json";
            context.Response.End();
        }
        else
        {
            context.Response.Write(row.ToString() + "]}");
            context.Response.ContentType = "text/json";
            context.Response.End();
        }
    }

    /// <summary>
    /// 删除一行数据
    /// </summary>
    /// <param name="context"></param>
    private void DeleteRow(HttpContext context)
    {
        string rowid = context.Request.Params["id"];

        if (bll.Exists(rowid))
        {

            bll.Delete(rowid);
        }
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}

后来新增了很多功能,比如合计
这里写图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值