Files
2026-07-02 10:11:39 +00:00

845 lines
38 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using Lskj.Business;
using Lskj.Business.Impl;
using Lskj.Control;
using Lskj.Control.Model;
using Lskj.Core;
using Lskj.Data;
using Lskj.Model;
using Lskj.PubModuleExport.Model;
using Lskj.Util;
using OfficeOpenXml;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace Lskj.PubModuleExport
{
public partial class FrmMain : BaseForm
{
#region 私有变量
/// <summary>
/// 主键
/// </summary>
private string ParmaryKey;
/// <summary>
/// 左侧树数据
/// </summary>
private DataRow LeftRowObj;
/// <summary>
/// 左侧树主键关联右侧数据字段
/// </summary>
private string ParentUnionField;
/// <summary>
/// 左侧树配置字段
/// </summary>
private string LeftField;
#endregion
#region 公有变量
/// <summary>
/// 共有入口参数
/// </summary>
public DynamicModuleDetailModel Model;
/// <summary>
/// 主表数据类
/// </summary>
public ModuleModel SysModel;
/// <summary>
/// 自定义查询条件
/// </summary>
public MyControl SearchObj { get; private set; }
#endregion
/// <summary>
/// 构造方法
/// </summary>
public FrmMain(DynamicModuleDetailModel model = null)
{
InitializeComponent();
this.Model = model != null ? model : null;
}
/// <summary>
/// 窗体加载时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
InitControl();
InitEvent();
}
/// <summary>
/// 初始化事件绑定
/// </summary>
private void InitEvent()
{
this.splitMainContainer.SplitterPositionChanged += OnSplitMainContainerPositionChanged;
this.splitRightContainer.SplitterPositionChanged += OnSplitMainContainerPositionChanged;
}
/// <summary>
/// 设置分割条位置
/// </summary>
private void InitlizeSpiltLocation()
{
try
{
string splitMainWidth = IniHelper.Read(string.Format("PubModuleExport_SplitMain_{0}", this.Model.ModuleCode));//通过Key获取Value值
if (!string.IsNullOrEmpty(splitMainWidth))
{
this.splitMainContainer.SplitterPosition = Convert.ToInt32(splitMainWidth);
}
string splitRightWidth = IniHelper.Read(string.Format("PubModuleExport_SplitRight_{0}", this.Model.ModuleCode));//通过Key获取Value值
if (!string.IsNullOrEmpty(splitRightWidth))
{
this.splitRightContainer.SplitterPosition = Convert.ToInt32(splitRightWidth);
}
}
catch (Exception ex)
{
MessageUtil.Show(ex.Message);
}
}
/// <summary>
/// 初始化控件
/// </summary>
private void InitControl()
{
WaitForm.ShowForm();
try
{
this.Model.Privilege = this.Model.Privilege.Equals("3") ? "1" : Model.ModuleId > 0 ? BaseImpl.GetUserPurviewsByMenuId(Model.ModuleId + "") + "" : BaseImpl.GetUserPurviewsByMenuCode(Model.ModuleCode) + "";// 权限(1.有操作权限.0.无权限.2.只读权限.3.右键配置权限全部开放)
DataRow modelRow = MainImpl.GetSystemdllTab(this.Model.ModuleCode);//获取单个模块信息
if (modelRow == null)
{
MessageUtil.Show("模块编号[" + this.Model.ModuleCode + "],配置错误!\r\n该模块信息未找到!");
return;
}
this.ParmaryKey = BaseImpl.GetBasePrimaryKey(this.Model.ModuleCode);//获取主键
this.SysModel = new ModuleModel(modelRow);//系统模块实体对象
switch (this.SysModel.MenuType)
{
case 1:
case 4://左侧为树节点
this.treeLeft.Visible = true;
//this.ModuleGridObj.LeftTreeViewEx = this.treeLeft;
this.InitlizeSpiltLocation();//设置分割条位置
this.treeLeft.TreeInhibitSort = this.SysModel.TreeInhibitSort;
this.SetLeftTreeView();//设置左侧树数据
if (this.SysModel.IsHideTreeViewBoxs)
{
this.treeLeft.TreeView.CheckBoxes = false;
}
break;
//case 2:
//case 5: // 左侧为表格
// this.gridLeft.Visible = true;
// this.treeLeft.Visible = false;
// this.ModuleGridObj.LeftGridEx = this.gridLeft;
// this.SetLeftGridView();
// if (this.SysModel.LeftGridIsCheck == 1 && !this.SysModel.IsTreeTable)
// {
// GridDragGrid.GridAddCheckBox(this.gridLeft.GridView);
// }
// break;
case 3://左侧为空
default:
this.splitMainContainer.PanelVisibility = SplitPanelVisibility.Panel2;
break;
}
//构建右侧表格
DataTable _gridColumns = BaseModuleImpl.GetBaseGridColumns(this.SysModel.ModeCode);
this.gcMain.SetReadOnlyColumns(_gridColumns);
this.gridBottom.SetReadOnlyColumns(_gridColumns);
//设置上方条件
this.pl_top.Controls.Clear();
DataTable queryTable = BaseModuleImpl.GetCustomQueryFields(this.SysModel.CondKey);//加载自定义配置字段
this.SearchObj = new MyControl(this.SysModel.MenuSql, this.gcMain, this.treeLeft);
this.SearchObj.ParentUnionField = this.ParentUnionField;
this.pl_top.Height = 0;
this.pl_top.Height = this.SearchObj.InitSearchControl(queryTable, this.pl_top);
//右侧表格双击
this.gcMain.GridView.DoubleClick += GcMain_DoubleClick;
this.gridBottom.GridView.DoubleClick += GridBottom_DoubleClick;
//下方按钮
this.btnExport.Click += BtnExport_Click;
this.btnDelete.Click += BtnDelete_Click;
this.InitlizeSpiltLocation();//设置分割条位置
}
catch (Exception)
{
}
WaitForm.HideForm();
}
private void BtnDelete_Click(object sender, EventArgs e)
{
DataTable table = this.gridBottom.GridControl.DataSourceTable();
if (table == null) return;
int[] rows = this.gridBottom.GridView.GetSelectedRows();
if (rows.Length < 1)
{
GridBottom_DoubleClick(null,null);
return;
}
ArrayList localDeletes = new ArrayList();
foreach (int rowid in rows)
{
localDeletes.Add(rowid);
}
// 删除选中且未保存的数据
for (int i = localDeletes.Count - 1; i >= 0; i--)
{
this.gridBottom.GridView.DeleteRow((int)localDeletes[i]);
}
}
/// <summary>
/// 导出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnExport_Click(object sender, EventArgs e)
{
DataTable dataTable = this.gridBottom.GridControl.DataSource as DataTable;
if (dataTable != null && dataTable.Rows.Count > 0)
{
if (!dataTable.Columns.Contains("DllFileName")) return;
SaveFileDialog dialog = new SaveFileDialog();
dialog.Title = "导出";
String suffix = ".xlsx" ;
dialog.FileName = this.SysModel.MenuText + DateTime.Now.ToString(SystemInfo.Instance.ExportFileDateFormat) + suffix;
dialog.Filter = "Excel文件(*.xlsx)|*.xlsx|PDF文件|*.PDF|RTF文件|*.RTF|HTML文件|*.html";
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
//清空临时文件
PubUtil.ClearFilesInDirectory(PubUtil.ExportFilePath);
string fileExt = Path.GetExtension(dialog.FileName).ToLower();
int i = 1;
List<string> Paths = new List<string>();
foreach (DataRow itemRow in dataTable.Rows)
{
string Path =PubUtil.ExportFilePath + i + ",";
i++;
if (string.IsNullOrWhiteSpace(itemRow["DllFileName"] + "") || string.IsNullOrWhiteSpace(itemRow["PurviewId"] + "")) continue;
if ((itemRow["DllFileName"] + "").Equals("Lskj.PubBill.dll", StringComparison.OrdinalIgnoreCase))
{
//单据
string moduleCode = itemRow["PurviewId"] + "";
DataRow modelRow = BillImpl.GetBillInfo(moduleCode);//获取单个模块信息
if (modelRow != null)
{
BillModel billModel = new BillModel(modelRow);
//主表控件
DataTable controls = BaseModuleImpl.GetControlLocation(billModel.FormKey, moduleCode);
GridControlEx gridControlExMain = new GridControlEx();
DataTable MasterData = BaseImpl.GetDataTableResult(billModel.MasterSql);//主表数据源
this.ReplaceAndRemoveUnmatchedColumns(MasterData, controls);
gridControlExMain.GridControl.DataSource = MasterData;
string sheetName = Path + billModel.TypeName + fileExt;
Paths.Add(sheetName);
gridControlExMain.GridControl.ExportGridToExcel(sheetName, gridControlExMain.GridView.OptionsView.AllowCellMerge);
//主表明细
DataTable detailColumns = BillImpl.GetDetailColumns(moduleCode);//初始化单据明细列
GridControlEx controlEx = new GridControlEx();
controlEx.SetReadOnlyColumns(detailColumns);
controlEx.GridControl.DataSource = BaseImpl.GetDataTableResult(billModel.DetailSql);
string DataSheetName = Path + billModel.TypeName + "-明细" + fileExt;
Paths.Add(DataSheetName);
controlEx.GridControl.ExportGridToExcel(DataSheetName, controlEx.GridView.OptionsView.AllowCellMerge);
}
}
else
{
//单表
string moduleCode = itemRow["PurviewId"] + "";
DataRow modelRow = MainImpl.GetSystemdllTab(moduleCode);//获取单个模块信息
if (modelRow != null)
{
ModuleModel module= new ModuleModel(modelRow);//系统模块实体对象
DataTable gridColumns = BaseModuleImpl.GetBaseGridColumns(moduleCode);//主表列
GridControlEx gridControlExMain = new GridControlEx();
gridControlExMain.SetReadOnlyColumns(gridColumns);
gridControlExMain.GridControl.DataSource = BaseImpl.GetDataTableResult(module.MenuSql);
string sheetName = Path + module.MenuText+ fileExt;
Paths.Add(sheetName);
gridControlExMain.GridControl.ExportGridToExcel(sheetName, gridControlExMain.GridView.OptionsView.AllowCellMerge);//GridCustomColumnStruct.BaseMainGridView + this.SysModel.FormKey
List<GridDetailModel> details = this.GetDetails(moduleCode);//明细
int j = 1;
foreach (GridDetailModel item in details)
{
string number = "(" + j + ")";
j++;
if (item.IsReadOnly&&!string.IsNullOrWhiteSpace(item.DetailSql))
{
//明细为动态sql
GridControlEx controlEx = new GridControlEx();
controlEx.GridControl.DataSource = BaseImpl.GetDataTableResult(item.DetailSql);
string DataSheetName = Path + module.MenuText + "-" + item.DetailName+ number + fileExt;
Paths.Add(DataSheetName);
controlEx.GridControl.ExportGridToExcel(DataSheetName, controlEx.GridView.OptionsView.AllowCellMerge);
}
else
{
//明细为模块
if (string.IsNullOrWhiteSpace(item.UnionModule)) continue;
DataRow detaModuleRow = MainImpl.GetSystemdllTab(item.UnionModule);//获取单个模块信息
if (detaModuleRow != null)
{
ModuleModel detaModule = new ModuleModel(detaModuleRow);//系统模块实体对象
GridControlEx controlEx = new GridControlEx();
DataTable detaGridColumns = BaseModuleImpl.GetBaseGridColumns(item.UnionModule);//主表列
controlEx.SetReadOnlyColumns(detaGridColumns);
controlEx.GridControl.DataSource = BaseImpl.GetDataTableResult(detaModule.MenuSql);
string DataSheetName = Path + module.MenuText + "-" + item.DetailName+ number + fileExt;
Paths.Add(DataSheetName);
controlEx.GridControl.ExportGridToExcel(DataSheetName, controlEx.GridView.OptionsView.AllowCellMerge);
}
}
}
}
}
}
//把文件夹中多个文件合并
this.MergeExcel_EPPlus(Paths.ToArray(), dialog.FileName);
}
}
}
/// <summary>
/// 合并多XLSX文件(最终稳定版:仅复制数据+解决枚举异常)
/// </summary>
/// <param name="sourceFilePaths">待合并文件路径列表</param>
/// <param name="outputFilePath">合并后输出路径</param>
public void MergeExcel_EPPlus(string[] sourceFilePaths, string outputFilePath)
{
// 基础参数校验
if (sourceFilePaths == null || sourceFilePaths.Length == 0)
throw new ArgumentNullException(nameof(sourceFilePaths), "待合并文件列表不能为空");
if (string.IsNullOrEmpty(outputFilePath))
throw new ArgumentNullException(nameof(outputFilePath), "输出文件路径不能为空");
// 创建目标Excel包
using (ExcelPackage targetPackage = new ExcelPackage())
{
try
{
// 删除EPPlus默认创建的空工作表
if (targetPackage.Workbook.Worksheets.Count > 0)
{
targetPackage.Workbook.Worksheets.Delete(0);
}
// 遍历所有待合并的源文件
foreach (var filePath in sourceFilePaths)
{
// 跳过无效文件(不存在/非xlsx)
if (!File.Exists(filePath) || Path.GetExtension(filePath).ToLower() != ".xlsx")
{
XtraMessageBox.Show($"跳过无效文件:{filePath}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
continue;
}
// 读取源Excel文件(使用FileStream避免文件占用)
using (var sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (ExcelPackage sourcePackage = new ExcelPackage(sourceStream))
{
// ========== 核心修复:先将工作表名称存入列表,避免枚举时修改集合 ==========
// 步骤1:提取所有源工作表名称到临时列表
List<string> sourceSheetNames = new List<string>();
foreach (ExcelWorksheet sheet in sourcePackage.Workbook.Worksheets)
{
sourceSheetNames.Add(sheet.Name);
}
// 步骤2:遍历名称列表(而非直接遍历工作表集合)
foreach (string sheetName in sourceSheetNames)
{
// 获取源工作表(通过名称,而非枚举)
ExcelWorksheet sourceSheet = sourcePackage.Workbook.Worksheets[sheetName];
// 跳过空工作表(无数据维度)
if (sourceSheet == null || sourceSheet.Dimension == null)
{
continue;
}
//过滤隐藏
if (sourceSheet.Hidden != eWorkSheetHidden.Visible)
{
continue;
}
// 步骤3:源工作簿内复制临时表(2参数Copy方法)
string tempSheetName = $"Temp_{Guid.NewGuid().ToString("N").Substring(0, 8)}";
// 先检查临时表名是否重复(防呆)
if (sourcePackage.Workbook.Worksheets[tempSheetName] != null)
{
tempSheetName += $"_{DateTime.Now.Ticks}";
}
ExcelWorksheet tempSheet = sourcePackage.Workbook.Worksheets.Copy(sheetName, tempSheetName);
// 步骤4:创建目标工作表(处理名称重复)
string baseTargetName = Path.GetFileNameWithoutExtension(filePath);
string targetSheetName = baseTargetName;
int index = 1;
// 检查目标工作簿是否已有同名工作表
while (targetPackage.Workbook.Worksheets.Any(ws => ws.Name == targetSheetName))
{
targetSheetName = $"{baseTargetName}_{index++}";
}
ExcelWorksheet targetSheet = targetPackage.Workbook.Worksheets.Add(targetSheetName);
// 步骤5:安全复制数据(仅复制值+列宽+行高,无样式)
SafeCopyWorksheetContent(tempSheet, targetSheet);
// 步骤6:删除源工作簿内的临时表(此时已不在枚举过程中,无异常)
if (sourcePackage.Workbook.Worksheets[tempSheetName] != null)
{
sourcePackage.Workbook.Worksheets.Delete(tempSheetName);
}
}
}
// 每处理一个文件清理一次内存,避免堆积
GC.Collect();
GC.WaitForPendingFinalizers();
}
// 保存合并后的文件(覆盖已存在的文件)
FileInfo outputFileInfo = new FileInfo(outputFilePath);
if (outputFileInfo.Exists)
{
outputFileInfo.Delete(); // 删除已存在的文件,避免保存失败
}
targetPackage.SaveAs(outputFileInfo);
XtraMessageBox.Show($"Excel文件合并完成!\n输出路径:{outputFilePath}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
throw new Exception($"合并Excel失败:{ex.Message}", ex);
}
}
}
/// <summary>
/// 安全复制工作表内容(仅复制数据+列宽+行高,无样式,无越界异常)
/// </summary>
/// <param name="sourceSheet">源工作表</param>
/// <param name="targetSheet">目标工作表</param>
private void SafeCopyWorksheetContent(ExcelWorksheet sourceSheet, ExcelWorksheet targetSheet)
{
// 获取源工作表的有效数据范围
int startRow = sourceSheet.Dimension.Start.Row;
int startCol = sourceSheet.Dimension.Start.Column;
int endRow = sourceSheet.Dimension.End.Row;
int endCol = sourceSheet.Dimension.End.Column;
// 1. 批量复制单元格值(核心:仅复制数据,无样式操作)
targetSheet.Cells[startRow, startCol, endRow, endCol].Value =
sourceSheet.Cells[startRow, startCol, endRow, endCol].Value;
// 2. 复制列宽(仅复制有有效值的列)
for (int col = startCol; col <= endCol; col++)
{
if (sourceSheet.Column(col).Width > 0)
{
targetSheet.Column(col).Width = sourceSheet.Column(col).Width;
}
}
// 3. 复制行高(仅复制有有效值的行)
for (int row = startRow; row <= endRow; row++)
{
if (sourceSheet.Row(row).Height > 0)
{
targetSheet.Row(row).Height = sourceSheet.Row(row).Height;
}
}
// 4. 自动调整列宽(优化显示效果)
targetSheet.Cells[startRow, startCol, endRow, endCol].AutoFitColumns();
}
/// <summary>
/// 顶部表格双击,添加到下方
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GcMain_DoubleClick(object sender, EventArgs e)
{
DataRow rowItem = this.gcMain.GridView.GetFocusedDataRow();
if (rowItem != null)
{
DataTable dataTable = this.gridBottom.GridControl.DataSource as DataTable;
if (dataTable == null)
{
dataTable = rowItem.Table.Clone();
this.gridBottom.GridControl.DataSource = dataTable;
}
DataRow Item = dataTable.Rows.Cast<DataRow>().FirstOrDefault(x => x[this.ParmaryKey] + "" == rowItem[this.ParmaryKey] + "");
if (Item == null)
{
dataTable.Rows.Add(rowItem.ItemArray);
//gridBottom.GridView.ClearSelection();
//gridBottom.GridView.FocusedRowHandle = dataTable.Rows.Count - 1;
//gridBottom.GridView.SelectRow(dataTable.Rows.Count - 1);
}
rowItem.AcceptChanges();
}
}
/// <summary>
/// 取消选中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GridBottom_DoubleClick(object sender, EventArgs e)
{
if (this.gridBottom.GridView.RowCount == 0) return;
DataRow rowItem = this.gridBottom.GridView.GetFocusedDataRow();
(this.gridBottom.GridControl.DataSource as DataTable).Rows.Remove(rowItem);
}
/// <summary>
/// <para>说明:树节点点击后刷新数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-10-26 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="TreeViewEventArgs"/> instance containing the event data.</param>
protected void OnTreeLeftTreeNodeSelected(object sender, TreeViewEventArgs e)
{
try
{
string where = null;
if (string.IsNullOrWhiteSpace(this.ParentUnionField))
{
where = string.Format(this.SysModel.TreeExactQuery ? " and {0} = '{1}' " : " and {0} like '{1}%' ", this.treeLeft.TreeNodeKeyField, e.Node.Name);
}
else
{
where = string.Format(this.SysModel.TreeExactQuery ? " and {0} = '{1}' " : " and {0} like '{1}%' ", this.ParentUnionField, e.Node.Name);
}
this.SetMainGridView(where);
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
}
/// <summary>
/// 分隔条位置改变时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnSplitMainContainerPositionChanged(object sender, EventArgs e)
{
try
{
if (this.Model != null)
{
IniHelper.Write(string.Format("PubModuleExport_SplitMain_{0}", this.Model.ModuleCode), this.splitMainContainer.SplitterPosition + "");
IniHelper.Write(string.Format("PubModuleExport_SplitRight_{0}", this.Model.ModuleCode), this.splitRightContainer.SplitterPosition + "");
}
}
catch (Exception ex)
{
MessageUtil.Show(ex.Message);
}
}
/// <summary>
/// <para>说明:设置左侧树数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-10-25 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
private void SetLeftTreeView()
{
this.LeftRowObj = BaseModuleImpl.GetBaseLeftTreeField(this.Model.ModuleCode);//获取表格左侧树字段
if (this.LeftRowObj != null)
{
this.ParentUnionField = this.LeftRowObj["fieldname"] + "";
string parentKeyField = this.LeftRowObj["fieldsqlid"] + "";
this.treeLeft.TreeNodeKeyField = parentKeyField;
this.treeLeft.TreeNodeTextField = this.LeftRowObj["fieldsqlname"] + "";
this.treeLeft.TreeNodeSelectAfter += new TreeViewEventHandler(OnTreeLeftTreeNodeSelected);
this.treeLeft.TreeNodeLength = this.LeftRowObj.Table.Columns.Contains("TreeNodeLength") ? this.LeftRowObj["TreeNodeLength"] + "" : "";
this.treeLeft.BindTreeView(BaseImpl.GetDataTableResult(this.LeftRowObj["fieldsql"] + ""));
if (this.LeftRowObj.Table.Columns.Contains("TreeNodeSearch") && "1".Equals(this.LeftRowObj["TreeNodeSearch"] + "")) this.treeLeft.pl_top.Visible = true;
}
else
{
// 根据模块上配置的sql加载树
if (this.SysModel != null && !string.IsNullOrEmpty(this.SysModel.TreeSQL))
{
this.ParentUnionField = "SpeciesNo";
string parentKeyField = "SpeciesNo";
this.treeLeft.TreeNodeKeyField = parentKeyField;
this.treeLeft.TreeNodeTextField = "SpeciesName";
this.treeLeft.TreeNodeSelectAfter += new TreeViewEventHandler(OnTreeLeftTreeNodeSelected);
this.treeLeft.BindTreeView(BaseImpl.GetDataTableResult(this.SysModel.TreeSQL));
}
else if (this.SysModel.DefaultTreeSql)
{
this.ParentUnionField = "SpeciesNo";
string parentKeyField = "SpeciesNo";
this.treeLeft.TreeNodeKeyField = parentKeyField;
this.treeLeft.TreeNodeTextField = "SpeciesName";
this.treeLeft.TreeNodeSelectAfter += new TreeViewEventHandler(OnTreeLeftTreeNodeSelected);
this.treeLeft.BindTreeView(BaseImpl.GetDataTableResult("select a.SpeciesNo,a.SpeciesName from p_productspeciestab a where a.ban=0"));
}
}
}
/// <summary>
/// <para>说明:加载主表格数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-01-31 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="where">The where key.</param>
protected void SetMainGridView(string where = "")
{
string sqlValue = this.SysModel.MenuSql;
//判断是否是select开头,上方的判断可能出现开头是空格或者注释的情况
sqlValue = IsSelectAtStart(sqlValue) ? sqlValue + where : sqlValue;
this.SearchObj.SearchGrid(sqlValue);
}
/// <summary>
/// <para>说明:检查可用条件</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-11-09 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="cond">The cond.</param>
/// <param name="dataRow">The data row.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
private bool ValidateCond(string cond, DataRow dataRow)
{
bool result = false;
cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
if (cond.StartsWith("@") || cond.StartsWith("!"))
{
result = "1".Equals(BaseImpl.GetDefaultValue(cond));
}
else if (dataRow == null)
{
result = ReplaceHelper.EvalCond(cond);
}
else
{
result = ReplaceHelper.ReplaceRowParamCond(dataRow, cond);
}
return result;
}
/// <summary>
/// 判断是否是selete开头(可以处理sql前方有注释和空格的情况)
/// </summary>
/// <param name="sqlText"></param>
/// <returns></returns>
public static bool IsSelectAtStart(string sqlText)
{
string cleanedText = Regex.Replace(sqlText, @"^(\s*--.*?(\r\n|\n)|\s*)*", "");
return cleanedText.StartsWith("select", StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// <para>说明:拿到底部表格数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-11-21 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <returns>List&lt;GridDetailModel&gt;.</returns>
private List<GridDetailModel> GetDetails(string ModuleCode)
{
List<GridDetailModel> details = new List<GridDetailModel>();//表格明细对象的集合
DataTable table = BaseModuleImpl.GetBaseDetailPages(ModuleCode);// 根据传入的模块编号获得基础档案底部标签的数据
foreach (DataRow item in table.Rows)
{
DataTable gridColumns = ReportImpl.GetReportDetailColumns(ModuleCode, item["id"] + "");//获取报表明细列
details.Add(new GridDetailModel(item, gridColumns, GridCustomColumnStruct.BaseDetailGridView));
}
return details;
}
/// <summary>
/// 替换DataTable列名并删除无匹配的列:
/// 1. 将MasterData匹配FieldName的列名替换为对应的userName
/// 2. 删除MasterData中在controls无匹配FieldName的列
/// </summary>
/// <param name="MasterData">数据源表(需要替换列名+删除列)</param>
/// <param name="controls">控件信息表(FieldName=字段名,userName=中文列名)</param>
public void ReplaceAndRemoveUnmatchedColumns(DataTable MasterData, DataTable controls)
{
// 前置校验:避免空表/空引用导致异常
if (MasterData == null || controls == null || MasterData.Columns.Count == 0 || controls.Rows.Count == 0)
{
Console.WriteLine("数据表为空,无需处理");
return;
}
// 第一步:提取controls中的FieldName(去重),作为保留列名单
// 同时构建FieldName → userName的映射字典
HashSet<string> keepFieldNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase); // 不区分大小写
Dictionary<string, string> fieldNameToUserNameDict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (DataRow row in controls.Rows)
{
string fieldName = row["FieldName"]?.ToString()?.Trim();
string userName = row["userName"]?.ToString()?.Trim();
// 过滤空值,避免无效数据
if (string.IsNullOrEmpty(fieldName) || string.IsNullOrEmpty(userName))
{
continue;
}
// 去重:只保留第一个匹配的FieldName→userName
if (!fieldNameToUserNameDict.ContainsKey(fieldName))
{
keepFieldNames.Add(fieldName);
fieldNameToUserNameDict.Add(fieldName, userName);
}
}
// 第二步:遍历MasterData的列(注意:删除列需用倒序遍历,避免索引错乱)
// 先收集需要删除的列,再批量删除(比遍历中直接删除更安全)
List<DataColumn> columnsToRemove = new List<DataColumn>();
foreach (DataColumn column in MasterData.Columns)
{
string originalColumnName = column.ColumnName.Trim();
// 情况1:列名在保留名单中 → 替换为对应的userName
if (keepFieldNames.Contains(originalColumnName))
{
string newColumnName = fieldNameToUserNameDict[originalColumnName];
// 避免重复列名(极端情况:不同FieldName对应相同userName
if (!MasterData.Columns.Contains(newColumnName))
{
column.ColumnName = newColumnName;
Console.WriteLine($"列名替换成功:{originalColumnName} → {newColumnName}");
}
else
{
Console.WriteLine($"警告:替换后的列名[{newColumnName}]已存在,保留原列名[{originalColumnName}]");
}
}
// 情况2:列名不在保留名单中 → 标记为待删除
else
{
columnsToRemove.Add(column);
Console.WriteLine($"列[{originalColumnName}]无匹配的FieldName,标记为待删除");
}
}
// 第三步:批量删除无匹配的列
foreach (DataColumn col in columnsToRemove)
{
MasterData.Columns.Remove(col);
Console.WriteLine($"已删除列:{col.ColumnName}");
}
}
}
}