项目背景:原来的报表都是C/S,动态生成的列数据,因为表结构是纵向的,但是综合报表需要横向展示,所以需要动态列的展示。不过C/S也不能满足需求了,现在公司要求做一版B/S结构的报表。因为公司工具用的还是VS2013,我用的MVC框架,前端就用了EasyUI。
C/S模式下用的DataTable 装载动态列,原代码不变,将DataTabel 转换 EasyUI 中DataGrid 对应的数据。
新建一个类
/// <summary>
/// EasyUI datagrid 动态数据
/// </summary>
public class EasyUIPageObject
{
/// <summary>
/// datagrid 对应data
/// </summary>
public object rows { get; set; }
/// <summary>
/// datagrid 对应总行数
/// </summary>
public int total { get; set; }
/// <summary>
/// datagrid 对应 columns 列
/// </summary>
public object columns { get; set; }
/// <summary>
/// 需要显示的统计行
/// </summary>
public string connect { get; set; }
}
EasyUI datagrid 的json格式包括名称必须保持一致。
前端代码,jquery
$.ajax({
url: '/Report/SubmitForm',
dataType: 'json',
type: 'post',
data: formdata,
success: function (data) {
if (data.total > 0) {
var columns = $.parseJSON(data.columns)
//因为我要对数据内容进行样式处理,所以添加了样式方法
$.each(columns, function (index, item) {
item.formatter = formatValue
})
var rows = $.parseJSON(data.rows)
//动态绑定列,注意列一定要用 []
$("#tt").datagrid({
singleSelect: true,
pagination: true,
pageNumber: 1,
pageSize: 20,
pageList: [20, 30, 50],
columns: [columns],
})
//因为有分页,所以数据单独绑定的
var dd = { total: data.total, rows: rows };
$("#tt").datagrid('loadData', dd)
}
else {
$("#tt").datagrid('loadData', { total: 0, rows: [] });
$.messager.alert("提示", "当前没有任何有效的数据。");
}
},
error: function (e) {
console.log(e)
}
})
//改变表格NG数据样式
function formatValue(value, row, index) {
if (value.indexOf("NG") > -1) {
if (value.indexOf("^") > -1) {
var v = value.split('^')[0];
if (v == ' ')
return '<span style="background:red;">' + v + '</span>';
else
return '<span style="color:red;">' + v + '</span>';
}
else {
return '<span style="color:red;">' + value + '</span>';
}
} else {
return value
}
以下是控制器代码
[HttpPost]
public JsonResult SubmitForm(string startTime, string endTime, string partNo, string type, string Text, string checkModel)
{
//该类是用来传递页面查询条件的
SelectModel model = new SelectModel { BeginTime = startTime, EndTime = endTime, PartNo = partNo, ModelType = type, Text = Text, CheckModel = checkModel };
//该方法是用来生成动态表格的,表格列名我都用的中文
DataTable dt = _bll.GetDataGrid(model);
EasyUIPageObject item = null;
if (dt != null && dt.Rows.Count > 0)
{
//该方法是通过DataTable生成EasyUI datagrid 的数据格式,等下下面单独列出
item = _bll.GetEasyUIDataGridData(dt, 1, 20, item);
item.total = dt.Rows.Count;
//将原始数据保存在Session中
Session["Table"] = dt;
}
else
{
if (checkModel.Equals("0"))
{
Session["Table"] = new DataTable();
}
}
if (item == null)
{
item = new EasyUIPageObject
{
total = 0,
rows = "[]",
columns = "[]"
};
}
return Json(item);
}
以下是DataTable数据转换EasyUI datagrid数据格式的方法
/// <summary>
/// 将DataTable 数据 转换EasyUI datagrid 数据列格式
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public EasyUIPageObject GetEasyUIDataGridColumns(DataTable dt)
{
EasyUIPageObject entity = new EasyUIPageObject();
entity.total = dt.Rows.Count;
StringBuilder sb = new StringBuilder();
sb.Append("[");
for (int i = 0; i < dt.Columns.Count; i++)
{
sb.Append("{").Append("\"field\":\"").Append(dt.Columns[i].ColumnName).Append("\",\"title\":\"").Append(dt.Columns[i].ColumnName).Append("\",\"width\":100,\"align\":\"center\"},");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("]");
entity.columns = sb.ToString();
return entity;
}
/// <summary>
/// 根据数据转换 EasyUI datagrid 的数据格式
/// </summary>
/// <param name="dt">原始数据</param>
/// <param name="pageNum">页码</param>
/// <param name="pageSize">页数</param>
/// <param name="entity">数据转换实体类</param>
/// <returns></returns>
public EasyUIPageObject GetEasyUIDataGridData(DataTable dt, int pageNum, int pageSize,EasyUIPageObject entity)
{
int minpage = (pageNum - 1) * pageSize;
int maxpage = pageNum * pageSize;
if (maxpage > dt.Rows.Count)
maxpage = dt.Rows.Count;
StringBuilder sb = new StringBuilder();
sb.Append("[");
for (int i = minpage; i < maxpage; i++)
{
sb.Append("{");
for (int j = 0; j < dt.Columns.Count; j++)
{
if (j == 0)
sb.AppendFormat("\"{0}\":\"{1}\",", dt.Columns[j].ColumnName, (i + 1));
else
sb.AppendFormat("\"{0}\":\"{1}\",", dt.Columns[j].ColumnName, dt.Rows[i][j]);
}
sb.Remove(sb.Length - 1, 1);
sb.Append("},");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("]");
entity.rows = sb.ToString();
return entity;
}
最后回归界面,当动态列和动态数据生成后,easyui 才会生成分页控件,所以我们需要在datagrid数据加载完成的事件中添加分页的方法。
$("#tt").datagrid({
onLoadSuccess: function (data) {
var pg = $('#tt').datagrid('getPager');
if (pg) {
$(pg).pagination({
showRefresh: false,
onSelectPage: function (pageNumber, pageSize) {
$.ajax({
url: '/Report/SelectPage',
datatype: 'json',
type: 'post',
data: { num: pageNumber, size: pageSize },
success: function (data) {
if (data.total == 0) {
$("#tt").datagrid('loadData', { total: 0, rows: [] });
$.messager.alert("提示", "当前没有任何有效数据。");
}
else {
var rr = $.parseJSON(data.rows);
$("#tt").datagrid('loadData', { total: data.total, rows: rr });
}
},
error: function (e) {
console.log(e)
}
})
},
onChangePageSize: function (pageSize) {
$.ajax({
url: '/Report/ChangePageSize',
datatype: 'json',
type: 'post',
data: { size: pageSize },
success: function (data) {
if (data.total == 0) {
$("#tt").datagrid('loadData', { total: 0, rows: [] });
$.messager.alert("提示", "当前没有任何有效数据。");
}
else {
var rr = $.parseJSON(data.rows);
$("#tt").datagrid('loadData', { total: data.total, rows: rr });
}
},
error: function (e) {
console.log(e)
}
})
}
})
全部完成,最后我发现一个问题,生成动态列和动态数据 后因为都是动态生成的会导致列的宽度和数据的宽度不一致,导致有部分列未显示,后来在百度中一个大神告诉一个方法,就是要修改jquery.easyui.min.js文件,搜索内容:[\.|\s],找到后改成以下内容:col.cellClass=_73d.cellClassPrefix+"-"+col.field.replace(/[\.|\s]/g,"-").replace(/./g,function($1){return $1.charCodeAt(0).toString(16);});
这个方法可以纠正动态列生成导致,列和数据的宽度不一致的问题。