git_bsmd/nsw/Source/bsmd.ExcelReadService/ExcelReader.cs

535 lines
20 KiB
C#

//
// 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.Drawing;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using bsmd.database;
namespace bsmd.ExcelReadService
{
public class ExcelReader : IDisposable
{
private ILog _log = LogManager.GetLogger(typeof(ExcelReader));
private Workbooks _excelWorkbooks;
private Workbook _portcall;
private Application _excelApp;
private Dictionary<string, Name> _nameDict;
private int okColor = ColorTranslator.ToOle(Color.FromArgb(200, 255, 200)); // light green
private int warnColor = ColorTranslator.ToOle(Color.FromArgb(255, 255, 200)); // yellow
private int failColor = ColorTranslator.ToOle(Color.FromArgb(255, 150, 150)); // light red
internal enum ReadState { NONE, OK, WARN, FAIL };
public ExcelReader(string filePath)
{
this._excelApp = new Application();
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>();
foreach(Name name in _portcall.Names)
{
_nameDict[name.Name] = name;
}
}
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;
}
internal void HighlightLookup(string lookup, ReadState state)
{
if (!_nameDict.ContainsKey(lookup)) return;
Range range = _nameDict[lookup].RefersToRange;
if(range != null)
{
switch(state)
{
case ReadState.FAIL:
range.Interior.Color = this.failColor; break;
case ReadState.WARN:
range.Interior.Color = this.warnColor; break;
case ReadState.OK:
range.Interior.Color = this.okColor; break;
case ReadState.NONE:
default:
break;
}
}
Marshal.ReleaseComObject(range);
}
internal string ReadText(string lookup)
{
if (!_nameDict.ContainsKey(lookup)) return null;
try
{
var val = _nameDict[lookup].RefersToRange.Value;
var val2 = _nameDict[lookup].RefersToRange.Value2;
if (val != null)
return val.ToString();
if (val2 != null)
return val2.ToString();
}
catch(COMException)
{
_log.WarnFormat("COMException reading field:{0}", lookup);
}
return null;
}
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())
{
string portName = LocodeDB.PortNameFromLocode(val);
if(portName == null)
{
this.HighlightLookup(lookup, ReadState.WARN);
}
else
{
this.HighlightLookup(lookup, ReadState.OK);
}
}
else
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
return val;
}
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)) {
this.HighlightLookup(lookup, ReadState.OK);
result = 0;
}
else if (val.Equals("f", StringComparison.CurrentCultureIgnoreCase) || val.Equals("female", StringComparison.CurrentCultureIgnoreCase))
{
this.HighlightLookup(lookup, ReadState.OK);
result = 1;
}
else
{
result = 2;
this.HighlightLookup(lookup, ReadState.WARN);
}
}
if(result == null)
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
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)) result = 0;
if (val.Equals("passport", StringComparison.CurrentCultureIgnoreCase)) result = 1;
if (val.Equals("muster_book", StringComparison.CurrentCultureIgnoreCase)) result = 2;
if (val.Equals("picture_id", StringComparison.CurrentCultureIgnoreCase)) result = 3;
if (val.Equals("residental_permit", StringComparison.CurrentCultureIgnoreCase)) result = 4;
if (val.Equals("other_legal_identity_document", StringComparison.CurrentCultureIgnoreCase)) result = 5;
if (val.Equals("ic", StringComparison.CurrentCultureIgnoreCase)) result = 0;
if (result == null)
this.HighlightLookup(lookup, ReadState.WARN);
else
this.HighlightLookup(lookup, ReadState.OK);
}
else
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
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) result = 0;
if (val.IndexOf("europe", StringComparison.OrdinalIgnoreCase) >= 0) result = 1;
if (val.IndexOf("overseas", StringComparison.OrdinalIgnoreCase) >= 0) result = 2;
if (result == null)
this.HighlightLookup(lookup, ReadState.WARN);
else
this.HighlightLookup(lookup, ReadState.OK);
}
else
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
return result;
}
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 == null)
this.HighlightLookup(lookup, ReadState.WARN);
else
this.HighlightLookup(lookup, ReadState.OK);
}
else
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
return result;
}
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 == null)
this.HighlightLookup(lookup, ReadState.WARN);
else
this.HighlightLookup(lookup, ReadState.OK);
}
else
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
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) result = 0;
if (val.IndexOf("some", StringComparison.OrdinalIgnoreCase) >= 0) result = 1;
if (val.IndexOf("none", StringComparison.OrdinalIgnoreCase) >= 0) result = 2;
if (result == null)
this.HighlightLookup(lookup, ReadState.WARN);
else
this.HighlightLookup(lookup, ReadState.OK);
}
else
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
return result;
}
public void Dispose()
{
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);
}
}
internal DateTime? ReadDate(string lookup)
{
try
{
DateTime? date = null;
if (_nameDict.ContainsKey(lookup))
{
var val = _nameDict[lookup].RefersToRange.Value;
if (val is DateTime) return val;
if (val is double)
{
try
{
date = DateTime.FromOADate(val);
}
catch (ArgumentException) { /* .. */ }
if(date == null)
{
CultureInfo provider = CultureInfo.InvariantCulture;
string dateString = val.ToString();
string format = "yyyyMMdd";
DateTime tmpDate;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out tmpDate))
date = tmpDate;
}
}
if (date == null)
{
DateTime tmpDate;
if (DateTime.TryParse(val, out tmpDate))
date = tmpDate;
}
// TODO: weitere varianten ausprobieren
if (date != null)
{
if ((date.Value < new DateTime(1900, 1, 1)) || (date.Value > new DateTime(2030, 1, 1)))
{
date = null;
this.HighlightLookup(lookup, ReadState.WARN);
}
else
{
this.HighlightLookup(lookup, ReadState.OK);
}
}
else
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
}
return date;
}
catch (Exception)
{
this.HighlightLookup(lookup, ReadState.FAIL);
_log.WarnFormat("error parsing datetime for lookup {0}", lookup);
return null;
}
}
internal DateTime? ReadDateTime(string dateField, string timeField)
{
DateTime? result = null;
DateTime? etaDate = this.ReadDate(dateField);
DateTime? etaTime = this.ReadTime(timeField);
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);
}
}
if(result.HasValue)
{
// wir haben local time gelesen, wird jetzt in UTC konvertiert
result = result.Value.ToUniversalTime();
}
return result;
}
internal DateTime? ReadTime(string lookup)
{
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();
string format = "HHmm";
DateTime tmpDate;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out tmpDate))
result = tmpDate;
}
}
if (result == null)
{
DateTime date;
if (DateTime.TryParseExact(val, "HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault, out date))
result = date;
}
if (result == null)
{
DateTime date;
if (DateTime.TryParseExact(val, "HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault, out date))
return date;
}
if ((result == null) && (val != null))
{
CultureInfo provider = CultureInfo.InvariantCulture;
string dateString = val.ToString();
string format = "HHmm";
DateTime tmpDate;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out tmpDate))
result = tmpDate;
}
if (result != null)
{
this.HighlightLookup(lookup, ReadState.OK);
}
else
{
this.HighlightLookup(lookup, ReadState.WARN);
}
}
}
catch (Exception)
{
this.HighlightLookup(lookup, ReadState.FAIL);
_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)
{
double tmpDouble;
if (double.TryParse(val, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite,
CultureInfo.InvariantCulture, out tmpDouble))
result = tmpDouble;
if (result == null)
{
if (double.TryParse(val, out tmpDouble)) // current language style (==GER, mit , statt .)
result = tmpDouble;
}
}
if (result != null)
{
this.HighlightLookup(lookup, ReadState.OK);
}
else
{
this.HighlightLookup(lookup, ReadState.FAIL);
}
}
}
catch (Exception)
{
this.HighlightLookup(lookup, ReadState.FAIL);
_log.WarnFormat("error reading number for lookup {0}", lookup);
}
return result;
}
internal bool? ReadBoolean(string lookup)
{
string val = this.ReadText(lookup);
if (val == null)
{
this.HighlightLookup(lookup, ReadState.FAIL);
return null;
}
this.HighlightLookup(lookup, ReadState.OK);
if ((val == "y") || (val == "Y") || val.Equals("yes", StringComparison.OrdinalIgnoreCase) || (val == "1") || (val == "x") || (val == "X"))
return true;
return false;
}
}
}