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

201 lines
7.6 KiB
C#

using log4net;
using Microsoft.Office.Interop.Excel;
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
namespace bsmd.ExcelReadService
{
/// <summary>
/// Kapselt die Implementierung / Schreiben des Bestätigungs-Sheets. Bisher wurde das Highlighting direkt in das ursprüngl. Sheet
/// übernommen. Da die Bestätigung aber anders aussieht und aus mehreren Sheets bestehen kann ist das jetzt abgetrennt in einer
/// eignenen Klasse. Der Pfad zu den Templates ist in den Settings hinterlegt, die Klasse wird mit der entspr. Collection aufgerufen
/// Das wiederum ergibt sich aus dem Zielhafen in PoC.
/// </summary>
internal class Confirmation : IDisposable
{
private static ILog _log = LogManager.GetLogger(typeof(Confirmation));
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
private int whiteColor = ColorTranslator.ToOle(Color.White);
private List<Workbook> workbooks = new List<Workbook>();
private List<Dictionary<string, Name>> nameDicts = new List<Dictionary<string, Name>>();
private List<string> templateNames = new List<string>();
private List<Dictionary<string, string>> actualNameDict = null;
#region Construction
public Confirmation(System.Collections.Specialized.StringCollection sheetCollection, Application excelInstance)
{
string nameDictKey = "";
foreach (string template in sheetCollection)
{
try
{
nameDictKey += template;
// die Templates sollten echte Excel Templates (.xlst) sein
Workbook aWorkbook = excelInstance.Workbooks.Open(template, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, false, false, false);
/*
if (aWorkbook == excelInstance.ActiveWorkbook)
_log.Info("aWorkbook is active workbook");
else
aWorkbook.Activate();
*/
Dictionary<string, Name> nameDict = new Dictionary<string, Name>();
// hier müsste etwas hin das nur aus der eben geladenen Vorlage die Namen rauszieht..
// eben nicht aus *allen* Vorlagen. Das funktioniert auch nur liefern einige der Names keine Ranges..
foreach(Name workbookName in aWorkbook.Names)
{
_log.Info(workbookName.Name);
if (workbookName.Name.Contains("!"))
{
continue;
}
else
{
nameDict[workbookName.Name] = workbookName;
}
}
workbooks.Add(aWorkbook);
nameDicts.Add(nameDict);
templateNames.Add(Path.GetFileNameWithoutExtension(template));
}
catch(Exception ex)
{
_log.ErrorFormat("Failure creating sheet from template {0}:{1}", template, ex.Message);
}
}
}
#endregion
#region public
public void ConfirmText(string lookup, string value, ExcelReader.ReadState state)
{
this.ConfirmValue(lookup, value, state);
}
public void ConfirmNumber(string lookup, double? value, ExcelReader.ReadState state)
{
this.ConfirmValue(lookup, value, state);
}
public void ConfirmDate(string lookup, DateTime? value, ExcelReader.ReadState state)
{
this.ConfirmValue(lookup, value, state);
}
public void ConfirmTime(string lookup, DateTime? value, ExcelReader.ReadState state)
{
this.ConfirmValue(lookup, value, state);
}
public List<string> SaveConfirmationSheets(string receivedFileName)
{
List<string> result = new List<string>();
for(int i=0;i<this.workbooks.Count;i++)
{
// construct file path
string fileNameWithPath = Path.Combine(Path.GetDirectoryName(receivedFileName),
string.Format("{0}_{1}.xlsx", this.templateNames[i], Path.GetFileNameWithoutExtension(receivedFileName)));
this.workbooks[i].SaveAs(fileNameWithPath, XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
this.workbooks[i].Saved = true;
result.Add(fileNameWithPath);
this.workbooks[i].Close();
}
return result;
}
public void Dispose()
{
for (int i = 0; i < this.workbooks.Count; i++)
{
this.workbooks[i].Close();
this.workbooks[i] = null;
}
}
#endregion
#region private
private void ConfirmValue(string lookup, object value, ExcelReader.ReadState state)
{
for(int i=0;i<this.workbooks.Count;i++)
{
Workbook workbook = this.workbooks[i];
Dictionary<string, Name> nameDict = this.nameDicts[i];
Name someName = null;
if(nameDict.ContainsKey(lookup))
{
try
{
someName = nameDict[lookup];
Range range = someName.RefersToRange;
if (range != null)
{
range.Interior.Color = this.ColorForState(state);
range.Value = value;
}
Marshal.ReleaseComObject(range);
_log.InfoFormat("Value {0} for lookup {1} OK", value, lookup);
}
catch(Exception ex)
{
_log.WarnFormat("cannot set value {0} for lookup {1}: {2}",
value, lookup, ex.Message);
}
}
}
}
private int ColorForState(ExcelReader.ReadState state)
{
switch (state)
{
case ExcelReader.ReadState.FAIL:
return this.failColor;
case ExcelReader.ReadState.WARN:
return this.warnColor;
case ExcelReader.ReadState.OK:
return this.okColor;
case ExcelReader.ReadState.NONE:
default:
break;
}
return this.whiteColor;
}
#endregion
}
}