using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; namespace 云心电ECG数据解析服务端 { public class Hl7EcgOptions { float[] valueConvert(float[] valueArray) { float[] quotients = valueArray.Select(n => n / 9).ToArray();//把数值缩小9倍 这是用标准数据进行标定得到的 缩小倍数系数 return quotients; } /// /// 读取HL7文件中的患者信息和心电分析参数 /// /// public analysisParas getAnalysisParas(string xmlFilePath) { try { FileInfo fi = new FileInfo(xmlFilePath); XmlDocument xmlDoc = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true;//忽略文档里面的注释 XmlReader reader = XmlReader.Create(xmlFilePath, settings); xmlDoc.Load(reader); XmlNodeList xnList = xmlDoc.DocumentElement.GetElementsByTagName("annotation"); analysisParas ap = new analysisParas(); //先从hl7 ecg xml文件中读取心电数据 XmlNodeList xnListx1 = xmlDoc.DocumentElement.GetElementsByTagName("digits"); // Dictionary> EcgTable = new Dictionary>(); int leadDataIndex = 0; for (int i = 0; i < 12; i++) { string[] ecgDataArray = new string[xnListx1.Item(leadDataIndex + i).InnerText.Split(' ').Length]; ecgDataArray = xnListx1.Item(leadDataIndex + i).InnerText.Split(' '); //List ecg_List = valueConvert(Array.ConvertAll(ecgDataArray, float.Parse)).ToList(); List ecg_List = new List(); for (int b = 0; b < ecgDataArray.Length; b++) if (!string.IsNullOrEmpty(ecgDataArray[b])) ecg_List.Add(float.Parse(ecgDataArray[b]) / 9); if (i == 0) ap.LEAD_I = ecg_List; if (i == 1) ap.LEAD_II = ecg_List; if (i == 2) ap.LEAD_III = ecg_List; if (i == 3) ap.LEAD_AVR = ecg_List; if (i == 4) ap.LEAD_AVL = ecg_List; if (i == 5) ap.LEAD_AVF = ecg_List; if (i == 6) ap.LEAD_V1 = ecg_List; if (i == 7) ap.LEAD_V2 = ecg_List; if (i == 8) ap.LEAD_V3 = ecg_List; if (i == 9) ap.LEAD_V4 = ecg_List; if (i == 10) ap.LEAD_V5 = ecg_List; if (i == 11) ap.LEAD_V6 = ecg_List; // EcgTable.Add(i, ecg_List); } XmlNodeList xnList1 = xmlDoc.DocumentElement.GetElementsByTagName("family"); ap.patientName = xnList1[0].InnerText;//姓名 XmlNodeList xnList2 = xmlDoc.DocumentElement.GetElementsByTagName("administrativeGenderCode"); string valStr = xnList2[0].OuterXml; string sexStr = valStr.Substring(valStr.IndexOf("code="), valStr.IndexOf("codeSystem=") - valStr.IndexOf("code=")).Replace("code=", "").Replace("\"", "").Trim();//性别 if (sexStr.Trim() == "M") ap.gender = "男"; if (sexStr.Trim() == "F") ap.gender = "女"; XmlNodeList xnList4 = xmlDoc.DocumentElement.GetElementsByTagName("birthTime"); string birthday = xnList4[0].OuterXml;//出生日期 birthday = birthday.Substring(birthday.IndexOf("value="), birthday.IndexOf("xmlns=") - birthday.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); if (birthday.Length > 0) { ap.birthDay = birthday; int year = int.Parse(ap.birthDay.Substring(0, 4)); ap.age = (DateTime.Now.Year - year).ToString(); } XmlNodeList xnList5 = xmlDoc.DocumentElement.GetElementsByTagName("patientid"); string patientId = xnList5[0].OuterXml;//患者id patientId = patientId.Substring(patientId.IndexOf("extension="), patientId.IndexOf("xmlns=") - patientId.IndexOf("extension=")).Replace("extension=", "").Replace("\"", "").Trim(); ap.patientid = patientId; //获取日期和时间 XmlNodeList xnList3 = xmlDoc.DocumentElement.GetElementsByTagName("effectiveTime"); string collStr = xnList3[0].FirstChild.OuterXml; string collectTime = collStr.Substring(collStr.IndexOf("value="), collStr.IndexOf("xmlns=") - collStr.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim();//采集时间 if (collectTime.Length > 0) { ap.collectTime = collectTime.Insert(4, "-").Insert(7, "-").Insert(10, " ").Insert(13, ":").Insert(16, ":");//转换成日期时间格式 } foreach (XmlNode xnx in xnList) { // string sss = xnx.FirstChild.Name; string OuterXml1 = xnx.FirstChild.OuterXml; // string xxx = xnx.LastChild.Name; string OuterXml2 = xnx.LastChild.OuterXml; if (OuterXml1.Contains("MDC_ECG_HEART_RATE")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.heartRate = valueStr; } if (OuterXml1.Contains("MDC_ECG_TIME_PD_P") && !OuterXml1.Contains("MDC_ECG_TIME_PD_PR") && !OuterXml1.Contains("MDC_ECG_TIME_PD_PQ")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.P = valueStr; } if (OuterXml1.Contains("MDC_ECG_TIME_PD_QRS")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.QRS = valueStr; } if (OuterXml1.Contains("MDC_ECG_TIME_PD_RR")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.RR = valueStr; } if (OuterXml1.Contains("MDC_ECG_TIME_PD_PR")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.PR = valueStr; } if (OuterXml1.Contains("MDC_ECG_TIME_PD_PQ")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.PQ = valueStr; } if (OuterXml1.Contains("MDC_ECG_TIME_PD_QT") && !OuterXml1.Contains("MDC_ECG_TIME_PD_QTc")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.QT = valueStr; } if (OuterXml1.Contains("MDC_ECG_TIME_PD_QTc")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.QTc = valueStr; } if (OuterXml1.Contains("MDC_ECG_ANGLE_P_FRONT")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.P_degrees = valueStr; } if (OuterXml1.Contains("MDC_ECG_ANGLE_QRS_FRONT")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.QRS_degrees = valueStr; } if (OuterXml1.Contains("MDC_ECG_ANGLE_T_FRONT")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.T_degrees = valueStr; } if (OuterXml1.Contains("Biocare_RV5") && !OuterXml1.Contains("Biocare_RV5_PLUS_SV1")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.RV5 = valueStr; } if (OuterXml1.Contains("Biocare_SV1")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.SV1 = valueStr; } if (OuterXml1.Contains("Biocare_RV5_PLUS_SV1")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.RV5PLUSSV1 = valueStr; } if (OuterXml1.Contains("Biocare_PAPER_SPEED")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.paperSpeed = valueStr + "mm/s"; } if (OuterXml1.Contains("Biocare_GAIN")) { string valueStr = OuterXml2.Substring(OuterXml2.IndexOf("value="), OuterXml2.IndexOf("unit=") - OuterXml2.IndexOf("value=")).Replace("value=", "").Replace("\"", "").Trim(); ap.Gain = valueStr + "mm/mV"; } } reader.Close(); return ap; } catch (Exception ex) { } return null; } /// /// 根据HL7-ECG XML文件 生成心电图 /// /// HL7-ECG XML 文件的路径 /// 心电图报告标题 /// public string createEcgBmpByHL7XMLFile(string path, string reportInfo) { analysisParas ap = getAnalysisParas(path); FileInfo fi = new FileInfo(path); XmlDocument xmlDoc = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true;//忽略文档里面的注释 XmlReader reader = XmlReader.Create(path, settings); xmlDoc.Load(reader); XmlNodeList xn = xmlDoc.ChildNodes; XmlNodeList xnList = xmlDoc.DocumentElement.GetElementsByTagName("digits"); Dictionary> EcgTable = new Dictionary>(); int leadDataIndex = 0; for (int i = 0; i < 12; i++) { string[] ecgDataArray = new string[xnList.Item(leadDataIndex + i).InnerText.Split(' ').Length]; ecgDataArray = xnList.Item(leadDataIndex + i).InnerText.Split(' '); List ecg_List = new List(); for (int b = 0; b < ecgDataArray.Length; b++) if (!string.IsNullOrEmpty(ecgDataArray[b])) ecg_List.Add(float.Parse(ecgDataArray[b]) / 9); EcgTable.Add(i, ecg_List); } EcgDataDraw_New EDDN = new EcgDataDraw_New(); var btmp = new Bitmap(3319, 2357); Graphics Ecg_Graphics = Graphics.FromImage(btmp); List leadInfo = new List(); for (int i = 0; i < 12; i++) leadInfo.Add(i); EDDN.InitEcgParameter(btmp, 12, EcgTable, 300, leadInfo);//初始化 EDDN.Draw_EcgBackGroundGrid(500);//画背景网格 EDDN.Draw_EcgWave(500, 0, 0);//画波形 EDDN.Draw_analysisParas(ap);//画患者信息和分析参数 EDDN.Draw_CalibrationVoltage_And_LeadName();//画定标电压和导联名称 EDDN.Draw_ReportHeadInfo(reportInfo, "", ""); //string bmpPath = fi.DirectoryName + @"\EcgDataFiles\" + reportInfo + ".jpg"; // string RotateEcgDataFilesPath = fi.DirectoryName + @"\RotateEcgDataFiles\" + reportInfo+ ".jpg"; //string xmlPath = fi.DirectoryName + @"\XmlDataFiles\" + reportInfo + ".xml"; string ecgBmpPath = fi.DirectoryName + @"\" + ap.patientName + "[" + Guid.NewGuid().ToString() + "].jpg"; btmp.Save(ecgBmpPath, ImageFormat.Jpeg); //btmp.RotateFlip(RotateFlipType.Rotate90FlipNone);//顺时针旋转90° //btmp.Save(RotateEcgDataFilesPath, ImageFormat.Jpeg); btmp.Dispose(); reader.Close(); // fi.CopyTo(xmlPath, true); //string returnStr = FtpHelper.FileUpLoad(bmpPath, ConfigurationManager.AppSettings["path1"], reportInfo + ".jpg");//上传 png文件 // textBox2.AppendText(bmpPath + "\r\n" + reportInfo + ".jpg" + "\r\n FTP:" + returnStr + "\r\n"); // FtpHelper.FileUpLoad(xmlPath, ConfigurationManager.AppSettings["path1"], reportInfo.Split('_')[0] + ".xml");//上传 xml文件 //dataSubmit(reportInfo);//提交数据 //SqliteOptions_sql.CreateInstance().SqliteAdd("INSERT INTO [dbo].[tb_Pecg] ([ID],[medicalSN],[patientName],[sex],[birthday],[createDate],[ecgFilePath]) VALUES ('" + Guid.NewGuid().ToString() + "','" + reportInfo.Split('_')[0] + "','" + reportInfo.Split('_')[1] + "','" + reportInfo.Split('_')[2] + "','" + birthday + "','" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + (reportInfo.Split('_')[0] + ".jpg") + "')"); //fi.Delete(); //textBox2.AppendText(label1.Text + "\r\n"); //label1.Text = string.Empty; return ecgBmpPath; } } }