using PTMedicalInsurance.Common; using PTMedicalInsurance.Helper; using Newtonsoft.Json.Linq; using PTMedicalInsurance.Variables; using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Linq; using System.Threading; using System.Windows.Forms; using PTMedicalInsurance.Entity.Base; using Ganss.Excel; using PTMedicalInsurance.Entity; namespace PTMedicalInsurance.Forms { public partial class ExcelImport : Form { private string mapSection; private List mapLst = new List(); private int buttonHeight = 30; // 按钮高度 private int rowSpacing = 20; // 行间距 private string excelFile = ""; private Dictionary> mappingPairs = new Dictionary>(); public delegate void ImportExcelHandler(string text); public event ImportExcelHandler onImport; public ExcelImport() { InitializeComponent(); rdDrugs.CheckedChanged += checkChange; rdService.CheckedChanged += checkChange; rdMaterial.CheckedChanged += checkChange; } private void SourceLabel_MouseDown(object sender, MouseEventArgs e) { Button sourceLabel = (Button)sender; DoDragDrop(sourceLabel, DragDropEffects.Copy); } /// /// 画连接线 /// /// /// private void DrawLine(Control sourceControl, Control targetControl) { Graphics g = CreateGraphics(); // 计算起始点和终点坐标(中心点) Point startPoint = new Point(sourceControl.Left + sourceControl.Width / 2, sourceControl.Top + sourceControl.Height / 2); Point endPoint = new Point(targetControl.Left + targetControl.Width / 2, targetControl.Top + targetControl.Height / 2); // 绘制连线(直线) Pen pen = new Pen(Color.Red); // 自定义颜色或样式 g.DrawLine(pen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); pen.Dispose(); g.Dispose(); } private void btnLoad_Click(object sender, EventArgs e) { if(openFileDlg.ShowDialog() == DialogResult.OK) { excelFile = openFileDlg.FileName; initMapper(); } } private void readIni() { IniFile ini = new IniFile(Global.curEvt.path + @"\InsuMapRelation.ini"); string excelImportSection = ""; if (rdDrugs.Checked) { mapSection = "Drugs"; excelImportSection = "ExcelImport_Drugs"; } if (rdService.Checked) { mapSection = "Services"; excelImportSection = "ExcelImport_Services"; } if (rdMaterial.Checked) { mapSection = "Materials"; excelImportSection = "ExcelImport_Materials"; } mapLst = new List(); mapLst = ini.ReadKeys(mapSection); this.maxPreviewRows.Value = !string.IsNullOrEmpty(ini.ReadValue(excelImportSection, "MaxPreviewRows")) ? int.Parse(ini.ReadValue(excelImportSection, "MaxPreviewRows")) : 20; this.maxUploadRows.Value = !string.IsNullOrEmpty(ini.ReadValue(excelImportSection, "MaxRowNumber")) ? int.Parse(ini.ReadValue(excelImportSection, "MaxRowNumber")) : 5000; this.headerLineNum.Value = !string.IsNullOrEmpty(ini.ReadValue(excelImportSection, "HeaderLineNum")) ? int.Parse(ini.ReadValue(excelImportSection, "HeaderLineNum")) : 1; this.headerStartNO.Value = !string.IsNullOrEmpty(ini.ReadValue(excelImportSection, "HeaderStartNO")) ? int.Parse(ini.ReadValue(excelImportSection, "HeaderStartNO")) : 2; this.codeMinLength.Value = !string.IsNullOrEmpty(ini.ReadValue(excelImportSection, "CodeMinLength")) ? int.Parse(ini.ReadValue(excelImportSection, "CodeMinLength")) : 6; this.txtCombinMark.Text = !string.IsNullOrEmpty(ini.ReadValue(excelImportSection, "CombinMark")) ? ini.ReadValue(excelImportSection, "CombinMark") : "-"; this.tbSheetName.Text = !string.IsNullOrEmpty(ini.ReadValue(excelImportSection, "SheetName")) ? ini.ReadValue(excelImportSection, "SheetName") : "总表"; } private void initMapper() { mappingPairs.Clear(); bool limited = true; if (maxPreviewRows.Value < 0) limited = false; ExcelMapper mapper = createMapper(limited); this.loadExcel(mapper,true); if (mapper == null || mapper.headers == null) { MessageBox.Show("mapper为空"); return; } string[] igoreColumns = new string[]{ "HospitalDr","InterfaceDr","HisType","HisTypeName" }; panelTarget.Controls.Clear(); panelSource.Controls.Clear(); mapper.headers.Where((x)=>!string.IsNullOrEmpty(x)).ToList().ForEach((cellName) => { Button btn = AddButton(panelSource, cellName); btn.MouseDown += SourceLabel_MouseDown; }); foreach (DataGridViewTextBoxColumn c in this.dataGridView1.Columns) { if (igoreColumns.Contains(c.DataPropertyName)) continue; Button btn = AddButton(panelTarget, c.HeaderText); btn.AllowDrop = true; btn.Tag = c.DataPropertyName; btn.DragDrop += panelTarget_DragDrop; btn.DragEnter += panelTarget_DragEnter; } } private ExcelMapper createMapper(bool limitedMaxRow) { try { ExcelMapper mapper = new ExcelMapper(excelFile); // 设置连接符 mapper.CombinMark = txtCombinMark.Text.Trim(); // 仅作为预览的数量 if (limitedMaxRow) { mapper.MaxRowNumber = Decimal.ToInt32(maxPreviewRows.Value); } if (headerLineNum.Value < 1) { // 无标题 mapper.HeaderRow = false; } else { mapper.HeaderRowNumber = int.Parse(headerLineNum.Value.ToString()) -1 ; mapper.MinRowNumber = int.Parse(headerStartNO.Value.ToString()) -1; } this.AddMapping(mapper); //new Thread(new ParameterizedThreadStart(loadExcel)).Start(mapper); return mapper; }catch(Exception e) { MessageBox.Show("createMapper:"+e.Message); } return null; } private int getHisType(out string typeName) { int type = 1; typeName = rdDrugs.Text; if (rdService.Checked) { type = 2; typeName = rdService.Text; } if (rdMaterial.Checked) { type = 3; typeName = rdMaterial.Text; } return type; } private List loadExcel(object mapper,bool show) { List list = new List(); try { string typeName; int type = getHisType(out typeName); if (mapper == null) return list; list = (mapper as ExcelMapper).Fetch(tbSheetName.Text).ToList(); //MessageBox.Show(list.Count.ToString()); //if (mappingPairs.Count != 0) list.ForEach((mi) => { mi.HospitalDr = (Global.inf.hospitalDr + ""); mi.InterfaceDr = Global.inf.interfaceDr + ""; mi.HisType = type.ToString(); mi.HisTypeName = typeName; }); // 过滤符合和code特征的数据 int codeMinLen = int.Parse(codeMinLength.Value.ToString()); MedInsuDirectory[] dataArray = list.Where((x) => x.Code == null || (x.Code != null && x.Code.Length > codeMinLen)).ToArray(); //MedInsuDirectory[] dataArray = list.Where((x) => x.Code.Length > codeMinLen).ToArray(); //MedInsuDirectory[] dArray = list.Where((x) => x.Code == null || (x.Code != null && x.Code.Length <= codeMinLen)).ToArray(); //foreach (var x in dArray) //{ // Global.writeLog(x.Code); //} if (show) { this.Invoke(new MethodInvoker(() => { DataGridViewExtensions.Bind(this.dataGridView1, dataArray); })); } //btnLoad.Enabled = false; btnPreview.Enabled = true; } catch (Exception e) { MessageBox.Show(e.Message); } return list; } private Button AddButton(Panel containerPanel, string buttonText) { Button newButton = new Button(); newButton.Name = containerPanel.Name + buttonText; newButton.Text = buttonText; newButton.Height = buttonHeight; newButton.AutoSize = true; int buttonCountInColumn = containerPanel.Controls.Count; // 设置按钮位置和大小 newButton.Left = (containerPanel.Width - newButton.Width) / 2; if (buttonCountInColumn == 0) newButton.Top = rowSpacing / 2; else newButton.Top = containerPanel.Controls[buttonCountInColumn - 1].Bottom + rowSpacing; containerPanel.Controls.Add(newButton); return newButton; } private void panelTarget_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(Button))) e.Effect = DragDropEffects.Copy; } private void panelTarget_DragDrop(object sender, DragEventArgs e) { Button target = (Button)sender; Button source = (Button)e.Data.GetData(typeof(Button)); addMapping(source, target); } private void addMapping(Button source,Button target) { //string newKey = "[" + source.Text + "]==>[" + target.Text + "]"; string newKey = source.Text + "=" + target.Text; // 记录excel列名和实体属性名的映射关系 if (mappingPairs.ContainsKey(newKey)) return; mappingPairs.Add(newKey,new KeyValuePair(source.Text, target.Text)); source.BackColor = Color.Cyan; target.BackColor = Color.Cyan; lstMapping.Items.Add(newKey); } private void btnPreview_Click(object sender, EventArgs e) { Thread t = new Thread(() => { ExcelMapper mapper = createMapper(maxPreviewRows.Value<0); this.loadExcel(mapper, true); }); t.Start(); btnComplete.Enabled = true; } private void AddMapping(ExcelMapper mapper) { foreach(string key in this.mappingPairs.Keys) { KeyValuePair kv = this.mappingPairs[key]; Type destType = typeof(MedInsuDirectory); string name = DataGridViewExtensions.getProperty(kv.Value); if(!string.IsNullOrEmpty(name)) { mapper.AddMapping(destType, kv.Key, name); } } } private void btnComplete_Click(object sender, EventArgs e) { string tips = string.Format("医院【{0}】,接口【{1}】 \r\n 你确定要导入这些数据吗?", Global.inf.hospitalDr, Global.inf.interfaceDr); if (!tools.Confirm(tips)) return; new Thread(new ThreadStart(upload)).Start(); } private void upload() { ExcelMapper excel = createMapper(false); List list = this.loadExcel(excel,false); // 每次最大条数 int pageSize = Decimal.ToInt32(maxUploadRows.Value); int index = 0; int pages = list.Count / pageSize; if ((list.Count % pageSize) > 0) { pages = pages + 1; } while (index < pages) { int count = pageSize; if((index+1) * pageSize > list.Count) count = list.Count % pageSize; List pageList = list.GetRange(index * pageSize, count); // upload to server uploadToServer(pageList); index++; } MessageBox.Show("目录上传完成!"); } private void uploadToServer(List list) { InvokeHelper helper = new InvokeHelper(); string data = getUploadParams(list); if (this.onImport != null) { this.onImport.Invoke("开始上传:"+data); } JObject ret = helper.invokeInsuService(data, "医保目录上传"); if (this.onImport != null) { this.onImport.Invoke("返回:"+JsonHelper.toJsonString(ret)); } } private string getUploadParams(List list) { //再过滤一次 int codeMinLen = int.Parse(codeMinLength.Value.ToString()); MedInsuDirectory[] dataArray = list.Where((x) => (x.Name?.Length>2) && (x.Code?.Length > codeMinLen)).ToArray(); Request request = new Request(); request.code = "02020145"; request.data = list.ToArray(); request.session = new object[] { LoginUser.Current.user }; return JsonHelper.toJsonString(request); } private void ExcelImport_Load(object sender, EventArgs e) { this.rdDrugs.Checked = true; this.btnComplete.Enabled = false; this.btnPreview.Enabled = false; readIni(); } private void btnMapping_Click(object sender, EventArgs e) { foreach (Control c in panelSource.Controls) { Control[] targets = panelTarget.Controls.Find(panelTarget.Name + c.Text, true); if (targets != null && targets.Length == 1) { addMapping((Button)c, (Button)targets[0]); } } } private void lstMapping_DoubleClick(object sender, EventArgs e) { if (lstMapping.SelectedIndex != -1) { string key = lstMapping.Items[lstMapping.SelectedIndex].ToString(); lstMapping.Items.Remove(key); this.mappingPairs.Remove(key); } } private void button2_Click(object sender, EventArgs e) { if (lstMapping.Items.Count == 0) { MessageBox.Show("映射关系不能为空"); return; } IniFile ini = new IniFile(Global.curEvt.path+ @"\InsuMapRelation.ini"); ini.DeleteSection(mapSection); foreach (var item in lstMapping.Items) { string pair = item.ToString(); int length = pair.Length; int pos = pair.IndexOf("="); ini.WriteValue(mapSection, pair.Substring(0, pos), pair.Substring(pos+1, length - pos - 1)); } } private void button1_Click(object sender, EventArgs e) { initMapper(); lstMapping.Items.Clear(); IniFile ini = new IniFile(Global.curEvt.path + @"\InsuMapRelation.ini"); foreach (var item in mapLst) { string sourceField = item.ToString(); string targetField = ini.ReadValue(mapSection, item.ToString()); string newKey = sourceField + "=" + targetField; lstMapping.Items.Add(newKey); mappingPairs.Add(newKey, new KeyValuePair(sourceField ,targetField)); Control[] targets = panelTarget.Controls.Find(panelTarget.Name + targetField, true); Control[] sources = panelSource.Controls.Find(panelSource.Name + sourceField, true); //MessageBox.Show(sourceField); //foreach (Control ite in targets) //{ // MessageBox.Show(((Button)ite).Name); //} //foreach (Control ite in panelTarget.Controls) //{ // MessageBox.Show(((Button)ite).Name); //} if (targets != null && targets.Length == 1) { ((Button)targets[0]).BackColor = Color.Cyan; } if (sources != null && sources.Length == 1) { ((Button)sources[0]).BackColor = Color.Cyan; } } } private void checkChange(object sender, EventArgs e) { readIni(); } } }