741 lines
26 KiB
C#
741 lines
26 KiB
C#
|
using BLL;
|
|||
|
using Newtonsoft.Json.Linq;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Data;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace FineUIPro.Web.JDGL.SGManPower
|
|||
|
{
|
|||
|
public partial class ManPowerWorkGrid : PageBase
|
|||
|
{
|
|||
|
#region Page_Init
|
|||
|
|
|||
|
// 注意:动态创建的代码需要放置于Page_Init(不是Page_Load),这样每次构造页面时都会执行
|
|||
|
protected void Page_Init(object sender, EventArgs e)
|
|||
|
{
|
|||
|
InitGrid();
|
|||
|
}
|
|||
|
|
|||
|
public DataTable GridTable = new DataTable();
|
|||
|
|
|||
|
private void InitGrid()
|
|||
|
{
|
|||
|
FineUIPro.BoundField bf;
|
|||
|
FineUIPro.RenderField rf;
|
|||
|
FineUIPro.TextBox txTextBox;
|
|||
|
|
|||
|
// 设置Grid的编辑属性
|
|||
|
Grid1.AllowCellEditing = true;
|
|||
|
Grid1.ClicksToEdit = 1;
|
|||
|
Grid1.EnableAfterEditEvent = true;
|
|||
|
|
|||
|
UnitId = Request.Params["UnitId"];
|
|||
|
StartTime = Request.Params["StartTime"];
|
|||
|
EndTime = Request.Params["EndTime"];
|
|||
|
|
|||
|
GridTable.Columns.Add("Id");
|
|||
|
|
|||
|
// 添加隐藏列来存储额外的ID信息
|
|||
|
GridTable.Columns.Add("UnitId");
|
|||
|
GridTable.Columns.Add("WorkPostId");
|
|||
|
|
|||
|
ListItem[] list = new ListItem[4];
|
|||
|
list[0] = new ListItem("序号", "SerialNumber");
|
|||
|
list[1] = new ListItem("单位", "UnitName");
|
|||
|
list[2] = new ListItem("岗位", "WorkPostName");
|
|||
|
list[3] = new ListItem("累计", "TotalCount");
|
|||
|
|
|||
|
foreach (var item in list)
|
|||
|
{
|
|||
|
bf = new FineUIPro.BoundField();
|
|||
|
bf.ColumnID = item.Value;
|
|||
|
bf.DataField = item.Value;
|
|||
|
bf.HeaderText = item.Text;
|
|||
|
bf.HeaderTextAlign = TextAlign.Center;
|
|||
|
bf.TextAlign = TextAlign.Center;
|
|||
|
bf.Locked = true;
|
|||
|
Grid1.Columns.Add(bf);
|
|||
|
GridTable.Columns.Add(item.Value);
|
|||
|
}
|
|||
|
|
|||
|
// 动态获取日期范围
|
|||
|
DateTime startDate = Convert.ToDateTime(StartTime);
|
|||
|
DateTime endDate = Convert.ToDateTime(EndTime);
|
|||
|
var dateRange = Enumerable.Range(0, (endDate - startDate).Days + 1)
|
|||
|
.Select(i => startDate.AddDays(i))
|
|||
|
.ToList();
|
|||
|
|
|||
|
// 按年分组日期
|
|||
|
var groupedByYear = dateRange.GroupBy(d => d.Year)
|
|||
|
.OrderBy(g => g.Key)
|
|||
|
.ToList();
|
|||
|
|
|||
|
foreach (var yearGroup in groupedByYear)
|
|||
|
{
|
|||
|
GroupField yearGroupField = new GroupField();
|
|||
|
yearGroupField.HeaderText = $"{yearGroup.Key}年";
|
|||
|
yearGroupField.TextAlign = TextAlign.Center;
|
|||
|
|
|||
|
// 按月分组
|
|||
|
var groupedByMonth = yearGroup.GroupBy(d => d.Month)
|
|||
|
.OrderBy(g => g.Key)
|
|||
|
.ToList();
|
|||
|
|
|||
|
foreach (var monthGroup in groupedByMonth)
|
|||
|
{
|
|||
|
GroupField monthGroupField = new GroupField();
|
|||
|
monthGroupField.HeaderText = $"{monthGroup.Key}月";
|
|||
|
monthGroupField.TextAlign = TextAlign.Center;
|
|||
|
|
|||
|
// 添加具体日期的列
|
|||
|
foreach (var date in monthGroup.OrderBy(d => d))
|
|||
|
{
|
|||
|
bf = new FineUIPro.BoundField();
|
|||
|
bf.ColumnID = date.ToString("yyyy-MM-dd");
|
|||
|
bf.DataField = date.ToString("yyyy-MM-dd");
|
|||
|
bf.HeaderText = date.ToString("dd");
|
|||
|
bf.HeaderTextAlign = TextAlign.Center;
|
|||
|
bf.TextAlign = TextAlign.Center;
|
|||
|
monthGroupField.Columns.Add(bf);
|
|||
|
GridTable.Columns.Add(date.ToString("yyyy-MM-dd"));
|
|||
|
}
|
|||
|
|
|||
|
yearGroupField.Columns.Add(monthGroupField);
|
|||
|
}
|
|||
|
|
|||
|
Grid1.Columns.Add(yearGroupField);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
public string UnitId
|
|||
|
{
|
|||
|
get => (string)ViewState["UnitId"];
|
|||
|
set => ViewState["UnitId"] = value;
|
|||
|
}
|
|||
|
|
|||
|
public string StartTime
|
|||
|
{
|
|||
|
get => (string)ViewState["StartTime"];
|
|||
|
set => ViewState["StartTime"] = value;
|
|||
|
}
|
|||
|
|
|||
|
public string EndTime
|
|||
|
{
|
|||
|
get => (string)ViewState["EndTime"];
|
|||
|
set => ViewState["EndTime"] = value;
|
|||
|
}
|
|||
|
|
|||
|
protected void Page_Load(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!IsPostBack)
|
|||
|
{
|
|||
|
Funs.DropDownPageSize(this.ddlPageSize);
|
|||
|
// 设置Grid的PageSize与下拉框默认值一致
|
|||
|
Grid1.PageSize = Convert.ToInt32(ddlPageSize.SelectedValue);
|
|||
|
WorkPostService.InitWorkPostDropDownList(this.drpWorkPost, true); //岗位
|
|||
|
|
|||
|
// 绑定表格
|
|||
|
this.BindGrid();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#region 绑定数据
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 绑定数据
|
|||
|
/// </summary>
|
|||
|
private void BindGrid()
|
|||
|
{
|
|||
|
// 清空现有数据
|
|||
|
GridTable.Clear();
|
|||
|
// 重新添加列定义(保持列结构)
|
|||
|
if (GridTable.Columns.Count == 0)
|
|||
|
{
|
|||
|
GridTable.Columns.Add("Id");
|
|||
|
GridTable.Columns.Add("UnitId");
|
|||
|
GridTable.Columns.Add("WorkPostId");
|
|||
|
|
|||
|
// 添加动态日期列(这部分已经在InitGrid中定义了)
|
|||
|
ListItem[] list = new ListItem[4];
|
|||
|
list[0] = new ListItem("序号", "SerialNumber");
|
|||
|
list[1] = new ListItem("单位", "UnitName");
|
|||
|
list[2] = new ListItem("岗位", "WorkPostName");
|
|||
|
list[3] = new ListItem("累计", "TotalCount");
|
|||
|
foreach (var item in list)
|
|||
|
{
|
|||
|
GridTable.Columns.Add(item.Value);
|
|||
|
}
|
|||
|
|
|||
|
// 日期列会在InitGrid中添加,这里不需要重复添加
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// 清空行数据但保持列结构
|
|||
|
GridTable.Rows.Clear();
|
|||
|
}
|
|||
|
|
|||
|
// 使用原生SQL查询来提高性能,直接在数据库层面进行分组统计
|
|||
|
string strSql = @"
|
|||
|
SELECT UnitId, PostId, RecordDate, COUNT(1) as RecordCount
|
|||
|
FROM T_d_EmployInOutRecord
|
|||
|
WHERE ProjectId = @ProjectId
|
|||
|
AND RecordDate >= @StartDate
|
|||
|
AND RecordDate <= @EndDate";
|
|||
|
|
|||
|
var parameters = new List<System.Data.SqlClient.SqlParameter>
|
|||
|
{
|
|||
|
new System.Data.SqlClient.SqlParameter("@ProjectId", this.CurrUser.LoginProjectId),
|
|||
|
new System.Data.SqlClient.SqlParameter("@StartDate", Convert.ToDateTime(StartTime)),
|
|||
|
new System.Data.SqlClient.SqlParameter("@EndDate", Convert.ToDateTime(EndTime))
|
|||
|
};
|
|||
|
|
|||
|
if (UnitId != Const._Null)
|
|||
|
{
|
|||
|
strSql += " AND UnitId = @UnitId";
|
|||
|
parameters.Add(new System.Data.SqlClient.SqlParameter("@UnitId", UnitId));
|
|||
|
}
|
|||
|
|
|||
|
if (drpWorkPost.SelectedValue != Const._Null)
|
|||
|
{
|
|||
|
strSql += " AND PostId = @PostId";
|
|||
|
parameters.Add(new System.Data.SqlClient.SqlParameter("@PostId", drpWorkPost.SelectedValue));
|
|||
|
}
|
|||
|
|
|||
|
strSql += " GROUP BY UnitId, PostId, RecordDate";
|
|||
|
|
|||
|
// 执行查询获取分组数据
|
|||
|
var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray());
|
|||
|
|
|||
|
// 将数据转换为更易处理的格式
|
|||
|
var groupedData = new List<dynamic>();
|
|||
|
var groupedDict = new Dictionary<string, dynamic>();
|
|||
|
|
|||
|
foreach (System.Data.DataRow row in dt.Rows)
|
|||
|
{
|
|||
|
string key = $"{row["UnitId"]}_{row["PostId"]}";
|
|||
|
DateTime recordDate = Convert.ToDateTime(row["RecordDate"]);
|
|||
|
int count = Convert.ToInt32(row["RecordCount"]);
|
|||
|
|
|||
|
if (!groupedDict.ContainsKey(key))
|
|||
|
{
|
|||
|
dynamic group = new System.Dynamic.ExpandoObject();
|
|||
|
group.UnitId = row["UnitId"];
|
|||
|
group.PostId = row["PostId"];
|
|||
|
group.DailyCounts = new Dictionary<DateTime, int>();
|
|||
|
group.TotalCount = 0;
|
|||
|
groupedDict[key] = group;
|
|||
|
groupedData.Add(group);
|
|||
|
}
|
|||
|
|
|||
|
groupedDict[key].DailyCounts[recordDate] = count;
|
|||
|
groupedDict[key].TotalCount += count;
|
|||
|
}
|
|||
|
|
|||
|
Grid1.RecordCount = groupedData.Count();
|
|||
|
|
|||
|
// 分页处理
|
|||
|
var pagedData = groupedData.Skip(Grid1.PageSize * Grid1.PageIndex).Take(Grid1.PageSize).ToList();
|
|||
|
|
|||
|
// 只获取当前页需要的单位和岗位信息,避免加载全部数据
|
|||
|
var unitIds = pagedData.Where(x => x.UnitId != null).Select(x => x.UnitId.ToString()).Distinct().ToList();
|
|||
|
var postIds = pagedData.Where(x => x.PostId != null).Select(x => x.PostId.ToString()).Distinct().ToList();
|
|||
|
|
|||
|
var units = new Dictionary<string, string>();
|
|||
|
var workPosts = new Dictionary<string, string>();
|
|||
|
|
|||
|
if (unitIds.Any())
|
|||
|
{
|
|||
|
var unitQuery = from u in Funs.DB.Base_Unit
|
|||
|
where unitIds.Contains(u.UnitId)
|
|||
|
select new { u.UnitId, u.UnitName };
|
|||
|
foreach (var u in unitQuery)
|
|||
|
{
|
|||
|
units[u.UnitId] = u.UnitName;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (postIds.Any())
|
|||
|
{
|
|||
|
var postQuery = from p in Funs.DB.Base_WorkPost
|
|||
|
where postIds.Contains(p.WorkPostId)
|
|||
|
select new { p.WorkPostId, p.WorkPostName };
|
|||
|
foreach (var p in postQuery)
|
|||
|
{
|
|||
|
workPosts[p.WorkPostId] = p.WorkPostName;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
foreach (var group in pagedData)
|
|||
|
{
|
|||
|
DataRow row = GridTable.NewRow();
|
|||
|
|
|||
|
// 基本信息
|
|||
|
row["Id"] = Guid.NewGuid().ToString(); // 生成唯一ID用于行标识
|
|||
|
row["SerialNumber"] = GridTable.Rows.Count + 1; // 序号
|
|||
|
|
|||
|
// 单位信息
|
|||
|
string unitName = "";
|
|||
|
if (group.UnitId != null && units.ContainsKey(group.UnitId.ToString()))
|
|||
|
{
|
|||
|
unitName = units[group.UnitId.ToString()];
|
|||
|
}
|
|||
|
row["UnitName"] = unitName;
|
|||
|
row["UnitId"] = group.UnitId ?? (object)DBNull.Value;
|
|||
|
|
|||
|
// 岗位信息
|
|||
|
string workPostName = "";
|
|||
|
if (group.PostId != null && workPosts.ContainsKey(group.PostId.ToString()))
|
|||
|
{
|
|||
|
workPostName = workPosts[group.PostId.ToString()];
|
|||
|
}
|
|||
|
row["WorkPostName"] = workPostName;
|
|||
|
row["WorkPostId"] = group.PostId ?? (object)DBNull.Value;
|
|||
|
|
|||
|
// 每日数量填充
|
|||
|
foreach (var kvp in group.DailyCounts)
|
|||
|
{
|
|||
|
string dateColumnId = kvp.Key.ToString("yyyy-MM-dd");
|
|||
|
|
|||
|
// 确保列存在
|
|||
|
if (GridTable.Columns.Contains(dateColumnId))
|
|||
|
{
|
|||
|
row[dateColumnId] = kvp.Value;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 设置累计数量
|
|||
|
row["TotalCount"] = group.TotalCount;
|
|||
|
|
|||
|
GridTable.Rows.Add(row);
|
|||
|
}
|
|||
|
|
|||
|
Grid1.DataSource = GridTable;
|
|||
|
Grid1.DataBind();
|
|||
|
// 计算汇总数据
|
|||
|
OutputSummaryData();
|
|||
|
}
|
|||
|
|
|||
|
#region 计算合计
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 计算合计
|
|||
|
/// </summary>
|
|||
|
private void OutputSummaryData()
|
|||
|
{
|
|||
|
// 创建用于存储合计值的对象
|
|||
|
JObject summary = new JObject();
|
|||
|
|
|||
|
// 设置固定列的合计值
|
|||
|
summary.Add("UnitName", "合计");
|
|||
|
|
|||
|
// 计算TotalCount列的合计值
|
|||
|
int totalCountSum = 0;
|
|||
|
foreach (DataRow row in GridTable.Rows)
|
|||
|
{
|
|||
|
if (row["TotalCount"] != DBNull.Value && row["TotalCount"] != null)
|
|||
|
{
|
|||
|
int value;
|
|||
|
if (int.TryParse(row["TotalCount"].ToString(), out value))
|
|||
|
{
|
|||
|
totalCountSum += value;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
summary.Add("TotalCount", totalCountSum.ToString());
|
|||
|
|
|||
|
// 计算日期列的合计值
|
|||
|
foreach (DataColumn column in GridTable.Columns)
|
|||
|
{
|
|||
|
// 检查是否为日期列(格式为 yyyy-MM-dd)
|
|||
|
DateTime date;
|
|||
|
if (DateTime.TryParseExact(column.ColumnName, "yyyy-MM-dd", null,
|
|||
|
System.Globalization.DateTimeStyles.None, out date))
|
|||
|
{
|
|||
|
// 计算该列的合计值
|
|||
|
int columnSum = 0;
|
|||
|
foreach (DataRow row in GridTable.Rows)
|
|||
|
{
|
|||
|
if (row[column.ColumnName] != DBNull.Value && row[column.ColumnName] != null)
|
|||
|
{
|
|||
|
int value;
|
|||
|
if (int.TryParse(row[column.ColumnName].ToString(), out value))
|
|||
|
{
|
|||
|
columnSum += value;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
summary.Add(column.ColumnName, columnSum.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 设置汇总数据
|
|||
|
Grid1.SummaryData = summary;
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region GV 数据操作
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 分页
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
protected void Grid1_PageIndexChange(object sender, GridPageEventArgs e)
|
|||
|
{
|
|||
|
this.Grid1.PageIndex = e.NewPageIndex;
|
|||
|
this.BindGrid();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 排序
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
protected void Grid1_Sort(object sender, GridSortEventArgs e)
|
|||
|
{
|
|||
|
this.Grid1.SortDirection = e.SortDirection;
|
|||
|
this.Grid1.SortField = e.SortField;
|
|||
|
this.BindGrid();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 分页显示条数下拉框
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
|
|||
|
{
|
|||
|
Grid1.PageSize = Convert.ToInt32(ddlPageSize.SelectedValue);
|
|||
|
this.BindGrid();
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 数据查询
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 查询
|
|||
|
/// </summary>
|
|||
|
/// <param name="button"></param>
|
|||
|
/// <returns></returns>
|
|||
|
protected void btnQuery_OnClick(object sender, EventArgs e)
|
|||
|
{
|
|||
|
BindGrid();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 统计图表
|
|||
|
/// </summary>
|
|||
|
/// <param name="button"></param>
|
|||
|
/// <returns></returns>
|
|||
|
protected void btnGetChart_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (!string.IsNullOrEmpty(UnitId) && !string.IsNullOrEmpty(StartTime) && !string.IsNullOrEmpty(EndTime))
|
|||
|
{
|
|||
|
// 构建基础URL参数
|
|||
|
string urlParams = string.Format("UnitId={0}&StartTime={1}&EndTime={2}", UnitId, StartTime, EndTime);
|
|||
|
|
|||
|
// 添加岗位参数(如果已选择)
|
|||
|
if (drpWorkPost.SelectedValue != Const._Null && !string.IsNullOrEmpty(drpWorkPost.SelectedValue))
|
|||
|
{
|
|||
|
urlParams += "&WorkPostId=" + drpWorkPost.SelectedValue;
|
|||
|
}
|
|||
|
|
|||
|
PageContext.RegisterStartupScript(
|
|||
|
Window2.GetShowReference(string.Format("ManPowerWorkChart.aspx?{0}", urlParams), "人力计划图表"));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ShowNotify("请先选确保时间范围已设置", MessageBoxIcon.Warning);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
#region 关闭弹出窗
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 关闭弹出窗
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
protected void Window1_Close(object sender, WindowCloseEventArgs e)
|
|||
|
{
|
|||
|
BindGrid();
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 导出按钮
|
|||
|
|
|||
|
/// 导出按钮
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
protected void btnOut_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
Response.ClearContent();
|
|||
|
string filename = Funs.GetNewFileName();
|
|||
|
Response.AddHeader("content-disposition",
|
|||
|
"attachment; filename=" +
|
|||
|
System.Web.HttpUtility.UrlEncode("现场考勤人力表" + filename, System.Text.Encoding.UTF8) + ".xls");
|
|||
|
Response.ContentType = "application/excel";
|
|||
|
Response.ContentEncoding = System.Text.Encoding.UTF8;
|
|||
|
this.BindGrid();
|
|||
|
// 生成并写入Excel表格
|
|||
|
Response.Write(GetGridTableHtml(Grid1));
|
|||
|
Response.End();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 导出方法 - 支持多级表头
|
|||
|
/// </summary>
|
|||
|
/// <param name="grid"></param>
|
|||
|
/// <returns></returns>
|
|||
|
/// <summary>
|
|||
|
private string GetGridTableHtml(Grid grid)
|
|||
|
{
|
|||
|
StringBuilder sb = new StringBuilder();
|
|||
|
|
|||
|
MultiHeaderTable mht = new MultiHeaderTable();
|
|||
|
mht.ResolveMultiHeaderTable(grid.Columns);
|
|||
|
|
|||
|
sb.Append("<meta http-equiv=\"Content-Type\" content=\"application/vnd.ms-excel;charset=utf-8\"/>");
|
|||
|
sb.Append("<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">");
|
|||
|
|
|||
|
// 生成多级表头
|
|||
|
foreach (List<object[]> rows in mht.MultiTable)
|
|||
|
{
|
|||
|
sb.Append("<tr>");
|
|||
|
foreach (object[] cell in rows)
|
|||
|
{
|
|||
|
int rowspan = 1;
|
|||
|
int colspan = Convert.ToInt32(cell[1]);
|
|||
|
GridColumn column = cell[2] as GridColumn;
|
|||
|
|
|||
|
// 对于锁定列(固定列),确保rowspan为3
|
|||
|
if (column.Locked)
|
|||
|
{
|
|||
|
rowspan = 3;
|
|||
|
}
|
|||
|
|
|||
|
sb.AppendFormat("<th{0}{1}{2}>{3}</th>",
|
|||
|
" rowspan=\"" + rowspan + "\"",
|
|||
|
colspan != 1 ? " colspan=\"" + colspan + "\"" : "",
|
|||
|
colspan != 1 ? " style=\"text-align:center;\"" : "",
|
|||
|
column.HeaderText);
|
|||
|
}
|
|||
|
|
|||
|
sb.Append("</tr>");
|
|||
|
}
|
|||
|
|
|||
|
// 生成数据行
|
|||
|
foreach (GridRow row in grid.Rows)
|
|||
|
{
|
|||
|
sb.Append("<tr>");
|
|||
|
|
|||
|
foreach (GridColumn column in mht.Columns)
|
|||
|
{
|
|||
|
string html = row.Values[column.ColumnIndex].ToString();
|
|||
|
|
|||
|
// 特殊处理固定列
|
|||
|
if (column.ColumnID == "UnitName")
|
|||
|
{
|
|||
|
html = row.Values[column.ColumnIndex].ToString();
|
|||
|
}
|
|||
|
else if (column.ColumnID == "WorkPostName")
|
|||
|
{
|
|||
|
html = row.Values[column.ColumnIndex].ToString();
|
|||
|
}
|
|||
|
else if (column.ColumnID == "TotalCount")
|
|||
|
{
|
|||
|
html = row.Values[column.ColumnIndex].ToString();
|
|||
|
}
|
|||
|
// 处理日期列(格式为 yyyy-MM-dd)
|
|||
|
else if (DateTime.TryParseExact(column.ColumnID, "yyyy-MM-dd", null,
|
|||
|
System.Globalization.DateTimeStyles.None, out _))
|
|||
|
{
|
|||
|
html = row.Values[column.ColumnIndex].ToString();
|
|||
|
}
|
|||
|
|
|||
|
sb.AppendFormat("<td>{0}</td>", html);
|
|||
|
}
|
|||
|
|
|||
|
sb.Append("</tr>");
|
|||
|
}
|
|||
|
|
|||
|
// 添加合计行
|
|||
|
if (grid.SummaryData != null)
|
|||
|
{
|
|||
|
sb.Append("<tr style=\"font-weight:bold;\">");
|
|||
|
|
|||
|
foreach (GridColumn column in mht.Columns)
|
|||
|
{
|
|||
|
string summaryValue = "";
|
|||
|
// 检查SummaryData中是否有该列的合计值
|
|||
|
if (grid.SummaryData.Properties().Any(p => p.Name == column.ColumnID))
|
|||
|
{
|
|||
|
var property = grid.SummaryData.Properties().FirstOrDefault(p => p.Name == column.ColumnID);
|
|||
|
if (property != null)
|
|||
|
{
|
|||
|
summaryValue = property.Value.ToString();
|
|||
|
}
|
|||
|
}
|
|||
|
else if (column.ColumnID == "UnitName")
|
|||
|
{
|
|||
|
summaryValue = "合计";
|
|||
|
}
|
|||
|
|
|||
|
sb.AppendFormat("<td>{0}</td>", summaryValue);
|
|||
|
}
|
|||
|
|
|||
|
sb.Append("</tr>");
|
|||
|
}
|
|||
|
|
|||
|
sb.Append("</table>");
|
|||
|
|
|||
|
return sb.ToString();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#region 多表头处理
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 处理多表头的类
|
|||
|
/// </summary>
|
|||
|
public class MultiHeaderTable
|
|||
|
{
|
|||
|
// 包含 rowspan,colspan 的多表头,方便生成 HTML 的 table 标签
|
|||
|
public List<List<object[]>> MultiTable = new List<List<object[]>>();
|
|||
|
|
|||
|
// 最终渲染的列数组
|
|||
|
public List<GridColumn> Columns = new List<GridColumn>();
|
|||
|
|
|||
|
public void ResolveMultiHeaderTable(GridColumnCollection columns)
|
|||
|
{
|
|||
|
List<object[]> row = new List<object[]>();
|
|||
|
foreach (GridColumn column in columns)
|
|||
|
{
|
|||
|
object[] cell = new object[4];
|
|||
|
cell[0] = 1; // rowspan
|
|||
|
cell[1] = 1; // colspan
|
|||
|
cell[2] = column;
|
|||
|
cell[3] = null;
|
|||
|
|
|||
|
row.Add(cell);
|
|||
|
}
|
|||
|
|
|||
|
ResolveMultiTable(row, 0);
|
|||
|
ResolveColumns(row);
|
|||
|
}
|
|||
|
|
|||
|
private void ResolveColumns(List<object[]> row)
|
|||
|
{
|
|||
|
foreach (object[] cell in row)
|
|||
|
{
|
|||
|
GroupField groupField = cell[2] as GroupField;
|
|||
|
if (groupField != null && groupField.Columns.Count > 0)
|
|||
|
{
|
|||
|
List<object[]> subrow = new List<object[]>();
|
|||
|
foreach (GridColumn column in groupField.Columns)
|
|||
|
{
|
|||
|
subrow.Add(new object[]
|
|||
|
{
|
|||
|
1,
|
|||
|
1,
|
|||
|
column,
|
|||
|
groupField
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
ResolveColumns(subrow);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Columns.Add(cell[2] as GridColumn);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void ResolveMultiTable(List<object[]> row, int level)
|
|||
|
{
|
|||
|
List<object[]> nextrow = new List<object[]>();
|
|||
|
|
|||
|
foreach (object[] cell in row)
|
|||
|
{
|
|||
|
GroupField groupField = cell[2] as GroupField;
|
|||
|
if (groupField != null && groupField.Columns.Count > 0)
|
|||
|
{
|
|||
|
// 如果当前列包含子列,则更改当前列的 colspan,以及增加父列(向上递归)的colspan
|
|||
|
cell[1] = Convert.ToInt32(groupField.Columns.Count);
|
|||
|
PlusColspan(level - 1, cell[3] as GridColumn, groupField.Columns.Count - 1);
|
|||
|
|
|||
|
foreach (GridColumn column in groupField.Columns)
|
|||
|
{
|
|||
|
nextrow.Add(new object[]
|
|||
|
{
|
|||
|
1,
|
|||
|
1,
|
|||
|
column,
|
|||
|
groupField
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// 如果当前列不包含子列,但不是最末级列(不是叶子节点),则增加rowspan
|
|||
|
if (level > 0)
|
|||
|
{
|
|||
|
cell[0] = level + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
MultiTable.Add(row);
|
|||
|
|
|||
|
if (nextrow.Count > 0)
|
|||
|
{
|
|||
|
ResolveMultiTable(nextrow, level + 1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void PlusColspan(int level, GridColumn column, int colspan)
|
|||
|
{
|
|||
|
if (level < 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
foreach (List<object[]> rows in MultiTable)
|
|||
|
{
|
|||
|
foreach (object[] cells in rows)
|
|||
|
{
|
|||
|
if (cells[2] == column)
|
|||
|
{
|
|||
|
cells[1] = Convert.ToInt32(cells[1]) + colspan;
|
|||
|
|
|||
|
PlusColspan(level - 1, cells[3] as GridColumn, colspan);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
}
|
|||
|
}
|