471 lines
20 KiB
C#
471 lines
20 KiB
C#
// 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<Message> 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<PropertyInfo> props = new List<PropertyInfo>();
|
|
|
|
// 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<Math.Min(crewMessage.NumberOfExcelRows, crewMessage.Elements.Count); i++)
|
|
{
|
|
string crewLastName = string.Format("CREW.CrewMemberLastName_{0}", i + 1);
|
|
string crewFirstName = string.Format("CREW.CrewMemberFirstName_{0}", i + 1);
|
|
string crewGender = string.Format("CREW.CrewMemberGender_{0}", i + 1);
|
|
string crewNationality = string.Format("CREW.CrewMemberNationality_{0}", i + 1);
|
|
string crewDuty = string.Format("CREW.CrewMemberDuty_{0}", i + 1);
|
|
string crewPlaceOfBirth = string.Format("CREW.CrewMemberPlaceOfBirth_{0}", i + 1);
|
|
string crewDateOfBirth = string.Format("CREW.CrewMemberDateOfBirth_{0}", i + 1);
|
|
string crewIdentDocType = string.Format("CREW.CrewMemberIdentityDocumentType_{0}", i + 1);
|
|
string crewIdentDocId = string.Format("CREW.CrewMemberIdentityDocumentId_{0}", i + 1);
|
|
string crewVisaNo = string.Format("CREW.CrewMemberVisaNumber_{0}", i + 1);
|
|
CREW crew = crewMessage.Elements[i] as CREW;
|
|
WriteText(crewLastName, crew.CrewMemberLastName);
|
|
WriteText(crewFirstName, crew.CrewMemberFirstName);
|
|
WriteGender(crewGender, crew.CrewMemberGender);
|
|
WriteText(crewNationality, crew.CrewMemberNationality);
|
|
WriteText(crewDuty, crew.CrewMemberDuty);
|
|
WriteText(crewPlaceOfBirth, crew.CrewMemberPlaceOfBirth);
|
|
if(crew.CrewMemberDateOfBirth.HasValue)
|
|
WriteDate(crewDateOfBirth, crew.CrewMemberDateOfBirth.Value);
|
|
WriteIdentityDocumentType(crewIdentDocType, crew.CrewMemberIdentityDocumentType);
|
|
WriteText(crewIdentDocId, crew.CrewMemberIdentityDocumentId);
|
|
WriteText(crewVisaNo, crew.CrewMemberVisaNumber);
|
|
}
|
|
}
|
|
|
|
private void WriteCREWD(Message crewdMessage)
|
|
{
|
|
for (int i = 0; i < Math.Min(crewdMessage.NumberOfExcelRows, crewdMessage.Elements.Count); i++)
|
|
{
|
|
string crewLastName = string.Format("CREWD.CrewMemberLastName_{0}", i + 1);
|
|
string crewFirstName = string.Format("CREWD.CrewMemberFirstName_{0}", i + 1);
|
|
string crewGender = string.Format("CREWD.CrewMemberGender_{0}", i + 1);
|
|
string crewNationality = string.Format("CREWD.CrewMemberNationality_{0}", i + 1);
|
|
string crewDuty = string.Format("CREWD.CrewMemberDuty_{0}", i + 1);
|
|
string crewPlaceOfBirth = string.Format("CREWD.CrewMemberPlaceOfBirth_{0}", i + 1);
|
|
string crewDateOfBirth = string.Format("CREWD.CrewMemberDateOfBirth_{0}", i + 1);
|
|
string crewIdentDocType = string.Format("CREWD.CrewMemberIdentityDocumentType_{0}", i + 1);
|
|
string crewIdentDocId = string.Format("CREWD.CrewMemberIdentityDocumentId_{0}", i + 1);
|
|
string crewVisaNo = string.Format("CREWD.CrewMemberVisaNumber_{0}", i + 1);
|
|
CREWD crewd = crewdMessage.Elements[i] as CREWD;
|
|
WriteText(crewLastName, crewd.CrewMemberLastName);
|
|
WriteText(crewFirstName, crewd.CrewMemberFirstName);
|
|
WriteGender(crewGender, crewd.CrewMemberGender);
|
|
WriteText(crewNationality, crewd.CrewMemberNationality);
|
|
WriteText(crewDuty, crewd.CrewMemberDuty);
|
|
WriteText(crewPlaceOfBirth, crewd.CrewMemberPlaceOfBirth);
|
|
if (crewd.CrewMemberDateOfBirth.HasValue)
|
|
WriteDate(crewDateOfBirth, crewd.CrewMemberDateOfBirth.Value);
|
|
WriteIdentityDocumentType(crewIdentDocType, crewd.CrewMemberIdentityDocumentType);
|
|
WriteText(crewIdentDocId, crewd.CrewMemberIdentityDocumentId);
|
|
WriteText(crewVisaNo, crewd.CrewMemberVisaNumber);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region write simple things
|
|
|
|
private void WriteIdentityDocumentType(string label, byte? docType)
|
|
{
|
|
if(docType.HasValue)
|
|
{
|
|
switch(docType.Value)
|
|
{
|
|
case 1: WriteText(label, "identity_card"); break;
|
|
case 2: WriteText(label, "passport"); break;
|
|
case 3: WriteText(label, "muster_book"); break;
|
|
case 4: WriteText(label, "picture_id"); break;
|
|
case 5: WriteText(label, "residential_permit"); break;
|
|
case 6: WriteText(label, "other_legal_identity_document"); break;
|
|
default: WriteText(label, "ic"); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void WriteGender(string label, byte? gender)
|
|
{
|
|
if(gender.HasValue)
|
|
{
|
|
if (gender == 0) WriteText(label, "m");
|
|
if (gender == 1) WriteText(label, "w");
|
|
if (gender == 2) WriteText(label, "d");
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region write value types
|
|
|
|
private bool WriteBoolean(string lookupName, object v)
|
|
{
|
|
bool result = _nameDict.ContainsKey(lookupName);
|
|
bool b = (bool) v;
|
|
if (result)
|
|
{
|
|
_nameDict[lookupName].RefersToRange.Value = b ? "Y" : "N";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private bool WriteText(string lookupName, object v)
|
|
{
|
|
bool result = _nameDict.ContainsKey(lookupName);
|
|
|
|
if(result)
|
|
{
|
|
_nameDict[lookupName].RefersToRange.Value = v;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private bool WriteNumber(string lookupName, object v)
|
|
{
|
|
bool result = _nameDict.ContainsKey(lookupName);
|
|
|
|
if (result)
|
|
{
|
|
_nameDict[lookupName].RefersToRange.Value = v;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private bool WriteDate(string lookupName, object v)
|
|
{
|
|
bool result = _nameDict.ContainsKey(lookupName);
|
|
|
|
if (result)
|
|
{
|
|
if(v != null)
|
|
{
|
|
_nameDict[lookupName].RefersToRange.Value = ((DateTime) v).ToOADate(); // Test this I dont believe it
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|