123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Xml.Linq;
- using InABox.Core;
- using NPOI.SS.Formula.Functions;
- using NPOI.SS.UserModel;
- using NPOI.XSSF.UserModel;
- using NCell = NPOI.SS.UserModel.ICell;
- using NRow = NPOI.SS.UserModel.IRow;
- using NFont = NPOI.SS.UserModel.IFont;
- using NSheet = NPOI.SS.UserModel.ISheet;
- using NDataFormat = NPOI.SS.UserModel.IDataFormat;
- using NCellStyle = NPOI.SS.UserModel.ICellStyle;
- using NCellType = NPOI.SS.UserModel.CellType;
- using NPOI.SS.Util;
- using NPOI.OpenXmlFormats.Spreadsheet;
- using System.Security.Policy;
- using System.Drawing;
- using NPOI.HSSF.Util;
- using NPOI.HSSF.UserModel;
- using NPOI.XWPF.UserModel;
- namespace InABox.Scripting
- {
- public class RowEnumerator : IEnumerator<Row>
- {
- public Sheet Sheet { get; }
- private IEnumerator _enumerator { get; set; }
- public Row Current => new Row((_enumerator.Current as NRow)!, Sheet);
- object IEnumerator.Current => new Row((_enumerator.Current as NRow)!, Sheet);
- internal RowEnumerator(IEnumerator enumerator, Sheet sheet)
- {
- _enumerator = enumerator;
- Sheet = sheet;
- }
- public bool MoveNext()
- {
- return _enumerator.MoveNext();
- }
- public void Reset()
- {
- _enumerator.Reset();
- }
- public void Dispose()
- {
- }
- }
- public class Sheet : ISheet
- {
- private NSheet _sheet;
- public string Name => _sheet.SheetName;
- public int FirstRow => _sheet.FirstRowNum;
- public int LastRow => _sheet.LastRowNum;
- public Spreadsheet Spreadsheet { get; }
- ISpreadsheet ISheet.Spreadsheet => Spreadsheet;
- internal Sheet(NSheet sheet, Spreadsheet spreadsheet)
- {
- _sheet = sheet;
- Spreadsheet = spreadsheet;
- }
- public IEnumerable<IRow> Rows()
- {
- var enumerator = _sheet.GetRowEnumerator();
- var row = 0;
- while (enumerator.MoveNext() && row <= int.MaxValue)
- {
- yield return new Row((NRow)enumerator.Current, this);
- row++;
- }
- }
- public IEnumerator<IRow> RowEnumerator()
- {
- return new RowEnumerator(_sheet.GetRowEnumerator(), this);
- }
- public IRow NewRow()
- {
- var row = _sheet.CreateRow(_sheet.LastRowNum + 1);
- return new Row(row, this);
- }
- public IRow? GetRow(int row)
- {
- var nRow = _sheet.GetRow(row);
- if (nRow is null) return null;
- return new Row(nRow, this);
- }
- public float GetRowHeight(int row)
- {
- return _sheet.GetRow(row)?.HeightInPoints ?? _sheet.DefaultRowHeightInPoints;
- }
- public float GetDefaultRowHeight() => _sheet.DefaultRowHeightInPoints;
- public float GetColumnWidth(int column)
- {
- if (_sheet.IsColumnHidden(column)) return 0f;
- var width = _sheet.GetColumnWidth(column) / 256f;
- if (width <= 0f) return float.MinValue;
- return width;
- }
- public ISheet SetColumnWidth(int column, float charWidth)
- {
- _sheet.SetColumnWidth(column, (int)Math.Round(charWidth * 256));
- return this;
- }
- public ISheet MergeCells(int firstRow, int lastRow, int firstColumn, int lastColumn)
- {
- var range = new CellRangeAddress(firstRow, lastRow, firstColumn, lastColumn);
- _sheet.AddMergedRegion(range);
- return this;
- }
- public IEnumerable<CellRange> GetMergedCells()
- {
- foreach(var region in _sheet.MergedRegions)
- {
- yield return new CellRange(region.FirstRow, region.LastRow, region.FirstColumn, region.LastColumn);
- }
- }
- }
- public class Row : IRow
- {
- private NRow _row;
- public int RowNumber => _row.RowNum;
- public int FirstColumn => _row.FirstCellNum;
- public int LastColumn => _row.LastCellNum;
- public Sheet Sheet { get; }
- ISheet IRow.Sheet => Sheet;
- internal Row(NRow row, Sheet sheet)
- {
- _row = row;
- Sheet = sheet;
- }
- public string ExtractString(int column, bool uppercase = false)
- {
- try
- {
- var result = "";
- var cell = _row.GetCell(column, MissingCellPolicy.CREATE_NULL_AS_BLANK);
- if (cell.CellType == NCellType.Numeric)
- result = cell.NumericCellValue.ToString();
- else
- result = cell.StringCellValue;
- if (string.IsNullOrWhiteSpace(result))
- result = "";
- return uppercase ? result.ToUpper() : result;
- }
- catch (Exception e)
- {
- throw new Exception(string.Format("Row {0}:[{1}:{2}]: {3}", _row.Sheet.SheetName, _row.RowNum + 1, column, e.Message));
- }
- }
- public DateTime ExtractDateTime(int column)
- {
- try
- {
- var cell = _row.GetCell(column, MissingCellPolicy.CREATE_NULL_AS_BLANK);
- try
- {
- return cell.DateCellValue;
- }
- catch
- {
- var sDate = cell.StringCellValue;
- DateTime.TryParse(sDate, out var result);
- return result;
- }
- }
- catch (Exception e)
- {
- throw new Exception(string.Format("Row {0}:[{1}:{2}]: {3}", _row.Sheet.SheetName, _row.RowNum + 1, column, e.Message));
- }
- }
- public double? ExtractDouble(int column)
- {
- try
- {
- double result = 0.0F;
- var cell = _row.GetCell(column, MissingCellPolicy.CREATE_NULL_AS_BLANK);
- if (cell.CellType == NCellType.Numeric || cell.CellType == NCellType.Formula)
- result = cell.NumericCellValue;
- else if (cell.CellType == NCellType.String)
- result = double.Parse(cell.StringCellValue);
- return result;
- }
- catch (FormatException)
- {
- return null;
- }
- catch (Exception e)
- {
- throw new Exception(string.Format("Row {0}:[{1}:{2}]: {3}", _row.Sheet.SheetName, _row.RowNum + 1, column, e.Message));
- }
- }
- public int GetColumn(string name, bool throwException = true)
- {
- var cells = _row.GetEnumerator();
- while (cells.MoveNext())
- {
- var cell = cells.Current;
- if (!string.IsNullOrWhiteSpace(cell.StringCellValue) && cell.StringCellValue.ToUpper().Trim().Equals(name.ToUpper().Trim()))
- {
- return cell.ColumnIndex;
- }
- }
- if (!throwException)
- {
- return -1;
- }
- throw new Exception("Unable to find Column: " + name);
- }
- public ICell? GetCell(int column)
- {
- var nCell = _row.GetCell(column);
- if (nCell is null) return null;
- return new Cell(nCell, this);
- }
- public ICell NewCell(int column)
- {
- var cell = _row.CreateCell(column);
- return new Cell(cell, this);
- }
- public IEnumerable<ICell> Cells()
- {
- foreach(var cell in _row)
- {
- yield return new Cell(cell, this);
- }
- }
- }
- public class Cell : ICell
- {
- private NCell _cell;
- IRow ICell.Row => Row;
- public Row Row { get; }
- internal Cell(NCell cell, Row row)
- {
- _cell = cell;
- Row = row;
- }
- private CellType ConvertCellType(NCellType type)
- {
- return type switch
- {
- NCellType.Formula => CellType.Numeric,
- NCellType.Numeric => CellType.Numeric,
- NCellType.Error => CellType.Error,
- NCellType.String => CellType.String,
- NCellType.Boolean => CellType.Boolean,
- NCellType.Blank => CellType.Blank,
- _ or NCellType.Unknown => CellType.Unknown
- };
- }
- public CellType GetCellType()
- {
- if (_cell.CellType == NCellType.Formula)
- {
- return ConvertCellType(_cell.CachedFormulaResultType);
- }
- else if(_cell.CellType == NCellType.Numeric && DateUtil.IsCellDateFormatted(_cell))
- {
- return CellType.Date;
- }
- return ConvertCellType(_cell.CellType);
- }
- public string GetValue()
- {
- if (_cell.CellType == NCellType.Formula)
- {
- if (_cell.CachedFormulaResultType == NCellType.Numeric)
- return string.Format("{0:F}", _cell.NumericCellValue.ToString());
- return _cell.StringCellValue;
- }
- return _cell.ToString() ?? "";
- }
- public bool? GetBoolValue()
- {
- try
- {
- if (_cell.CellType == NCellType.Boolean)
- return _cell.BooleanCellValue;
- return null;
- }
- catch (Exception)
- {
- return null;
- }
- }
- public double? GetDoubleValue()
- {
- try
- {
- double result = 0.0F;
- if (_cell.CellType == NCellType.Numeric || _cell.CellType == NCellType.Formula)
- result = _cell.NumericCellValue;
- else if (_cell.CellType == NCellType.String)
- result = double.Parse(_cell.StringCellValue);
- return result;
- }
- catch (Exception)
- {
- return null;
- }
- }
- public DateTime GetDateTimeValue()
- {
- try
- {
- return _cell.DateCellValue;
- }
- catch
- {
- var sDate = _cell.StringCellValue;
- if(!DateTime.TryParse(sDate, out var result)){
- return DateTime.MinValue;
- }
- return result;
- }
- }
- public byte? GetByteValue()
- {
- try
- {
- byte result = 0;
- if (_cell.CellType == NCellType.Numeric || _cell.CellType == NCellType.Formula)
- result = (byte)_cell.NumericCellValue;
- else if (_cell.CellType == NCellType.String)
- result = byte.Parse(_cell.StringCellValue);
- return result;
- }
- catch (Exception)
- {
- return null;
- }
- }
- public ICell SetValue(bool value)
- {
- _cell.SetCellValue(value);
- return this;
- }
- public ICell SetValue(double value)
- {
- _cell.SetCellValue(value);
- return this;
- }
- public ICell SetValue(string value)
- {
- _cell.SetCellValue(value);
- return this;
- }
- public ICell SetValue(byte value)
- {
- _cell.SetCellValue(value);
- return this;
- }
- public ICell SetValue(DateTime value)
- {
- _cell.SetCellValue(value);
- return this;
- }
- public ICell SetBlank()
- {
- _cell.SetBlank();
- return this;
- }
- public ICellStyle GetStyle()
- {
- return new CellStyle(_cell.CellStyle, Row.Sheet.Spreadsheet);
- }
- public ICell SetStyle(ICellStyle style)
- {
- _cell.CellStyle = (style as CellStyle)!._style;
- return this;
- }
- }
- public class SheetEnumerator : IEnumerator<Sheet>
- {
- public Spreadsheet Spreadsheet { get; }
- public Sheet Current => new(_enumerator.Current, Spreadsheet);
- private IEnumerator<NSheet> _enumerator { get; }
- object IEnumerator.Current => new Sheet(_enumerator.Current, Spreadsheet);
- internal SheetEnumerator(IEnumerator<NSheet> enumerator, Spreadsheet spreadsheet)
- {
- _enumerator = enumerator;
- Spreadsheet = spreadsheet;
- }
- public void Dispose()
- {
- _enumerator.Dispose();
- }
- public bool MoveNext()
- {
- return _enumerator.MoveNext();
- }
- public void Reset()
- {
- _enumerator.Reset();
- }
- }
- public class DataFormat : IDataFormat
- {
- public short FormatIndex { get; }
- public DataFormat(short format)
- {
- FormatIndex = format;
- }
- }
- public class Font : IFont
- {
- public Spreadsheet Spreadsheet { get; set; }
- internal NFont _font { get; }
- public bool Bold { get => _font.IsBold; set => _font.IsBold = value; }
- public bool Italic { get => _font.IsItalic; set => throw new NotImplementedException(); }
- public UnderlineType Underline
- {
- get => _font.Underline switch
- {
- FontUnderlineType.None => UnderlineType.None,
- FontUnderlineType.Single => UnderlineType.Single,
- FontUnderlineType.Double => UnderlineType.Double,
- FontUnderlineType.SingleAccounting => UnderlineType.SingleAccounting,
- FontUnderlineType.DoubleAccounting => UnderlineType.DoubleAccounting,
- _ => UnderlineType.None,
- };
- set
- {
- _font.Underline = value switch
- {
- UnderlineType.None => FontUnderlineType.None,
- UnderlineType.Single => FontUnderlineType.Single,
- UnderlineType.Double => FontUnderlineType.Double,
- UnderlineType.SingleAccounting => FontUnderlineType.SingleAccounting,
- UnderlineType.DoubleAccounting => FontUnderlineType.DoubleAccounting,
- _ => FontUnderlineType.None
- };
- }
- }
- public Color Colour {
- get
- {
- if(_font is XSSFFont xFont)
- {
- return CellStyle.ConvertColour(xFont.GetXSSFColor());
- }
- else if(_font is HSSFFont hFont && Spreadsheet.Workbook is HSSFWorkbook workbook)
- {
- return CellStyle.ConvertColour(hFont.GetHSSFColor(workbook));
- }
- else
- {
- return CellStyle.ColourFromIndex(_font.Color);
- }
- }
- }
- public double FontSize { get => _font.FontHeightInPoints; set => _font.FontHeightInPoints = value; }
- public Font(NFont font, Spreadsheet spreadsheet)
- {
- _font = font;
- Spreadsheet = spreadsheet;
- }
- }
- public class CellStyle : ICellStyle
- {
- internal NCellStyle _style { get; }
- public IDataFormat DataFormat {
- get => new DataFormat(_style.DataFormat);
- set => _style.DataFormat = value.FormatIndex;
- }
- ISpreadsheet ICellStyle.Spreadsheet => Spreadsheet;
- public Spreadsheet Spreadsheet { get; }
- public Color Background => ConvertColour(_style.FillForegroundColorColor);
- public Color Foreground => ColourFromIndex(_style.GetFont(Spreadsheet.Workbook).Color);
- public IFont Font => new Font(_style.GetFont(Spreadsheet.Workbook), Spreadsheet);
- public CellAlignment VerticalAlignment => _style.VerticalAlignment switch
- {
- NPOI.SS.UserModel.VerticalAlignment.Top => CellAlignment.Start,
- NPOI.SS.UserModel.VerticalAlignment.Bottom => CellAlignment.End,
- NPOI.SS.UserModel.VerticalAlignment.Justify => CellAlignment.Justify,
- _ => CellAlignment.Middle
- };
- public CellAlignment HorizontalAlignment => _style.Alignment switch
- {
- NPOI.SS.UserModel.HorizontalAlignment.Center => CellAlignment.Middle,
- NPOI.SS.UserModel.HorizontalAlignment.Right => CellAlignment.End,
- NPOI.SS.UserModel.HorizontalAlignment.Justify => CellAlignment.Justify,
- _ => CellAlignment.Start
- };
- public bool WrapText => _style.WrapText;
-
- public CellStyle(NCellStyle style, Spreadsheet spreadsheet)
- {
- _style = style;
- Spreadsheet = spreadsheet;
- }
- public static Color ColourFromIndex(short index)
- {
- int indexNum = index;
- var hashIndex = HSSFColor.GetIndexHash();
- HSSFColor? indexed = null;
- if (hashIndex.ContainsKey(indexNum))
- indexed = hashIndex[indexNum];
- if (indexed != null)
- {
- byte[] rgb = new byte[3];
- rgb[0] = (byte)indexed.GetTriplet()[0];
- rgb[1] = (byte)indexed.GetTriplet()[1];
- rgb[2] = (byte)indexed.GetTriplet()[2];
- return Color.FromArgb(255, rgb[0], rgb[1], rgb[2]);
- }
- return Color.Empty;
- }
- public static Color ConvertColour(IColor? colour)
- {
- if(colour is null)
- {
- return Color.Empty;
- }
- if(colour is ExtendedColor extendedColour)
- {
- if (extendedColour.IsIndexed)
- {
- return ColourFromIndex(extendedColour.Index);
- }
- else
- {
- var rgb = extendedColour.RGBWithTint;
- return Color.FromArgb(255, rgb[0], rgb[1], rgb[2]);
- }
- }
- else if(colour is HSSFColor hssfColour)
- {
- var rgb = hssfColour.RGB;
- return Color.FromArgb(255, rgb[0], rgb[1], rgb[2]);
- }
- else
- {
- Logger.Send(LogType.Error, "", $"Unknown NPOI Colour class {colour.GetType()}");
- return Color.Empty;
- }
- }
- }
- public class Spreadsheet : ISpreadsheet
- {
- public IWorkbook Workbook;
- private NDataFormat DataFormat;
- private Spreadsheet(IWorkbook workbook)
- {
- Workbook = workbook;
- DataFormat = Workbook.CreateDataFormat();
- }
- public Spreadsheet(string fileName) : this(WorkbookFactory.Create(fileName)) { }
- public Spreadsheet(Stream file) : this(WorkbookFactory.Create(file)) { }
- public Spreadsheet() : this(new XSSFWorkbook()) { }
- public ISheet GetSheet(int index)
- {
- return new Sheet(Workbook.GetSheetAt(index), this);
- }
- public ISheet GetSheet(string name)
- {
- return new Sheet(Workbook.GetSheet(name), this);
- }
- public IEnumerator<ISheet> SheetEnumerator()
- {
- var enumerator = Workbook.GetEnumerator();
- return new SheetEnumerator(enumerator, this);
- }
- public IEnumerable<ISheet> Sheets()
- {
- for (var i = 0; i < Workbook.NumberOfSheets; i++)
- yield return GetSheet(i);
- }
- public void Write(FileStream file)
- {
- Workbook.Write(file);
- }
- public void Write(string filename, FileMode mode = FileMode.Create)
- {
- using(var stream = new FileStream(filename, FileMode.Create))
- {
- Workbook.Write(stream);
- }
- }
- public ISheet NewSheet(string name)
- {
- var sheet = Workbook.CreateSheet(name);
- return new Sheet(sheet, this);
- }
- public ISheet NewSheet()
- {
- var sheet = Workbook.CreateSheet();
- return new Sheet(sheet, this);
- }
- public ICellStyle NewStyle()
- {
- var style = Workbook.CreateCellStyle();
- var x = style.GetDataFormatString();
- return new CellStyle(style, this);
- }
- public IDataFormat GetDataFormat(string format)
- {
- var dataFormat = DataFormat.GetFormat(format);
- return new DataFormat(dataFormat);
- }
- }
- }
|