845 lines
38 KiB
C#
845 lines
38 KiB
C#
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<GridDetailModel>.</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}");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
}
|
||
}
|