Dateien aus ExcelReader hinzugefügt und teilweise bereits bearbeitet. Übersetzt noch nicht.!

This commit is contained in:
Daniel Schick 2021-11-30 09:26:02 +01:00
parent a6b055e76f
commit 26dcd0edd2
6 changed files with 3657 additions and 3 deletions

View File

@ -721,8 +721,8 @@ namespace ENI2.DetailViewControls
// get here if user selected some classes
// start importer
// show import result?
// validate all selected import classes (Finger with "selection")
}
}

108
ENI2/Import/ExcelBase.cs Normal file
View File

@ -0,0 +1,108 @@
// Copyright (c) 2017-today Informatikbüro Daniel Schick
// Base class excel (writer not yet implemented but eventually..)
using System;
using System.Collections.Generic;
using Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using log4net;
namespace ENI2.Import
{
internal class ExcelBase : IDisposable
{
#region Fields
internal enum CountryMode { NONE, DE, DK };
protected CountryMode _countryMode = CountryMode.NONE;
protected Workbooks _excelWorkbooks;
protected Workbook _portcall;
protected Application _excelApp;
protected Dictionary<string, Name> _nameDict;
protected ILog _log;
#endregion
#region Properties
internal CountryMode Mode { get { return _countryMode; } }
#endregion
#region Saving
internal bool Save(string filePath)
{
bool result = true;
if (this._excelApp == null) return false;
try
{
this._excelApp.SaveWorkspace(filePath);
}
catch (Exception ex)
{
_log.WarnFormat("cannot save workspace: {0}", ex.Message);
result = false;
}
return result;
}
internal bool SaveCopy(string filePath)
{
bool result = true;
if (this._excelApp == null) return false;
try
{
this._portcall.Saved = true;
this._portcall.SaveCopyAs(filePath);
}
catch (Exception ex)
{
_log.WarnFormat("cannot save copy of workbook: {0}", ex.Message);
result = false;
}
return result;
}
#endregion
#region Dispose
public void Dispose()
{
try
{
if (this._portcall != null)
{
this._portcall.Close(0);
_log.Debug("Close Worksheet");
Marshal.ReleaseComObject(this._portcall);
}
if (this._excelWorkbooks != null)
{
this._excelWorkbooks.Close();
_log.Debug("Close Workbooks");
Marshal.ReleaseComObject(this._excelWorkbooks);
// this._excelWorkbooks.Close();
}
if (this._excelApp != null)
{
_log.Debug("Quit Excel");
this._excelApp.Quit();
Marshal.ReleaseComObject(this._excelApp);
}
}
catch(Exception ex)
{
_log.ErrorFormat("Exception disposing ExcelReader: {0}", ex.Message);
}
}
#endregion
}
}

View File

@ -0,0 +1,57 @@
// Copyright (c) 2017- Informatikbüro Daniel Schick
// Description: Controller class for reading excel sheets (label-based)
using bsmd.database;
using log4net;
using System;
using System.Collections.Generic;
using System.IO;
namespace ENI2.Import
{
public class ExcelManager
{
private readonly ILog _log = LogManager.GetLogger(typeof(ExcelManager));
public ExcelManager()
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
}
public bool Import(string filePath, MessageCore core, List<Message.NotificationClass> classes, out string readMessage)
{
bool result = false;
try
{
using (ExcelReader reader = new ExcelReader(filePath))
{
ImportHeader importHeader = new ImportHeader
{
ImportDate = DateTime.Now
};
result = ExcelUtil.ProcessSheet(reader, out readMessage, core); // actual import
if (result)
{
importHeader.MessageCoreId = core.Id.Value;
importHeader.Filename = Path.GetFileName(filePath);
ReportingParty thisUser = ReportingParty.CurrentReportingParty;
importHeader.SenderEmail = thisUser.EMail;
importHeader.ReportingPartyId = thisUser.Id;
DBManager.Instance.Save(importHeader);
// Saving plaintext data (ImportHeader + ImportValues) for each reading
List<ImportValue> valueList = importHeader.CreateUpdateList(reader.ImportValues);
// Bulk save recommended here..
ImportValue.BulkSave(valueList);
}
}
}
catch (Exception ex)
{
readMessage = ex.Message;
_log.Error(ex);
}
return result;
}
}
}

576
ENI2/Import/ExcelReader.cs Normal file
View File

@ -0,0 +1,576 @@
//
// Class: ExcelReader
// Current CLR: 4.0.30319.34209
// System: Microsoft Visual Studio 10.0
// Author: dani
// Created: 6/15/2015 10:03:40 PM
//
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
using log4net;
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using ENI2.Locode;
using bsmd.database;
namespace ENI2.Import
{
internal class ExcelReader : ExcelBase
{
internal enum ReadState { NONE, OK, WARN, FAIL };
internal Dictionary<string, string> ImportValues { get; } = new Dictionary<string, string>();
public ExcelReader(string filePath)
{
_log = LogManager.GetLogger(typeof(ExcelReader));
this._excelApp = new Application();
this._excelApp.DisplayAlerts = false;
this._excelWorkbooks = _excelApp.Workbooks;
this._portcall = _excelWorkbooks.Open(filePath, 0, true, 5, "", "", false, XlPlatform.xlWindows, "", false, false, 0, false, false, false);
_nameDict = new Dictionary<string, Name>();
int bookCnt = 0;
foreach(Name name in _portcall.Names)
{
string theValue = name.Value;
// Namensbezug: =SheetZelle. Leere Referenzen überspringen (kommt immer mal wieder vor!)
string nameKey = name.Name;
try
{
if (nameKey.Contains("!"))
nameKey = nameKey.Substring(nameKey.IndexOf('!') + 1);
}
catch(Exception)
{
_log.DebugFormat("Strange name in Sheet: {0}", nameKey);
continue;
}
if ((theValue != "=#REF!#REF!") && (theValue != "=#BEZUG!#BEZUG!"))
{
_nameDict[nameKey] = name;
bookCnt++;
}
}
_log.DebugFormat("{0} named ranges found at Workbook level", bookCnt);
foreach(Worksheet ws in _portcall.Worksheets)
{
int wsCnt = 0;
foreach(Name name in ws.Names)
{
string theValue = name.Value;
// Namensbezug: =SheetZelle. Leere Referenzen überspringen (kommt immer mal wieder vor!)
if (!_nameDict.ContainsKey(name.Name))
{
if ((theValue != "=#REF!#REF!") && (theValue != "=#BEZUG!#BEZUG!"))
{
_nameDict[name.Name] = name;
wsCnt++;
}
}
}
if (wsCnt > 0)
_log.DebugFormat("{0} named ranges found in Worksheet {1}", wsCnt, ws.Name);
}
}
internal string ReadText(string lookup)
{
string result = null;
if (_nameDict.ContainsKey(lookup))
{
try
{
var val = _nameDict[lookup].RefersToRange.Value;
var val2 = _nameDict[lookup].RefersToRange.Value2;
if (val != null)
result = val.ToString().Trim();
else if (val2 != null)
result = val2.ToString().Trim();
}
catch (COMException ex)
{
_log.WarnFormat("COMException reading field {0}: {1}", lookup, ex.ErrorCode);
}
}
if (result != null)
{
result = result.Trim();
this.ImportValues[lookup] = result;
}
return result;
}
internal string ReadTextNoWhitespace(string lookup)
{
string val = this.ReadText(lookup);
if (val == null) return val;
return new string(val.Where(c => !Char.IsWhiteSpace(c)).ToArray());
}
internal string ReadLoCode(string lookup)
{
string val = this.ReadText(lookup);
if (!val.IsNullOrEmpty())
{
val = val.ToUpper();
string portName = LocodeDB.PortNameFromLocode(val);
if(portName.IsNullOrEmpty())
_log.WarnFormat("unknown Locode {0}", val);
}
return val;
}
internal int? ReadCargoLACode(string lookup)
{
string val = ReadText(lookup);
if (val.IsNullOrEmpty()) return null;
if(int.TryParse(val, out int result))
{
if ((result < 10) || (result > 99))
_log.WarnFormat("invalid cargo LA code {0}", result);
return result;
}
else
{
_log.ErrorFormat("Cargo LA code parse error for {0}", lookup);
return null;
}
}
internal byte? ReadGender(string lookup)
{
byte? result = null;
string val = this.ReadText(lookup);
if (val != null)
{
if (val.Equals("m", StringComparison.CurrentCultureIgnoreCase) || val.Equals("male", StringComparison.CurrentCultureIgnoreCase)) {
result = 0;
}
else if (val.Equals("f", StringComparison.CurrentCultureIgnoreCase) || val.Equals("female", StringComparison.CurrentCultureIgnoreCase))
{
result = 1;
}
else
{
result = 2;
}
}
if(result == null)
{
_log.ErrorFormat("error reading gender on {0}", lookup);
}
return result;
}
internal byte? ReadIdentityDocumentType(string lookup)
{
byte? result = null;
string val = this.ReadText(lookup);
if (val != null)
{
if (val.Equals("identity_card", StringComparison.CurrentCultureIgnoreCase) || val.Equals("1")) result = 0;
if (val.Equals("passport", StringComparison.CurrentCultureIgnoreCase) || val.Equals("2")) result = 1;
if (val.Equals("muster_book", StringComparison.CurrentCultureIgnoreCase) || val.Equals("3")) result = 2;
if (val.Equals("picture_id", StringComparison.CurrentCultureIgnoreCase) || val.Equals("4")) result = 3;
if (val.Equals("residental_permit", StringComparison.CurrentCultureIgnoreCase) || val.Equals("5")) result = 4;
if (val.Equals("other_legal_identity_document", StringComparison.CurrentCultureIgnoreCase) || val.Equals("6")) result = 5;
if (val.Equals("ic", StringComparison.CurrentCultureIgnoreCase)) result = 0;
}
if (!result.HasValue)
_log.ErrorFormat("cannot read identity document type {0}", lookup);
return result;
}
internal byte? ReadShippingArea(string lookup)
{
string val = this.ReadText(lookup);
byte? result = null;
if (val != null)
{
if ((val.IndexOf("baltic", StringComparison.OrdinalIgnoreCase) >= 0) || (val.Equals("1"))) result = 0;
if ((val.IndexOf("europe", StringComparison.OrdinalIgnoreCase) >= 0) || (val.Equals("2"))) result = 1;
if ((val.IndexOf("overseas", StringComparison.OrdinalIgnoreCase) >= 0) || (val.Equals("3"))) result = 2;
}
if (!result.HasValue)
_log.ErrorFormat("cannot read shipping area {0}", lookup);
return result;
}
internal byte? ReadGeneralDescriptionOfCargo(string lookup)
{
string val = this.ReadText(lookup);
byte? result = null;
if (val != null)
{
if (val.Contains("container", StringComparison.OrdinalIgnoreCase) || val.Equals("1")) result = 0;
if (val.Contains("vehicles", StringComparison.OrdinalIgnoreCase) || val.Equals("2")) result = 1;
if (val.Contains("convent", StringComparison.OrdinalIgnoreCase) || val.Equals("3")) result = 2;
if (val.Contains("dry", StringComparison.OrdinalIgnoreCase) || val.Equals("4")) result = 3;
if (val.Contains("liquid", StringComparison.OrdinalIgnoreCase) || val.Equals("5")) result = 4;
if (val.Contains("empty", StringComparison.OrdinalIgnoreCase) || val.Equals("6")) result = 5;
}
if (!result.HasValue)
_log.ErrorFormat("cannot read general description of cargo {0}", lookup);
return result;
}
internal byte? ReadCargoHandlingType(string lookup)
{
string val = this.ReadText(lookup);
byte? result = null;
if(val != null)
{
if ((val.IndexOf("load", StringComparison.OrdinalIgnoreCase) >= 0) || val.Equals("1")) result = 0;
if ((val.IndexOf("discharge", StringComparison.OrdinalIgnoreCase) >= 0) || val.Equals("2")) result = 1;
if ((val.IndexOf("transit", StringComparison.OrdinalIgnoreCase) >= 0) || val.Equals("3")) result = 2;
}
if (!result.HasValue)
_log.ErrorFormat("cannot read cargo handling type {0}", lookup);
return result;
}
/// <summary>
/// read nationality field an returns 2 Char ISO code (optional lookup) and "confirms"
/// the field
/// </summary>
internal string ReadNationality(string lookup)
{
string val = this.ReadText(lookup);
if (val.Length == 2)
{
string isoCode = LocodeDB.CountryCodeFromName(val);
if (isoCode == null)
_log.ErrorFormat("Wrong ISO code {0}", val);
}
else
{
_log.ErrorFormat("cannot read nationality {0}", lookup);
}
return val;
}
internal byte? ReadHullConfiguration(string lookup)
{
string val = this.ReadText(lookup);
byte? result = null;
if (val != null)
{
if (val.IndexOf("sbt", StringComparison.OrdinalIgnoreCase) >= 0) result = 1;
if (val.IndexOf("single", StringComparison.OrdinalIgnoreCase) >= 0) result = 0;
if (val.IndexOf("double", StringComparison.OrdinalIgnoreCase) >= 0) result = 2;
}
if (!result.HasValue)
_log.ErrorFormat("cannot read hull configuration {0}", lookup);
return result;
}
internal byte? ReadPackingGroup(string lookup)
{
string val = this.ReadText(lookup);
byte? result = null;
if(val!= null)
{
if (val == "I") result = 1;
if (val == "II") result = 2;
if (val == "III") result = 3;
if (val.Equals("NONE", StringComparison.OrdinalIgnoreCase)) result = 0;
}
if (!result.HasValue)
_log.ErrorFormat("cannot read packing group {0}", lookup);
return result;
}
internal string ReadShip2ShipActivityType(string lookup)
{
string val = this.ReadText(lookup);
bool isValid = false;
if(!val.IsNullOrEmpty())
{
if (int.TryParse(val, out int typeVal))
{
if ((typeVal >= 1) && (typeVal <= 23))
isValid = true;
}
}
if (!isValid)
_log.WarnFormat("cannot read ship2ship activity type {0}", lookup);
return val;
}
internal byte? ReadConditionTanks(string lookup)
{
string val = this.ReadText(lookup);
byte? result = null;
if (val != null)
{
if (val.IndexOf("full", StringComparison.OrdinalIgnoreCase) >= 0) result = 0;
if (val.IndexOf("empty", StringComparison.OrdinalIgnoreCase) >= 0) result = 1;
if (val.IndexOf("inerted", StringComparison.OrdinalIgnoreCase) >= 0) result = 2;
}
if (!result.HasValue)
_log.ErrorFormat("cannot read condition tanks {0}", lookup);
return result;
}
internal byte? ReadDelivery(string lookup)
{
string val = this.ReadText(lookup);
byte? result = null;
if (val != null)
{
if ((val.IndexOf("all", StringComparison.OrdinalIgnoreCase) >= 0) || val.Equals("1")) result = 0;
if ((val.IndexOf("some", StringComparison.OrdinalIgnoreCase) >= 0) || val.Equals("2")) result = 1;
if ((val.IndexOf("none", StringComparison.OrdinalIgnoreCase) >= 0) || val.Equals("3")) result = 2;
}
if (!result.HasValue)
_log.ErrorFormat("cannot read delivery {0}", lookup);
return result;
}
internal DateTime? ReadBirthDate(string lookup)
{
DateTime? result = this.ReadDate(lookup);
if(result.HasValue)
{
if (result.Value > DateTime.Now)
_log.WarnFormat("Birth date implausible for {0} : {1}", lookup, result);
}
return result;
}
internal DateTime? ReadDate(string lookup, bool noHighlight = false)
{
try
{
DateTime? date = null;
if (_nameDict.ContainsKey(lookup))
{
var val = _nameDict[lookup].RefersToRange.Value;
if (val is DateTime)
{
date = val;
}
else if (val is double)
{
try
{
date = DateTime.FromOADate(val);
}
catch (ArgumentException) { /* .. */ }
if(date == null)
{
CultureInfo provider = CultureInfo.InvariantCulture;
string dateString = val.ToString();
const string format = "yyyyMMdd";
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out DateTime tmpDate))
date = tmpDate;
}
}
if (date == null)
{
if (DateTime.TryParse(val, out DateTime tmpDate))
date = tmpDate;
}
if (date != null)
{
if ((date.Value < new DateTime(1899, 1, 1)) || (date.Value > new DateTime(2030, 1, 1)))
{
date = null; // this can't be right
}
}
}
return date;
}
catch (Exception)
{
_log.WarnFormat("error parsing datetime for lookup {0}", lookup);
return null;
}
}
internal DateTime? ReadDateTime(string dateField, string timeField, bool noHighlight = false)
{
DateTime? result = null;
DateTime? etaDate = this.ReadDate(dateField, noHighlight);
DateTime? etaTime = this.ReadTime(timeField, noHighlight);
if (etaDate != null)
{
result = new DateTime(etaDate.Value.Year, etaDate.Value.Month, etaDate.Value.Day);
if (etaTime != null)
{
result = new DateTime(etaDate.Value.Year, etaDate.Value.Month, etaDate.Value.Day, etaTime.Value.Hour, etaTime.Value.Minute, etaTime.Value.Second, DateTimeKind.Local);
result = result.Value.ToUniversalTime();
}
}
return result;
}
internal DateTime? ReadTime(string lookup, bool noHighlight = false)
{
DateTime? result = null;
try
{
if (_nameDict.ContainsKey(lookup))
{
var val = _nameDict[lookup].RefersToRange.Value;
if (val is DateTime)
{
result = val;
}
if (val is double)
{
try
{
result = DateTime.FromOADate(val);
}
catch(ArgumentException) { }
if (result == null)
{
CultureInfo provider = CultureInfo.InvariantCulture;
string dateString = val.ToString();
if (!dateString.Contains(":"))
{
const string format = "HHmm";
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out DateTime tmpDate))
result = tmpDate;
}
}
}
if (result == null)
{
if (DateTime.TryParseExact(val, "HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault, out DateTime date))
result = date;
}
if (result == null)
{
if (DateTime.TryParseExact(val, "HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault, out DateTime date))
result = date;
}
if ((result == null) && (val != null))
{
CultureInfo provider = CultureInfo.InvariantCulture;
string dateString = val.ToString();
if (!dateString.Contains(":"))
{
const string format = "HHmm";
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out DateTime tmpDate))
result = tmpDate;
}
}
}
}
catch (Exception)
{
_log.WarnFormat("error reading time for lookup {0}", lookup);
}
return result;
}
internal double? ReadNumber(string lookup)
{
double? result = null;
try
{
if (_nameDict.ContainsKey(lookup))
{
var val = _nameDict[lookup].RefersToRange.Value;
if (val is double) result = val;
if (val is string)
{
if (double.TryParse(val, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite,
CultureInfo.InvariantCulture, out double tmpDouble))
result = tmpDouble;
if (result == null)
{
if (double.TryParse(val, out tmpDouble)) // current language style (==GER, mit , statt .)
result = tmpDouble;
}
}
if ((result == null) && (val != null))
{
double tmpDouble2 = val[1, 1];
result = tmpDouble2;
}
}
}
catch (Exception)
{
_log.WarnFormat("error reading number for lookup {0}", lookup);
}
return result;
}
internal double ReadNumberDefaultZero(string lookup)
{
double? result = this.ReadNumber(lookup);
if(!result.HasValue)
{
result = 0;
}
return result.Value;
}
internal bool? ReadBoolean(string lookup, bool noHighlight = false)
{
string val = this.ReadText(lookup);
if (val == null)
return null;
if ((val == "y") || (val == "Y") || val.Equals("yes", StringComparison.OrdinalIgnoreCase) || (val == "1") || (val == "x") || (val == "X"))
return true;
return false;
}
}
}

2913
ENI2/Import/ExcelUtil.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ using System.Data.SQLite;
using bsmd.database;
using log4net;
namespace bsmd.ExcelReadService
namespace ENI2.Locode
{
/// <summary>
/// Locodes suchen (zu Orten), die DB ist aus einem github Projekt: