// Copyright (c) 2017- schick Informatik // Description: // using Microsoft.Office.Interop.Excel; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; using bsmd.database; namespace ENI2.Excel { internal class ExcelWriter : ExcelBase { #region Fields private readonly string _saveFilePath; #endregion #region Construction public ExcelWriter(string filePath) : base(filePath) { string refFilePath = System.IO.Path.Combine(Environment.CurrentDirectory, @"Excel\Reference_Sheet_DE.xlsx"); this._workBook = _excelWorkbooks.Open(refFilePath, 0, true, 5, "", "", false, XlPlatform.xlWindows, "", false, false, 0, false, false, false); this.InitNameFields(); _saveFilePath = filePath; } #endregion #region public methods public void WriteData(List messages, MessageCore core, out string resultMessage) { resultMessage = ""; foreach (Message message in messages) { try { switch(message.MessageNotificationClass) { case Message.NotificationClass.AGNT: if (message.Elements[0] is AGNT agnt) this.WriteMessage(agnt); break; case Message.NotificationClass.ATA: if (message.Elements[0] is ATA ata) this.WriteMessage(ata); break; case Message.NotificationClass.ATD: if (message.Elements[0] is ATD atd) this.WriteMessage(atd); break; case Message.NotificationClass.BKRA: this.WriteBKRA(message); break; case Message.NotificationClass.BKRD: this.WriteBKRD(message); break; case Message.NotificationClass.BPOL: if (message.Elements[0] is BPOL bpol) { this.WriteMessage(bpol); this.WriteItineraries(bpol); } break; case Message.NotificationClass.CREW: this.WriteCREW(message); break; case Message.NotificationClass.CREWD: this.WriteCREWD(message); break; case Message.NotificationClass.HAZA: if (message.Elements[0] is HAZ haza) this.WriteMessage(haza); break; case Message.NotificationClass.HAZD: if (message.Elements[0] is HAZ hazd) this.WriteMessage(hazd); break; case Message.NotificationClass.INFO: if (message.Elements[0] is INFO info) this.WriteMessage(info); break; case Message.NotificationClass.LADG: this.WriteLADG(message); break; case Message.NotificationClass.MDH: if (message.Elements[0] is MDH mdh) this.WriteMessage(mdh); break; case Message.NotificationClass.NAME: if (message.Elements[0] is NAME name) this.WriteMessage(name); break; case Message.NotificationClass.NOA_NOD: if (message.Elements[0] is NOA_NOD noa_nod) this.WriteMessage(noa_nod); break; case Message.NotificationClass.PAS: break; case Message.NotificationClass.PASD: break; case Message.NotificationClass.POBA: if (message.Elements[0] is POBA poba) this.WriteMessage(poba); break; case Message.NotificationClass.POBD: if (message.Elements[0] is POBD pobd) this.WriteMessage(pobd); break; case Message.NotificationClass.PRE72H: if (message.Elements[0] is PRE72H pre72h) this.WriteMessage(pre72h); break; case Message.NotificationClass.SEC: if (message.Elements[0] is SEC sec) this.WriteMessage(sec); break; case Message.NotificationClass.SERV: break; case Message.NotificationClass.STAT: if (message.Elements[0] is STAT stat) this.WriteMessage(stat); break; case Message.NotificationClass.STO: break; case Message.NotificationClass.TIEFA: if (message.Elements[0] is TIEFA tiefa) this.WriteMessage(tiefa); break; case Message.NotificationClass.TIEFD: if (message.Elements[0] is TIEFD tiefd) this.WriteMessage(tiefd); break; case Message.NotificationClass.TOWA: break; case Message.NotificationClass.TOWD: break; case Message.NotificationClass.WAS: if (message.Elements[0] is WAS was) this.WriteMessage(was); break; default: _log.InfoFormat("skip writing message class {0}", message.MessageNotificationClassDisplay); break; } } catch (Exception ex) { resultMessage += string.Format("{2}:{0}{1}", ex.Message, Environment.NewLine, message.MessageNotificationClassDisplay); } } WriteCore(core); } public void Save() { this._workBook.SaveAs(_saveFilePath, XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); this._workBook.Saved = true; } #endregion #region private excel field writing // generische Methode zum Schreiben der Felder nach Excel für Meldeklassen, die kein // Listentyp sind private void WriteMessage(DatabaseEntity dbEntity) { Type objType = dbEntity.GetType(); List props = new List(); // add lookup properties to scan list props.AddRange(objType.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(LookupNameAttribute)))); foreach (PropertyInfo property in props) { object propValue = property.GetValue(dbEntity, null); string value = (propValue == null) ? string.Empty : propValue.ToString(); LookupNameAttribute lookupNameAttribute = Attribute.GetCustomAttribute(property, typeof(LookupNameAttribute)) as LookupNameAttribute; bool success = true; if (property.PropertyType == typeof(DateTime?)) { success = this.WriteDate(lookupNameAttribute.LookupName, property.GetValue(dbEntity)); } else if (property.PropertyType == typeof(double?)) { success = this.WriteNumber(lookupNameAttribute.LookupName, property.GetValue(dbEntity)); } else if (property.PropertyType == typeof(string)) { success = this.WriteText(lookupNameAttribute.LookupName, property.GetValue(dbEntity)); } else if (property.PropertyType == typeof(int?)) { success = this.WriteNumber(lookupNameAttribute.LookupName, property.GetValue(dbEntity)); } else if (property.PropertyType == typeof(byte?)) { success = this.WriteNumber(lookupNameAttribute.LookupName, property.GetValue(dbEntity)); } else if (property.PropertyType == typeof(Boolean?)) { object boolVal = property.GetValue(dbEntity); if(boolVal != null) success = this.WriteBoolean(lookupNameAttribute.LookupName, boolVal); } else { string message = string.Format("unhandled property type: {0} for lookup {1}", property.PropertyType, lookupNameAttribute.LookupName); _log.Warn(message); } if (!success) { string message = string.Format("Sheet does not contain lookup field {0}", lookupNameAttribute.LookupName); _log.Error(message); System.Diagnostics.Trace.WriteLine(message); // throw new FormatException(message); } } } private void WriteCore(MessageCore core) { } #region list / special message classes private void WriteLADG(Message ladgMessage) { for (int i = 0; i < Math.Min(ladgMessage.NumberOfExcelRows, ladgMessage.Elements.Count); i++) { string lnCHT = string.Format("LADG.CargoHandlingType_{0}", i + 1); string lnType = string.Format("LADG.CargoType_{0}", i + 1); string lnCNOI = string.Format("LADG.CargoNumberOfItems_{0}", i + 1); string lnCGQ = string.Format("LADG.CargoGrossQuantity_TNE_{0}", i + 1); string lnLoad = string.Format("LADG.CargoPortOfLoading_{0}", i + 1); string lnDis = string.Format("LADG.CargoPortOfDischarge_{0}", i + 1); string lnLACode = string.Format("LADG.CargoLACode_{0}", i + 1); string lnZusatz = string.Format("LADG.CargoTypeZusatz_{0}", i + 1); LADG ladg = ladgMessage.Elements[i] as LADG; if (ladg.CargoHandlingType.HasValue) { switch (ladg.CargoHandlingType) { case 1: WriteText(lnCHT, "load"); break; case 2: WriteText(lnCHT, "discharge"); break; case 3: WriteText(lnCHT, "transit"); break; default: break; } } WriteText(lnType, ladg.CargoCodeNST); WriteText(lnZusatz, ladg.CargoCodeNST_3); WriteNumber(lnCNOI, ladg.CargoNumberOfItems); WriteNumber(lnCGQ, ladg.CargoGrossQuantity_TNE); WriteText(lnLoad, ladg.PortOfLoading); WriteText(lnDis, ladg.PortOfDischarge); WriteNumber(lnLACode, ladg.CargoLACode); } } private void WriteBKRA(Message bkraMessage) { for (int i = 0; i < Math.Min(bkraMessage.NumberOfExcelRows, bkraMessage.Elements.Count); i++) { string lnQuantity = string.Format("BKRA.BunkerFuelQuantity_TNE_{0}", i + 1); string lnType = string.Format("BKRA.BunkerFuelType_{0}", i + 1); BRKA brka = bkraMessage.Elements[i] as BRKA; WriteNumber(lnQuantity, brka.BunkerFuelQuantity_TNE); WriteText(lnType, brka.BunkerFuelType); } } private void WriteBKRD(Message bkrdMessage) { for (int i = 0; i < Math.Min(bkrdMessage.NumberOfExcelRows, bkrdMessage.Elements.Count); i++) { string lnQuantity = string.Format("BKRD.BunkerFuelQuantity_TNE_{0}", i + 1); string lnType = string.Format("BKRD.BunkerFuelType_{0}", i + 1); BRKD brkd = bkrdMessage.Elements[i] as BRKD; WriteNumber(lnQuantity, brkd.BunkerFuelQuantity_TNE); WriteText(lnType, brkd.BunkerFuelType); } } private void WriteItineraries(BPOL bpol) { for (int i = 0; i < Math.Min(10, bpol.PortOfItineraries.Count); i++) { string bpolName = string.Format("BPOL.PortOfItineraryName_{0}", i + 1); string bpolLocode = string.Format("BPOL.PortOfItineraryLoCode_{0}", i + 1); string bpolETADate = string.Format("BPOL.PortOfItineraryETADate_{0}", i + 1); string bpolETATime = string.Format("BPOL.PortOfItineraryETATime_{0}", i + 1); PortOfItinerary poi = bpol.PortOfItineraries[i]; WriteText(bpolName, poi.PortOfItineraryName); WriteText(bpolLocode, poi.PortOfItineraryLocode); if (poi.PortOfItineraryETA.HasValue) { WriteDate(bpolETADate, poi.PortOfItineraryETA.Value.Date); WriteText(bpolETATime, poi.PortOfItineraryETA.Value.ToShortTimeString()); } } } private void WriteCREW(Message crewMessage) { for(int i = 0; i