最近公司开发的EMIS系统有个模块需要按excel格式写,原先有个estartable插件,我们经理写的,在原来的模块上面很好用,由于我水平有限,我在短期内不能清晰的修改或扩展它,最近掌握了angularJS,突发奇想,自己写了这套,没有写的太高深,但效果很满意哦。,废话、又是废话一堆,那么咱们上截图看看啥样的效果吧:
理想的样子、也是最终的效果
有点脑残了,光把优势写在图片上了,忘记拷贝到这里了。…..
简单罗列使用优势:
外观:
1、简单、美丽、看着就舒服…..醉了
操作:
1、新增一行,方便快捷,缺点:暂时不能在指定位置插入一行,需要优化功能
2、删除按钮:每行最前方有删除按钮,根据本行索引自动删除,同时也会传入本行id,会触发到数据库同步删除数据
3、保存:一行一个对象,存在json数据,逐行存储方式,避免服务器压力
4、强大的自动计算:可根据需要指定某些单元格的计算结果显示在某个单元格内,目前适用于本行内,不适用于异行操作
5、强大的编辑功能:随时随地,点谁编辑谁,即编即存,这全基于angular的双向数据绑定功能,不多解释。
6、自动显示序号功能,无需写代码,自己会展示。
…..
时间原因,不多解析;先上一部分代码看看喽
<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)'>xbutton>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;
}
}
///
/// 逐条保存填写或更新填写
///
/// "context">
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();
}
///
/// 得到当天的填写记录
///
/// "context">
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();
}
}
///
/// 删除一行数据
///
/// "context">
private void DeleteRow(HttpContext context)
{
string rowid = context.Request.Params["id"];
if (bll.Exists(rowid))
{
bll.Delete(rowid);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}