// // 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; 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 _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(); 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; var val = _nameDict[lookup].RefersToRange.Value; var val2 = _nameDict[lookup].RefersToRange.Value2; if(val != null) return val.ToString(); if (val2 != null) return val2.ToString(); 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 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) this.HighlightLookup(lookup, ReadState.OK); else this.HighlightLookup(lookup, ReadState.WARN); } 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.WARN); } } } 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; } } }