225 lines
6.8 KiB
C#
225 lines
6.8 KiB
C#
// Copyright (c) 2017-today Informatikbüro Daniel Schick
|
|
// Base class excel access (named ranges, colorizing, etc.)
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using ClosedXML.Excel;
|
|
using log4net;
|
|
using System.Globalization;
|
|
using System.Text.RegularExpressions;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
|
|
namespace ENI2.Excel
|
|
{
|
|
internal class ExcelBase : IDisposable
|
|
{
|
|
|
|
#region Fields
|
|
|
|
internal enum CountryMode { NONE, DE, DK };
|
|
|
|
protected CountryMode _countryMode = CountryMode.DE;
|
|
|
|
protected XLWorkbook _workBook;
|
|
protected Dictionary<string, IXLDefinedName> _nameDict;
|
|
protected ILog _log;
|
|
|
|
#endregion Fields
|
|
|
|
#region Construction
|
|
|
|
public ExcelBase()
|
|
{
|
|
_log = LogManager.GetLogger(this.GetType().Name);
|
|
}
|
|
|
|
#endregion Construction
|
|
|
|
#region Properties
|
|
|
|
internal CountryMode Mode { get { return _countryMode; } }
|
|
|
|
internal Dictionary<string, IXLDefinedName> NameDict { get { return _nameDict; } }
|
|
|
|
internal IXLWorksheets Worksheets { get { return _workBook?.Worksheets; } }
|
|
|
|
#endregion
|
|
|
|
#region protected methods
|
|
|
|
protected void InitNameFields()
|
|
{
|
|
_nameDict = new Dictionary<string, IXLDefinedName>();
|
|
int bookCnt = 0;
|
|
|
|
// Get workbook-level defined names
|
|
foreach (var definedName in _workBook.DefinedNames)
|
|
{
|
|
string nameKey = definedName.Name;
|
|
|
|
try
|
|
{
|
|
// Handle sheet-scoped names (Sheet1!Name format)
|
|
if (nameKey.Contains("!"))
|
|
nameKey = nameKey.Substring(nameKey.IndexOf('!') + 1);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
_log.DebugFormat("Strange name in Sheet: {0}", nameKey);
|
|
continue;
|
|
}
|
|
|
|
// Check if the defined name is valid (not a broken reference)
|
|
if (definedName.IsValid)
|
|
{
|
|
_nameDict[nameKey] = definedName;
|
|
bookCnt++;
|
|
}
|
|
}
|
|
_log.DebugFormat("{0} defined names found at Workbook level", bookCnt);
|
|
|
|
// Get worksheet-level defined names
|
|
foreach (var ws in _workBook.Worksheets)
|
|
{
|
|
int wsCnt = 0;
|
|
foreach (var definedName in ws.DefinedNames)
|
|
{
|
|
string nameKey = definedName.Name;
|
|
|
|
if (!_nameDict.ContainsKey(nameKey))
|
|
{
|
|
if (definedName.IsValid)
|
|
{
|
|
_nameDict[nameKey] = definedName;
|
|
wsCnt++;
|
|
}
|
|
}
|
|
}
|
|
if (wsCnt > 0)
|
|
_log.DebugFormat("{0} defined names found in Worksheet {1}", wsCnt, ws.Name);
|
|
}
|
|
}
|
|
|
|
private static double? ParseAnyDouble(string val)
|
|
{
|
|
double? result = null;
|
|
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;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal double? ReadNumber(string lookup)
|
|
{
|
|
double? result = null;
|
|
try
|
|
{
|
|
if (_nameDict.ContainsKey(lookup))
|
|
{
|
|
var definedName = _nameDict[lookup];
|
|
var ranges = definedName.Ranges;
|
|
var range = ranges.FirstOrDefault();
|
|
|
|
if (range != null)
|
|
{
|
|
var cell = range.FirstCell();
|
|
if (cell != null)
|
|
{
|
|
var cellValue = cell.Value;
|
|
|
|
if (cellValue.IsNumber)
|
|
{
|
|
result = cellValue.GetNumber();
|
|
}
|
|
else if (cellValue.IsText)
|
|
{
|
|
string textVal = cellValue.GetText();
|
|
if (!string.IsNullOrEmpty(textVal))
|
|
{
|
|
result = ParseAnyDouble(textVal);
|
|
|
|
if (result == null)
|
|
{
|
|
Match m = Regex.Match(textVal, "([0-9\\.\\,]+)([a-zA-Z]*)");
|
|
if (m.Success)
|
|
{
|
|
result = ParseAnyDouble(m.Groups[1].Value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
_log.WarnFormat("error reading number for lookup {0}", lookup);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal void Colorize(string lookup, int color)
|
|
{
|
|
if (_nameDict.ContainsKey(lookup))
|
|
{
|
|
var definedName = _nameDict[lookup];
|
|
var ranges = definedName.Ranges;
|
|
var range = ranges.FirstOrDefault();
|
|
if (range != null)
|
|
{
|
|
Colorize(range, color);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void Colorize(IXLRange range, int color)
|
|
{
|
|
// Convert int color to Color object
|
|
Color backgroundColor = Color.FromArgb(color);
|
|
range.Style.Fill.BackgroundColor = XLColor.FromColor(backgroundColor);
|
|
|
|
// Set worksheet tab color
|
|
range.Worksheet.SetTabColor(XLColor.FromColor(backgroundColor));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public methods
|
|
|
|
public void Save(string path)
|
|
{
|
|
_workBook.SaveAs(path);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Dispose
|
|
|
|
public void Dispose()
|
|
{
|
|
try
|
|
{
|
|
if (_workBook != null)
|
|
{
|
|
_log.Debug("Disposing Workbook");
|
|
_workBook.Dispose();
|
|
_workBook = null;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.ErrorFormat("Exception disposing ExcelBase: {0}", ex.Message);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
} |