From 448848538700cd1631c895e3d25cf5e57da22bab Mon Sep 17 00:00:00 2001 From: claudiamurialdo <33756655+claudiamurialdo@users.noreply.github.com> Date: Tue, 4 Jul 2023 12:49:27 -0300 Subject: [PATCH] Add Genexus Office module implementation using NPoi (#832) * Add Genexus Office module implementation using NPoi * Fix camel case on some namespaces. * Change .NET package name * Replace Get/Set methods by Properties. * Fix build error. * Uses NPOI 2.5.6 for package compatibility on System.Text.Encoding.CodePages, System.Security.Cryptography.Pkcs and System.Security.Cryptography.Xml. * Fix error "Offset and length were out of bounds for the array or count is greater .." when disposing ByteArrayInputStream. * ExcelSpreadsheet.Open("test.xlsx") on an existing file was locking the file so that the following &ExcelSpreadsheet.Save() failed. Replace FontHeight (which is in unit's of 1/20th of a point) by FontHeightInPoints which is in points. * Fix template path. --- dotnet/DotNetStandardClasses.sln | 26 +- .../src/dotnetcore/GxOffice/GxOffice.csproj | 52 + .../src/dotnetframework/GxOffice/Constants.cs | 14 + .../dotnetframework/GxOffice/ExcelFactory.cs | 27 + .../GxOffice/ExcelSpreadsheetGXWrapper.cs | 414 ++++++ .../dotnetframework/GxOffice/GxOffice.csproj | 19 + .../GxOffice/IExcelCellRange.cs | 41 + .../GxOffice/IExcelSpreadsheet.cs | 34 + .../GxOffice/IExcelWorksheet.cs | 13 + .../src/dotnetframework/GxOffice/IGXError.cs | 8 + .../exception/ExcelDocumentNotSupported.cs | 9 + .../GxOffice/exception/ExcelException.cs | 32 + .../exception/ExcelReadonlyException.cs | 9 + .../ExcelTemplateNotFoundException.cs | 9 + .../GxOffice/poi/xssf/ExcelCells.cs | 1304 +++++++++++++++++ .../GxOffice/poi/xssf/ExcelSpreadsheet.cs | 523 +++++++ .../GxOffice/poi/xssf/ExcelWorksheet.cs | 85 ++ .../GxOffice/poi/xssf/StylesCache.cs | 47 + .../GxOffice/style/ExcelAlignment.cs | 39 + .../GxOffice/style/ExcelBorder.cs | 25 + .../GxOffice/style/ExcelCellBorder.cs | 40 + .../GxOffice/style/ExcelColor.cs | 49 + .../GxOffice/style/ExcelFill.cs | 19 + .../GxOffice/style/ExcelFont.cs | 80 + .../GxOffice/style/ExcelStyle.cs | 68 + .../GxOffice/style/ExcelStyleDimension.cs | 17 + .../DotNetCoreUnitTest.csproj | 1 + .../DotNetCoreUnitTest/Excel/ExcelPoiTest.cs | 1191 +++++++++++++++ .../test/DotNetUnitTest/DotNetUnitTest.csproj | 1 + 29 files changed, 4193 insertions(+), 3 deletions(-) create mode 100644 dotnet/src/dotnetcore/GxOffice/GxOffice.csproj create mode 100644 dotnet/src/dotnetframework/GxOffice/Constants.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/ExcelFactory.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/ExcelSpreadsheetGXWrapper.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/GxOffice.csproj create mode 100644 dotnet/src/dotnetframework/GxOffice/IExcelCellRange.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/IExcelSpreadsheet.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/IExcelWorksheet.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/IGXError.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/exception/ExcelDocumentNotSupported.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/exception/ExcelException.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/exception/ExcelReadonlyException.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/exception/ExcelTemplateNotFoundException.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelCells.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelSpreadsheet.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelWorksheet.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/poi/xssf/StylesCache.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/style/ExcelAlignment.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/style/ExcelBorder.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/style/ExcelCellBorder.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/style/ExcelColor.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/style/ExcelFill.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/style/ExcelFont.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/style/ExcelStyle.cs create mode 100644 dotnet/src/dotnetframework/GxOffice/style/ExcelStyleDimension.cs create mode 100644 dotnet/test/DotNetCoreUnitTest/Excel/ExcelPoiTest.cs diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index e6f63c4b3..8650b334f 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -233,7 +233,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCoreOpenTelemetryTest {5937CEC2-5C16-4650-B0E6-78CD34357384} = {5937CEC2-5C16-4650-B0E6-78CD34357384} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApp", "test\TestApp\TestApp.csproj", "{5937CEC2-5C16-4650-B0E6-78CD34357384}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp", "test\TestApp\TestApp.csproj", "{5937CEC2-5C16-4650-B0E6-78CD34357384}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GxOffice", "src\dotnetframework\GxOffice\GxOffice.csproj", "{0CD32C8A-496A-46A2-9270-8B03421BADA2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "excel", "excel", "{BE108BE8-805D-4FCF-86BA-B2EAF581FFB2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GxOffice", "src\dotnetcore\GxOffice\GxOffice.csproj", "{E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "excel", "excel", "{B521FF6D-E081-4DE6-AC00-A9BE3B6439D1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -569,6 +577,14 @@ Global {5937CEC2-5C16-4650-B0E6-78CD34357384}.Debug|Any CPU.Build.0 = Debug|Any CPU {5937CEC2-5C16-4650-B0E6-78CD34357384}.Release|Any CPU.ActiveCfg = Release|Any CPU {5937CEC2-5C16-4650-B0E6-78CD34357384}.Release|Any CPU.Build.0 = Release|Any CPU + {0CD32C8A-496A-46A2-9270-8B03421BADA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0CD32C8A-496A-46A2-9270-8B03421BADA2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0CD32C8A-496A-46A2-9270-8B03421BADA2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0CD32C8A-496A-46A2-9270-8B03421BADA2}.Release|Any CPU.Build.0 = Release|Any CPU + {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -586,8 +602,8 @@ Global {792980F3-3B4D-4F20-8802-271644DEE48C} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} {99750990-6CBB-4188-80FA-4C2CD1FB1AE9} = {F900A4AD-7249-41B4-B918-CB9E8C73747C} {3C1D57CC-9715-4698-8974-FF578A9F5F48} = {F900A4AD-7249-41B4-B918-CB9E8C73747C} - {54982BA3-AC0A-4074-98ED-A1A61DD09224} = {F900A4AD-7249-41B4-B918-CB9E8C73747C} - {89FD9EC5-E490-4BB9-9A7F-C4BE87E62381} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} + {54982BA3-AC0A-4074-98ED-A1A61DD09224} = {BE108BE8-805D-4FCF-86BA-B2EAF581FFB2} + {89FD9EC5-E490-4BB9-9A7F-C4BE87E62381} = {B521FF6D-E081-4DE6-AC00-A9BE3B6439D1} {A92C9C85-407B-4A89-A861-8CAEC695723E} = {F900A4AD-7249-41B4-B918-CB9E8C73747C} {651C8B51-B5D5-48DC-9B61-19883254D2F2} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} {FDD63DB8-FAEB-4808-8B7D-B2D9E4617E5C} = {F1E13DF4-9F50-41A2-9DC3-04B673B21032} @@ -681,6 +697,10 @@ Global {7AD4B13D-FA17-489B-9721-C00BCB6A3F2C} = {BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8} {B040A39A-53DC-4514-BE7F-A275FE1355FF} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} {5937CEC2-5C16-4650-B0E6-78CD34357384} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} + {0CD32C8A-496A-46A2-9270-8B03421BADA2} = {BE108BE8-805D-4FCF-86BA-B2EAF581FFB2} + {BE108BE8-805D-4FCF-86BA-B2EAF581FFB2} = {F900A4AD-7249-41B4-B918-CB9E8C73747C} + {E1CD114A-F8A5-4246-B5E3-FD27EDEC7C82} = {B521FF6D-E081-4DE6-AC00-A9BE3B6439D1} + {B521FF6D-E081-4DE6-AC00-A9BE3B6439D1} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E18684C9-7D76-45CD-BF24-E3944B7F174C} diff --git a/dotnet/src/dotnetcore/GxOffice/GxOffice.csproj b/dotnet/src/dotnetcore/GxOffice/GxOffice.csproj new file mode 100644 index 000000000..4a31a7b68 --- /dev/null +++ b/dotnet/src/dotnetcore/GxOffice/GxOffice.csproj @@ -0,0 +1,52 @@ + + + net6.0 + NETCORE + Genexus.Office + GxOffice + Office Excel Poi + GeneXus.Office.Core + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dotnet/src/dotnetframework/GxOffice/Constants.cs b/dotnet/src/dotnetframework/GxOffice/Constants.cs new file mode 100644 index 000000000..5be36feda --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/Constants.cs @@ -0,0 +1,14 @@ +namespace GeneXus.MSOffice.Excel +{ + public static class Constants + { + public const bool EXTERNAL_PRIVATE_UPLOAD = true; + } + public static class ErrorCodes + { + public const int TEMPLATE_NOT_FOUND = 4; + public const int EXTENSION_NOT_SUPPORTED = 5; + public const int FILE_NOT_SAVED = 6; + public const int FILE_EXCEPTION = 7; + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetframework/GxOffice/ExcelFactory.cs b/dotnet/src/dotnetframework/GxOffice/ExcelFactory.cs new file mode 100644 index 000000000..f83452820 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/ExcelFactory.cs @@ -0,0 +1,27 @@ +using System.IO; +using GeneXus.Application; +using GeneXus.MSOffice.Excel.Poi.Xssf; + +namespace GeneXus.MSOffice.Excel +{ + public class ExcelFactory + { + public static IExcelSpreadsheet Create(IGXError handler, string filePath, string template) + { + if (!string.IsNullOrEmpty(filePath)) + { + filePath = Path.IsPathRooted(filePath) ? filePath : Path.Combine(GxContext.StaticPhysicalPath(), filePath); + } + if (!string.IsNullOrEmpty(template)) + { + template = Path.IsPathRooted(template) ? template : Path.Combine(GxContext.StaticPhysicalPath(), template); + } + + if (filePath.EndsWith(ExcelSpreadsheet.DefaultExtension) || string.IsNullOrEmpty(Path.GetExtension(filePath))) + { + return new ExcelSpreadsheet(handler, filePath, template); + } + throw new ExcelDocumentNotSupported(); + } + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetframework/GxOffice/ExcelSpreadsheetGXWrapper.cs b/dotnet/src/dotnetframework/GxOffice/ExcelSpreadsheetGXWrapper.cs new file mode 100644 index 000000000..a1ac17645 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/ExcelSpreadsheetGXWrapper.cs @@ -0,0 +1,414 @@ +using System; +using System.Collections.Generic; +using GeneXus.MSOffice.Excel.Poi.Xssf; +using log4net; + +namespace GeneXus.MSOffice.Excel +{ + public class ExcelSpreadsheetGXWrapper : IGXError + { + private static readonly ILog logger = LogManager.GetLogger(typeof(ExcelSpreadsheetGXWrapper)); + private int _errCode; + private string _errDescription = string.Empty; + private IExcelWorksheet _currentWorksheet; + private IExcelSpreadsheet _document; + private bool _isReadonly = false; + private bool _autofit = false; + private const string DEFAULT_SHEET_NAME = "Sheet"; + + public bool Autofit + { + set + { + _autofit = value; + if (_document != null) + { + _document.Autofit = _autofit; + } + } + } + + private bool Initialize() + { + return Initialize(DEFAULT_SHEET_NAME); + } + + private bool Initialize(string defaultSheetName) + { + bool ok = SelectFirstDefaultSheet(defaultSheetName); + if (!ok) + { + SetErrCod(1); + SetErrDes("Could not get/set first Sheet on Document"); + } + else + { + SetErrCod(0); + SetErrDes(string.Empty); + } + return ok; + } + + public bool Open(string filePath) + { + return Open(filePath, string.Empty); + } + + public bool Open(string filePath, string template) + { + try + { + logger.Debug("Opening Excel file: " + filePath); + _document = ExcelFactory.Create(this, filePath, template); + if (_autofit) + { + _document.Autofit = _autofit; + } + } + catch (ExcelTemplateNotFoundException e) + { + SetError("Excel Template file not found", e); + } + catch (ExcelDocumentNotSupported e) + { + SetError("Excel file extension not supported", e); + } + catch (Exception e)//InvalidOpertaionException + { + logger.Error("Excel File could not be loaded", e); + SetError(ErrorCodes.FILE_EXCEPTION, "Could not open file"); + } + return _document != null; + } + + public bool Save() + { + bool ok = false; + if (Initialize()) + { + try + { + ok = _document.Save(); + if (!ok) + { + SetError(ErrorCodes.FILE_NOT_SAVED, "Excel File could not be saved"); + } + } + catch (ExcelException e) + { + SetError("Excel File could not be saved", e); + } + } + + return ok; + } + + public bool SaveAs(string newFileName, string password) + { + return SaveAsImpl(newFileName, password); + } + + public bool SaveAs(string newFileName) + { + return SaveAsImpl(newFileName, null); + } + + private bool SaveAsImpl(string newFileName, string password) + { + bool ok = true; + if (Initialize()) + { + try + { + _document.SaveAs(newFileName); + } + catch (ExcelException e) + { + SetError(e); + ok = false; + } + } + return ok; + } + + public ExcelCells GetCell(int rowIdx, int colIdx) + { + if (Initialize()) + { + try + { + return (ExcelCells)_document.GetCell(_currentWorksheet, rowIdx, colIdx); + } + catch (ExcelException e) + { + SetError(e); + } + } + return null; + } + + public void SetError(ExcelException e) + { + SetError(e.ErrorCode, e.ErrorDescription); + logger.Error(e.ErrorDescription, e); + } + + public void SetError(string errorMsg, ExcelException e) + { + SetError(e.ErrorCode, e.ErrorDescription); + logger.Error(errorMsg); + } + + public ExcelCells GetCells(int rowIdx, int colIdx, int rowCount, int colCount) + { + if (Initialize()) + { + try + { + return (ExcelCells)_document.GetCells(_currentWorksheet, rowIdx, colIdx, rowCount, colCount); + } + catch (ExcelException e) + { + SetError(e); + } + } + return null; + } + + public bool SetCurrentWorksheet(int sheetIdx) + { + int zeroIndexSheet = sheetIdx - 1; + if (zeroIndexSheet >= 0 && Initialize() && _document.GetWorksheets().Count > zeroIndexSheet) + { + _currentWorksheet = _document.GetWorksheets()[zeroIndexSheet]; + if (_currentWorksheet != null) + { + _document.SetActiveWorkSheet(_currentWorksheet.Name); + } + return true; + } + return false; + } + + public bool SetCurrentWorksheetByName(string sheetName) + { + if (Initialize()) + { + ExcelWorksheet ws = _document.GetWorkSheet(sheetName); + if (ws != null) + { + _currentWorksheet = ws; + _document.SetActiveWorkSheet(sheetName); + return true; + } + } + return false; + } + + public bool InsertRow(int rowIdx, int rowCount) + { + if (Initialize()) + { + return _document.InsertRow(_currentWorksheet, rowIdx - 1, rowCount); + } + return false; + } + + public bool InsertColumn(int colIdx, int colCount) + { + //throw new Exception("NotImplemented"); + return false; + /* + * if (isOK()) { //return _document.(_currentWorksheet, colIdx, colCount); } + * return false; + */ + } + + public bool DeleteRow(int rowIdx) + { + if (Initialize()) + { + return _document.DeleteRow(_currentWorksheet, rowIdx - 1); + } + return false; + } + + public bool DeleteColumn(int colIdx) + { + if (Initialize()) + { + return _document.DeleteColumn(_currentWorksheet, colIdx - 1); + } + return false; + } + + public bool InsertSheet(string sheetName) + { + try + { + return _document != null && _document.InsertWorksheet(sheetName, 0) && Initialize(sheetName); + } + catch (ExcelException e) + { + SetError("Could not insert new sheet", e); + } + return false; + } + + public bool CloneSheet(string sheetName, string newSheetName) + { + if (Initialize()) + { + try + { + return _document.CloneSheet(sheetName, newSheetName); + } + catch (ExcelException e) + { + SetError(2, e.Message); + } + } + return false; + } + + public bool ToggleColumn(int colIdx, bool visible) + { + if (Initialize()) + { + return _document.ToggleColumn(_currentWorksheet, colIdx - 1, visible); + } + return false; + } + + public bool ToggleRow(int rowIdx, bool visible) + { + if (Initialize()) + { + return _document.ToggleRow(_currentWorksheet, rowIdx - 1, visible); + } + return false; + } + + public bool DeleteSheet(string sheetName) + { + if (Initialize()) + { + ExcelWorksheet ws = _document.GetWorkSheet(sheetName); + if (ws != null) + return _document.DeleteSheet(sheetName); + } + SetError(2, "Sheet not found"); + return false; + } + + public bool DeleteSheet(int sheetIdx) + { + if (Initialize()) + { + if (_document.GetWorksheets().Count >= sheetIdx) + return _document.DeleteSheet(sheetIdx - 1); + } + SetError(2, "Sheet not found"); + return false; + } + + + public bool Close() + { + if (Initialize()) + { + try + { + _document.Close(); + } + catch (ExcelException e) + { + GXLogging.Error(logger, "Close error", e); + } + } + _currentWorksheet = null; + _document = null; + return true; + } + + private void SetError(int error, string description) + { + _errCode = error; + _errDescription = description; + } + + public int ErrCode => _errCode; + + public string ErrDescription => _errDescription; + + public ExcelWorksheet CurrentWorksheet + { + get + { + if (Initialize()) + { + return (ExcelWorksheet)_currentWorksheet; + } + return null; + } + } + + public List GetWorksheets() + { + if (Initialize()) + return _document.GetWorksheets(); + else + return new List(); + } + + private bool SelectFirstDefaultSheet(string sheetName) + { + if (_document != null) + { + int sheetsCount = _document.GetWorksheets().Count; + if (sheetsCount == 0 && _isReadonly) + { + return true; + } + if (sheetsCount == 0) + { + try + { + _document.InsertWorksheet(sheetName, 0); + } + catch (ExcelException) { } + } + if (_currentWorksheet == null) + _currentWorksheet = _document.GetWorksheets()[0]; + } + return _currentWorksheet != null; + } + + public void SetColumnWidth(int colIdx, int width) + { + if (colIdx > 0 && Initialize()) + { + _document.SetColumnWidth(_currentWorksheet, colIdx, width); + } + } + + public void SetRowHeight(int rowIdx, int height) + { + if (rowIdx > 0 && Initialize()) + { + _document.SetRowHeight(_currentWorksheet, rowIdx, height); + } + } + + public void SetErrCod(short arg0) + { + _errCode = arg0; + } + + public void SetErrDes(string arg0) + { + _errDescription = arg0; + } + + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/GxOffice.csproj b/dotnet/src/dotnetframework/GxOffice/GxOffice.csproj new file mode 100644 index 000000000..ba4b31da3 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/GxOffice.csproj @@ -0,0 +1,19 @@ + + + net462 + Genexus.Office + GxOffice + Office Excel Poi + GeneXus.Office + + + + + + + + + + + + \ No newline at end of file diff --git a/dotnet/src/dotnetframework/GxOffice/IExcelCellRange.cs b/dotnet/src/dotnetframework/GxOffice/IExcelCellRange.cs new file mode 100644 index 000000000..093486b8f --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/IExcelCellRange.cs @@ -0,0 +1,41 @@ +using System; +using GeneXus.MSOffice.Excel.Style; + +namespace GeneXus.MSOffice.Excel +{ + public interface IExcelCellRange + { + int RowStart { get; } + + int RowEnd { get; } + + int ColumnStart { get; } + + int ColumnEnd { get; } + + string GetCellAdress(); + + string ValueType { get; } + + /* + * + * D: for Date and DateTime + * C: Characteres + * N: Numerics + * U: Unknown + */ + string Text { get; set; } + + decimal NumericValue { get; set; } + + DateTime DateValue { get; set; } + + bool Empty(); + + bool MergeCells(); + + bool SetCellStyle(ExcelStyle style); + + ExcelStyle GetCellStyle(); + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/IExcelSpreadsheet.cs b/dotnet/src/dotnetframework/GxOffice/IExcelSpreadsheet.cs new file mode 100644 index 000000000..1d6bf3a55 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/IExcelSpreadsheet.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using GeneXus.MSOffice.Excel.Poi.Xssf; + +namespace GeneXus.MSOffice.Excel +{ + public interface IExcelSpreadsheet + { + // General Methods + bool Save(); + bool SaveAs(string newFileName); + bool Close(); + + // CellMethods + IExcelCellRange GetCells(IExcelWorksheet worksheet, int startRow, int startCol, int rowCount, int colCount); + IExcelCellRange GetCell(IExcelWorksheet worksheet, int startRow, int startCol); + bool InsertRow(IExcelWorksheet worksheet, int rowIdx, int rowCount); + bool DeleteRow(IExcelWorksheet worksheet, int rowIdx); + bool DeleteColumn(IExcelWorksheet worksheet, int colIdx); + + // Worksheets + List GetWorksheets(); + ExcelWorksheet GetWorkSheet(string name); + bool InsertWorksheet(string newSheetName, int idx); + bool Autofit { set; } + void SetColumnWidth(IExcelWorksheet worksheet, int colIdx, int width); + void SetRowHeight(IExcelWorksheet worksheet, int rowIdx, int height); + bool SetActiveWorkSheet(string name); + bool DeleteSheet(int sheetIdx); + bool DeleteSheet(string sheetName); + bool ToggleColumn(IExcelWorksheet worksheet, int colIdx, bool visible); + bool ToggleRow(IExcelWorksheet _currentWorksheet, int i, bool visible); + bool CloneSheet(string sheetName, string newSheetName); + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/IExcelWorksheet.cs b/dotnet/src/dotnetframework/GxOffice/IExcelWorksheet.cs new file mode 100644 index 000000000..0d5a2a531 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/IExcelWorksheet.cs @@ -0,0 +1,13 @@ +namespace GeneXus.MSOffice.Excel +{ + public interface IExcelWorksheet + { + string Name { get; } + + bool Hidden { get; } + + bool Rename(string newName); + bool Copy(string newName); + void SetProtected(string password); + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/IGXError.cs b/dotnet/src/dotnetframework/GxOffice/IGXError.cs new file mode 100644 index 000000000..b9d69a4d2 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/IGXError.cs @@ -0,0 +1,8 @@ +namespace GeneXus.MSOffice.Excel +{ + public interface IGXError + { + void SetErrCod(short errCod); + void SetErrDes(string errDes); + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/exception/ExcelDocumentNotSupported.cs b/dotnet/src/dotnetframework/GxOffice/exception/ExcelDocumentNotSupported.cs new file mode 100644 index 000000000..7b6fb7f76 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/exception/ExcelDocumentNotSupported.cs @@ -0,0 +1,9 @@ +namespace GeneXus.MSOffice.Excel +{ + public class ExcelDocumentNotSupported : ExcelException + { + public ExcelDocumentNotSupported() : base(ErrorCodes.EXTENSION_NOT_SUPPORTED, "File extension not supported") + { + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/exception/ExcelException.cs b/dotnet/src/dotnetframework/GxOffice/exception/ExcelException.cs new file mode 100644 index 000000000..0a00c7263 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/exception/ExcelException.cs @@ -0,0 +1,32 @@ +using System; + +namespace GeneXus.MSOffice.Excel +{ + public class ExcelException : Exception + { + private int _errorCode; + private string _errDsc; + + public ExcelException(int errCode, string errDsc, Exception e) : base(errDsc, e) + { + _errorCode = errCode; + _errDsc = errDsc; + } + + public ExcelException(int errCode, string errDsc) : base(errDsc) + { + _errorCode = errCode; + _errDsc = errDsc; + } + + public int ErrorCode + { + get { return _errorCode; } + } + + public string ErrorDescription + { + get { return _errDsc; } + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/exception/ExcelReadonlyException.cs b/dotnet/src/dotnetframework/GxOffice/exception/ExcelReadonlyException.cs new file mode 100644 index 000000000..a67e0e040 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/exception/ExcelReadonlyException.cs @@ -0,0 +1,9 @@ +namespace GeneXus.MSOffice.Excel +{ + public class ExcelReadonlyException : ExcelException + { + public ExcelReadonlyException() : base(13, "Can not modify a readonly document") + { + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/exception/ExcelTemplateNotFoundException.cs b/dotnet/src/dotnetframework/GxOffice/exception/ExcelTemplateNotFoundException.cs new file mode 100644 index 000000000..9337477c3 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/exception/ExcelTemplateNotFoundException.cs @@ -0,0 +1,9 @@ +namespace GeneXus.MSOffice.Excel +{ + public class ExcelTemplateNotFoundException : ExcelException + { + public ExcelTemplateNotFoundException() : base(ErrorCodes.TEMPLATE_NOT_FOUND, "Template not found") + { + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelCells.cs b/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelCells.cs new file mode 100644 index 000000000..b7b95ef1a --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelCells.cs @@ -0,0 +1,1304 @@ + +using System; +using GeneXus.MSOffice.Excel.Style; +using GeneXus.Utils; +using log4net; +using NPOI.OpenXmlFormats.Spreadsheet; +using NPOI.SS.UserModel; +using NPOI.SS.Util; +using NPOI.XSSF.Model; +using NPOI.XSSF.UserModel; +using NPOI.XSSF.UserModel.Extensions; + +namespace GeneXus.MSOffice.Excel.Poi.Xssf +{ + public class ExcelCells : IExcelCellRange + { + private static readonly ILog logger = LogManager.GetLogger(typeof(ExcelCells)); + protected IGXError _errorHandler; + protected ExcelSpreadsheet doc; + protected int cellCount; + protected int pWidth; + protected int pHeight; + protected int colStartIdx; + protected int colEndIdx; + protected int rowStartIdx; + protected int rowEndIdx; + protected XSSFWorkbook pWorkbook; + protected ISheet pSelectedSheet; + protected bool fitColumnWidth; + protected bool readonlyFlag; + protected StylesCache stylesCache; + protected XSSFCell[] pCells; + protected ExcelStyle cellStyle; + public ExcelCells(IGXError errAccess, ExcelSpreadsheet document, XSSFWorkbook workBook, XSSFSheet selectedSheet, + int rowPos, int colPos, int height, int width, StylesCache stylesCache) : this(errAccess, document, workBook, selectedSheet, rowPos, colPos, height, width, false, stylesCache) + { } + + public ExcelCells() + { + } + + public ExcelCells(IGXError errAccess, ExcelSpreadsheet document, XSSFWorkbook workBook, XSSFSheet selectedSheet, + int rowPos, int colPos, int height, int width, bool isReadonly, StylesCache stylesCache) + { + _errorHandler = errAccess; + doc = document; + cellCount = 0; + pWidth = width; + pHeight = height; + colStartIdx = colPos; + colEndIdx = colPos + (width - 1); + rowStartIdx = rowPos; + rowEndIdx = rowPos + (height - 1); + pWorkbook = workBook; + pSelectedSheet = selectedSheet; + fitColumnWidth = true; + readonlyFlag = isReadonly; + this.stylesCache = stylesCache; + pCells = new XSSFCell[(width * height) + 1]; + + try + { + for (int y = rowPos; y < (rowPos + pHeight); y++) + { + XSSFRow pRow = GetExcelRow(selectedSheet, y); + if (pRow != null) + { + for (int x = colPos; x < (colPos + pWidth); x++) + { + ICell pCell = GetExcelCell(pRow, x); + if (pCell != null) + { + cellCount++; + pCells[cellCount] = (XSSFCell)pCell; + } + } + } + } + } + catch (Exception) + { + throw new ExcelException(8, "Invalid cell coordinates"); + } + } + + protected XSSFRow GetExcelRow(XSSFSheet sheet, int rowPos) + { + XSSFRow row = (XSSFRow)sheet.GetRow(rowPos); + + if (row == null) + { + row = (XSSFRow)sheet.CreateRow(rowPos); + } + + return row; + } + + protected XSSFCell GetExcelCell(XSSFRow row, int colPos) + { + XSSFCell cell = (XSSFCell)row.GetCell(colPos); + + if (cell == null) + { + cell = (XSSFCell)row.CreateCell(colPos); + } + + return cell; + } + + public bool SetNumber(double value) + { + try + { + for (int i = 1; i <= cellCount; i++) + { + pCells[i].SetCellValue(value); + } + return true; + } + catch (Exception) + { + throw new ExcelException(7, "Invalid cell value"); + } + } + + public decimal GetNumber() + { + try + { + return GetValue(); + } + catch (Exception) + { + throw new ExcelException(7, "Invalid cell value"); + } + } + + public bool SetDate(DateTime value) + { + CheckReadonlyDocument(); + + try + { + if (value != DateTime.MinValue) + { + DateTime d = value; + + string dformat = "m/d/yy h:mm"; + + if (value.Minute == 0 && value.Hour == 0 && value.Second == 0 && value.Millisecond == 0 && dformat.IndexOf(' ') > 0) + dformat = dformat.Substring(0, dformat.IndexOf(' ')); + + XSSFDataFormat df = (XSSFDataFormat)pWorkbook.CreateDataFormat(); + + for (int i = 1; i <= cellCount; i++) + { + XSSFCellStyle cellStyle = (XSSFCellStyle)pCells[i].CellStyle; + if (!DateUtil.IsCellDateFormatted(pCells[i])) + { + XSSFCellStyle newStyle = (XSSFCellStyle)pWorkbook.CreateCellStyle(); + CopyPropertiesStyle(newStyle, cellStyle); + newStyle.DataFormat = df.GetFormat(dformat); + pCells[i].CellStyle = newStyle; + FitColumnWidth(i, dformat.Length + 4); + } + else + { + FitColumnWidth(i, cellStyle.GetDataFormatString().Length + 4); + } + pCells[i].SetCellValue(value); + } + return true; + } + } + catch (Exception) + { + throw new ExcelException(7, "Invalid cell value"); + } + return false; + } + + public DateTime GetDate() + { + DateTime returnValue = DateTimeUtil.NullDate(); + try + { + returnValue = pCells[1].DateCellValue; + } + catch (Exception) + { + throw new ExcelException(7, "Invalid cell value"); + } + return returnValue; + } + + public bool SetTextImpl(string value) + { + CheckReadonlyDocument(); + + try + { + for (int i = 1; i <= cellCount; i++) + { + if (value.Length > 0 && value[0] == '=') + { + try + { + pCells[i].CellFormula = value.Substring(1); + } + catch (Exception) + { + pCells[i].SetCellType(CellType.String); + pCells[i].SetCellValue(value); + } + } + else + pCells[i].SetCellValue(value); + } + return true; + } + catch (Exception e) + { + throw new ExcelException(7, "Invalid cell value", e); + } + } + + private void CheckReadonlyDocument() + { + if (readonlyFlag) + { + throw new ExcelReadonlyException(); + } + } + public string Text + { + get + { + try + { + if (pCells[1].CellType == CellType.Formula) + return "=" + pCells[1].CellFormula; + else if (pCells[1].CellType == CellType.Numeric) + { + if (DateUtil.IsCellDateFormatted(pCells[1])) + { + return pCells[1].DateCellValue.ToString(); + } + else + { + return pCells[1].NumericCellValue.ToString(); + } + } + else + return pCells[1].StringCellValue; + } + catch (Exception) + { + _errorHandler.SetErrCod(7); + _errorHandler.SetErrDes("Invalid cell value"); + } + return null; + } + set + { + try + { + SetTextImpl(value); + } + catch (ExcelException e) + { + _errorHandler.SetErrCod((short)e.ErrorCode); + _errorHandler.SetErrDes(e.ErrorDescription); + } + + } + } + + public decimal GetValue() + { + decimal value = 0; + try + { + CellType cType = pCells[1].CellType; + switch (cType) + { + case CellType.Formula: + string type = GetFormulaType(); + if (type.Equals("N")) + value = new decimal(pCells[1].NumericCellValue); + else if (type.Equals("D")) + value = new decimal(GetDate().ToOADate()); + break; + case CellType.Boolean: + bool b = pCells[1].BooleanCellValue; + value = new decimal((b) ? 1 : 0); + break; + default: + value = new decimal(pCells[1].NumericCellValue); + break; + } + } + catch (Exception) + { + throw new ExcelException(7, "Invalid cell value"); + } + return value; + } + + public string GetCellType() + { + string type; + switch (pCells[1].CellType) + { + case CellType.Blank: + type = "U"; + break; + case CellType.Boolean: + type = "N"; + break; + case CellType.Error: + type = "U"; + break; + case CellType.Formula: + type = GetFormulaType(); + break; + case CellType.Numeric: + if (DateUtil.IsCellDateFormatted(pCells[1])) + { + type = "D"; + } + else + { + type = "N"; + } + break; + case CellType.String: + type = "C"; + break; + default: + type = string.Empty; + break; + } + return type; + } + + private string GetFormulaType() + { + try + { + DataFormatter formatter = new DataFormatter(); + + FormatBase format = formatter.GetDefaultFormat(pCells[1]); + if (format.GetType() == typeof(System.Globalization.DateTimeFormatInfo)) + { + return "D"; + } + else + { + return "N"; + } + } + catch (Exception) + { + try + { + DateTime dVal = pCells[1].DateCellValue; + if (dVal != DateTime.MinValue) + { + return "D"; + } + } + catch (Exception) + { + } + } + string sVal = string.Empty; + try + { + sVal = pCells[1].StringCellValue; + } + catch (Exception) + { + } + if (!string.IsNullOrEmpty(sVal)) + { + return "C"; + } + else + { + return "U"; + } + } + + public double GetSize() + { + return pWorkbook.GetFontAt(pCells[1].CellStyle.FontIndex).FontHeightInPoints; + } + + public void SetSize(double value) + { + CheckReadonlyDocument(); + + try + { + for (int i = 1; i <= cellCount; i++) + { + ICellStyle cellStyle = pCells[1].CellStyle; + XSSFFont fontCell = (XSSFFont)pWorkbook.GetFontAt(cellStyle.FontIndex); + XSSFCellStyle newStyle = null; + XSSFFont newFont = null; + + if (fontCell.FontHeightInPoints != value) + { + newFont = GetInternalFont(fontCell.IsBold, fontCell.Color, (short)value, + fontCell.FontName, fontCell.IsItalic, fontCell.IsStrikeout, + fontCell.TypeOffset, fontCell.Underline); + CopyPropertiesFont(newFont, fontCell); + + newFont.FontHeightInPoints = (short)value; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[1].CellStyle = newStyle; + } + } + } + catch (Exception ex) + { + GXLogging.Error(logger, "SetSize error", ex); + } + } + + public string GetFont() + { + return pWorkbook.GetFontAt(pCells[1].CellStyle.FontIndex).FontName; + } + + protected XSSFFont GetInternalFont(bool bold, short color, double fontHeight, string name, bool italic, + bool strikeout, FontSuperScript typeOffset, FontUnderlineType underline) + { + IFont font = pWorkbook.FindFont(bold, color, (short)fontHeight, name, italic, strikeout, typeOffset, underline); + if (font == null) + { + font = pWorkbook.CreateFont(); + } + return (XSSFFont)font; + } + + public void SetFont(string value) + { + CheckReadonlyDocument(); + + try + { + for (int i = 1; i <= cellCount; i++) + { + ICellStyle cellStyle = pCells[i].CellStyle; + IFont fontCell = pWorkbook.GetFontAt(cellStyle.FontIndex); + XSSFCellStyle newStyle = null; + XSSFFont newFont = null; + + if (!fontCell.FontName.Equals(value)) + { + newFont = GetInternalFont(fontCell.IsBold, fontCell.Color, (short)fontCell.FontHeight, value, + fontCell.IsItalic, fontCell.IsStrikeout, fontCell.TypeOffset, + fontCell.Underline); + CopyPropertiesFont(newFont, fontCell); + + newFont.FontName = value; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + } + } + catch (Exception) + { + throw new ExcelException(7, "Invalid cell value"); + } + } + public short GetBold() + { + if (pWorkbook.GetFontAt(pCells[1].CellStyle.FontIndex).IsBold) + { + return 1; + } + return 0; + } + + public void SetBold(short value) + { + CheckReadonlyDocument(); + + try + { + for (int i = 1; i <= cellCount; i++) + { + ICellStyle cellStyle = pCells[i].CellStyle; + IFont fontCell = pWorkbook.GetFontAt(cellStyle.FontIndex); + XSSFCellStyle newStyle = null; + XSSFFont newFont = null; + + switch (value) + { + case 0: + if (fontCell.IsBold) + { + newFont = GetInternalFont(true, fontCell.Color, (short)fontCell.FontHeight, + fontCell.FontName, fontCell.IsItalic, fontCell.IsStrikeout, + fontCell.TypeOffset, fontCell.Underline); + CopyPropertiesFont(newFont, fontCell); + newFont.IsBold = true; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + break; + case 1: + if (!fontCell.IsBold) + { + newFont = GetInternalFont(true, fontCell.Color, (short)fontCell.FontHeight, + fontCell.FontName, fontCell.IsItalic, fontCell.IsStrikeout, + fontCell.TypeOffset, fontCell.Underline); + CopyPropertiesFont(newFont, fontCell); + newFont.IsBold = true; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + break; + default: + throw new ExcelException(6, "Invalid font properties"); + } + } + } + catch (Exception) + { + throw new ExcelException(6, "Invalid bold value"); + } + } + + public short GetItalic() + { + if (pWorkbook.GetFontAt(pCells[1].CellStyle.FontIndex).IsItalic) + { + return 1; + } + return 0; + } + + public void SetItalic(short value) + { + CheckReadonlyDocument(); + + try + { + for (int i = 1; i <= cellCount; i++) + { + ICellStyle cellStyle = pCells[i].CellStyle; + IFont fontCell = pWorkbook.GetFontAt(cellStyle.FontIndex); + XSSFCellStyle newStyle = null; + XSSFFont newFont = null; + + switch (value) + { + case 0: + if (fontCell.IsItalic) + { + newFont = GetInternalFont(fontCell.IsBold, fontCell.Color, fontCell.FontHeight, + fontCell.FontName, false, fontCell.IsStrikeout, fontCell.TypeOffset, + fontCell.Underline); + CopyPropertiesFont(newFont, fontCell); + newFont.IsItalic = false; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + break; + case 1: + if (!fontCell.IsItalic) + { + newFont = GetInternalFont(fontCell.IsBold, fontCell.Color, fontCell.FontHeight, + fontCell.FontName, true, fontCell.IsStrikeout, fontCell.TypeOffset, + fontCell.Underline); + CopyPropertiesFont(newFont, fontCell); + newFont.IsItalic = true; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + break; + default: + throw new ExcelException(6, "Invalid font properties"); + } + } + } + catch (Exception) + { + throw new ExcelException(6, "Invalid font properties"); + } + } + public short GetUnderline() + { + if (pWorkbook.GetFontAt(pCells[1].CellStyle.FontIndex).Underline != FontUnderlineType.None) + { + return 1; + } + return 0; + } + + public void SetUnderline(short value) + { + CheckReadonlyDocument(); + + try + { + for (int i = 1; i <= cellCount; i++) + { + ICellStyle cellStyle = pCells[i].CellStyle; + IFont fontCell = pWorkbook.GetFontAt(cellStyle.FontIndex); + XSSFCellStyle newStyle = null; + XSSFFont newFont = null; + + switch (value) + { + case 0: + if (fontCell.Underline != FontUnderlineType.None) + { + newFont = GetInternalFont(fontCell.IsBold, fontCell.Color, fontCell.FontHeight, + fontCell.FontName, fontCell.IsItalic, fontCell.IsStrikeout, + fontCell.TypeOffset, FontUnderlineType.None); + CopyPropertiesFont(newFont, fontCell); + + newFont.Underline = FontUnderlineType.None; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + break; + case 1: + if (fontCell.Underline != FontUnderlineType.Single) + { + newFont = GetInternalFont(fontCell.IsBold, fontCell.Color, fontCell.FontHeight, + fontCell.FontName, fontCell.IsItalic, fontCell.IsStrikeout, + fontCell.TypeOffset, FontUnderlineType.Single); + CopyPropertiesFont(newFont, fontCell); + + newFont.Underline = FontUnderlineType.Single; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + break; + default: + throw new ExcelException(6, "Invalid font property"); + } + } + } + catch (Exception) + { + throw new ExcelException(6, "Invalid font properties"); + } + } + + public long GetColor() + { + return pWorkbook.GetFontAt(pCells[1].CellStyle.FontIndex).Color - 7; + } + + public void SetColor(short value) + { + SetColor((long)value); + } + + public void SetColor(int value) + { + SetColor((long)value); + } + + // This version optimizes the existing color palette in the spreadsheet. + // It searches for similar colors and if found, it uses them to avoid reloading + // the color palette, which has a maximum of 40h-10h positions. + public void SetColor(long value) + { + CheckReadonlyDocument(); + + try + { + for (int i = 1; i <= cellCount; i++) + { + XSSFCellStyle cellStyle = (XSSFCellStyle)pCells[i].CellStyle; + XSSFFont fontCell = (XSSFFont)pWorkbook.GetFontAt(cellStyle.FontIndex); + XSSFCellStyle newStyle = null; + XSSFFont newFont = null; + XSSFColor newColor = null; + + XSSFColor fontColor = fontCell.GetXSSFColor(); + + int val = (int)value; + int red = val >> 16 & 0xff; + int green = val >> 8 & 0xff; + int blue = val & 0xff; + + if (red != 0 || green != 0 || blue > 56) + { + if ((fontColor != null && (fontColor.GetRgb() == null || (fontColor.GetRgb()[0] == 0 + && fontColor.GetRgb()[1] == 0 && fontColor.GetRgb()[2] == 0)))) + { + if ((red + green + blue) != 0) + { + newColor = new XSSFColor(new byte[] { (byte)red, (byte)green, (byte)blue }); + + newFont = (XSSFFont)pWorkbook.CreateFont(); + CopyPropertiesFont(newFont, fontCell); + + newFont.SetColor(newColor); + + newStyle = (XSSFCellStyle)pWorkbook.CreateCellStyle(); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + } + else + { + if (fontColor != null) + { + byte[] triplet = fontColor.GetRgb(); + + if (triplet[0] != red || triplet[1] != green || triplet[2] != blue) + { + + newColor = new XSSFColor(new byte[] { (byte)red, (byte)green, (byte)blue }); + + newFont = (XSSFFont)pWorkbook.CreateFont(); + CopyPropertiesFont(newFont, fontCell); + + newFont.SetColor(newColor); + + newStyle = (XSSFCellStyle)pWorkbook.CreateCellStyle(); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + } + } + } + else + { + value = value + 7; + if (fontColor != null) + { + if (fontColor.Indexed != value) + { + newFont = GetInternalFont(fontCell.IsBold, (short)value, + fontCell.FontHeight, fontCell.FontName, fontCell.IsItalic, + fontCell.IsStrikeout, fontCell.TypeOffset, fontCell.Underline); + CopyPropertiesFont(newFont, fontCell); + + newFont.Color = (short)value; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + } + else + { + newFont = GetInternalFont(fontCell.IsBold, (short)value, + fontCell.FontHeight, fontCell.FontName, fontCell.IsItalic, + fontCell.IsStrikeout, fontCell.TypeOffset, fontCell.Underline); + CopyPropertiesFont(newFont, fontCell); + + newFont.Color = (short)value; + + newStyle = stylesCache.GetCellStyle(newFont); + CopyPropertiesStyle(newStyle, cellStyle); + + newStyle.SetFont(newFont); + pCells[i].CellStyle = newStyle; + } + } + } + } + catch (Exception e) + { + throw new ExcelException(6, "Invalid font properties", e); + } + } + + protected void CopyPropertiesStyle(XSSFCellStyle dest, ICellStyle source) + { + dest.CloneStyleFrom(source); + } + + protected void CopyPropertiesFont(XSSFFont dest, IFont source) + { + dest.FontHeightInPoints = source.FontHeightInPoints; + dest.FontName = source.FontName; + dest.IsBold = source.IsBold; + dest.IsItalic = source.IsItalic; + dest.Underline = source.Underline; + dest.Color = source.Color; + } + + private void FitColumnWidth(int i, int data) + { + if (fitColumnWidth) + { + int colW = pSelectedSheet.GetColumnWidth((int)(i + colStartIdx - 1)); + if ((256 * data) > colW) + { + colW = (short)(256 * data); + } + pSelectedSheet.SetColumnWidth((short)(i + colStartIdx - 1), colW); + } + } + + public void SetFitColumnWidth(bool fitCol) + { + fitColumnWidth = fitCol; + } + + public bool GetFitColumnWidth() + { + return fitColumnWidth; + } + + + public int RowStart => rowStartIdx + 1; + + public int RowEnd => rowEndIdx + 1; + + public int ColumnStart => colStartIdx + 1; + + public int ColumnEnd => colEndIdx + 1; + + public string GetCellAdress() + { + return null; + } + + public string ValueType => this.GetCellType(); + + public decimal NumericValue + { + get + { + try + { + return this.GetNumber(); + } + catch (ExcelException e) + { + _errorHandler.SetErrCod((short)e.ErrorCode); + _errorHandler.SetErrDes(e.ErrorDescription); + } + return new decimal(0); + } + set + { + try + { + SetNumber(Convert.ToDouble(value)); + } + catch (ExcelException e) + { + _errorHandler.SetErrCod((short)e.ErrorCode); + _errorHandler.SetErrDes(e.ErrorDescription); + } + } + } + + public DateTime DateValue + { + get + { + try + { + return GetDate(); + } + catch (ExcelException e) + { + _errorHandler.SetErrCod((short)e.ErrorCode); + _errorHandler.SetErrDes(e.ErrorDescription); + } + return DateTimeUtil.NullDate(); + } + set + { + try + { + SetDate(value); + } + catch (ExcelException e) + { + _errorHandler.SetErrCod((short)e.ErrorCode); + _errorHandler.SetErrDes(e.ErrorDescription); + } + } + } + public bool Empty() + { + for (int i = 1; i <= cellCount; i++) + { + pCells[i].SetCellValue(string.Empty); + } + return this.cellCount > 0; + } + + public bool MergeCells() + { + CellRangeAddress cellRange = new CellRangeAddress(rowStartIdx, rowEndIdx, colStartIdx, colEndIdx); + for (int i = 0; i < pSelectedSheet.NumMergedRegions; i++) + { + CellRangeAddress mergedRegion = pSelectedSheet.GetMergedRegion(i); + if (cellRange.Intersects(mergedRegion)) + { + pSelectedSheet.RemoveMergedRegion(i); + } + } + pSelectedSheet.AddMergedRegion(cellRange); + return true; + } + + public ExcelStyle GetCellStyle() + { + return cellStyle; + } + + public bool SetCellStyle(ExcelStyle newCellStyle) + { + if (cellCount > 0) + { + XSSFCellStyle style = (XSSFCellStyle)pWorkbook.CreateCellStyle(); + + ApplyNewCellStyle(style, newCellStyle); + for (int i = 1; i <= cellCount; i++) + { + pCells[i].CellStyle = style; + } + } + return cellCount > 0; + } + + private XSSFColor ToColor(ExcelColor color) + { + return new XSSFColor(new byte[] { (byte)color.Red, (byte)color.Green, (byte)color.Blue }); + } + private XSSFCellStyle ApplyNewCellStyle(XSSFCellStyle cellStyle, ExcelStyle newCellStyle) + { + ExcelFont cellFont = newCellStyle.CellFont; + if (cellFont != null && cellFont.IsDirty()) + { + XSSFFont cellStyleFont = (XSSFFont)pWorkbook.CreateFont(); + cellStyle.SetFont(cellStyleFont); + ExcelFont font = newCellStyle.CellFont; + if (font != null) + { + if (font.Bold) + { + cellStyleFont.IsBold = font.Bold; + } + if (font.FontFamily != null && font.FontFamily.Length > 0) + { + cellStyleFont.FontName = font.FontFamily; + } + if (font.Italic) + { + cellStyleFont.IsItalic = font.Italic; + } + if (font.Strike) + { + cellStyleFont.IsStrikeout = font.Strike; + } + if (font.Size != 0) + { + cellStyleFont.FontHeightInPoints = font.Size; + } + + if (font.Underline) + { + cellStyleFont.Underline = font.Underline ? FontUnderlineType.Single : FontUnderlineType.None; + } + if (font.Color != null && font.Color.IsDirty()) + { + cellStyleFont.SetColor(ToColor(font.Color)); + } + } + } + ExcelFill cellfill = newCellStyle.CellFill; + if (cellfill != null && cellfill.CellBackColor != null && cellfill.CellBackColor.IsDirty()) + { + cellStyle.SetFillForegroundColor(ToColor(cellfill.CellBackColor)); + cellStyle.FillPattern = FillPattern.SolidForeground; + } + + ExcelAlignment alignment = newCellStyle.CellAlignment; + if (alignment != null && alignment.IsDirty()) + { + if (alignment.HorizontalAlignment != 0) + { + HorizontalAlignment align; + switch (alignment.HorizontalAlignment) + { + case ExcelAlignment.HORIZONTAL_ALIGN_CENTER: + align = HorizontalAlignment.Center; + break; + case ExcelAlignment.HORIZONTAL_ALIGN_LEFT: + align = HorizontalAlignment.Left; + break; + case ExcelAlignment.HORIZONTAL_ALIGN_RIGHT: + align = HorizontalAlignment.Right; + break; + default: + align = (HorizontalAlignment)alignment.HorizontalAlignment; + break; + } + cellStyle.Alignment = align; + } + if (alignment.VerticalAlignment != 0) + { + VerticalAlignment align; + switch (alignment.HorizontalAlignment) + { + case ExcelAlignment.VERTICAL_ALIGN_BOTTOM: + align = VerticalAlignment.Bottom; + break; + case ExcelAlignment.VERTICAL_ALIGN_MIDDLE: + align = VerticalAlignment.Center; + break; + case ExcelAlignment.VERTICAL_ALIGN_TOP: + align = VerticalAlignment.Top; + break; + default: + align = (VerticalAlignment)alignment.HorizontalAlignment; + break; + } + cellStyle.VerticalAlignment = align; + } + } + + if (newCellStyle.IsLocked()) + { + cellStyle.IsLocked = newCellStyle.IsLocked(); + } + + if (newCellStyle.IsHidden()) + { + cellStyle.IsHidden = newCellStyle.IsHidden(); + } + + if (newCellStyle.ShrinkToFit) + { + cellStyle.ShrinkToFit = newCellStyle.ShrinkToFit; + } + + if (newCellStyle.WrapText) + { + cellStyle.WrapText = newCellStyle.WrapText; + } + + if (newCellStyle.TextRotation != 0) + { + cellStyle.Rotation = (short)newCellStyle.TextRotation; + } + + if (newCellStyle.Indentation >= 0) + { + cellStyle.Indention = (short)newCellStyle.Indentation; + } + + if (newCellStyle.DataFormat != null && newCellStyle.DataFormat.Length > 0) + { + cellStyle.DataFormat = pWorkbook.CreateDataFormat().GetFormat(newCellStyle.DataFormat); + } + + if (newCellStyle.Border != null) + { + ExcelCellBorder cellBorder = newCellStyle.Border; + ApplyBorderSide(cellStyle, BorderCellSide.TOP, cellBorder.BorderTop); + ApplyBorderSide(cellStyle, BorderCellSide.BOTTOM, cellBorder.BorderBottom); + ApplyBorderSide(cellStyle, BorderCellSide.LEFT, cellBorder.BorderLeft); + ApplyBorderSide(cellStyle, BorderCellSide.RIGHT, cellBorder.BorderRight); + + bool hasDiagonalUp = cellBorder.BorderDiagonalUp != null && cellBorder.BorderDiagonalUp.IsDirty(); + bool hasDiagonalDown = cellBorder.BorderDiagonalDown != null && cellBorder.BorderDiagonalDown.IsDirty(); + if (hasDiagonalUp || hasDiagonalDown) + { + CT_Xf _cellXf = cellStyle.GetCoreXf(); + ExcelBorder border = (hasDiagonalUp) ? cellBorder.BorderDiagonalUp : cellBorder.BorderDiagonalDown; + XSSFColor diagonalColor = ToColor(border.BorderColor); + BorderStyle.TryParse(border.Border, out BorderStyle borderStyle); + SetBorderDiagonal(borderStyle, diagonalColor, this.pWorkbook.GetStylesSource(), _cellXf, hasDiagonalUp, hasDiagonalDown); + } + } + return cellStyle; + } + + private static CT_Border GetCTBorder(StylesTable _stylesSource, CT_Xf _cellXf) + { + CT_Border ct; + if (_cellXf.applyBorder) + { + int idx = (int)_cellXf.borderId; + XSSFCellBorder cf = _stylesSource.GetBorderAt(idx); + ct = (CT_Border)cf.GetCTBorder().Copy(); + } + else + { + ct = new CT_Border(); + } + return ct; + } + + public static void SetBorderDiagonal(BorderStyle border, XSSFColor color, StylesTable _stylesSource, CT_Xf _cellXf, bool up, bool down) + { + CT_Border ct = GetCTBorder(_stylesSource, _cellXf); + CT_BorderPr pr = ct.IsSetDiagonal() ? ct.diagonal : ct.AddNewDiagonal(); + + ct.diagonalDown = down; + ct.diagonalUp = up; + pr.style = ToStBorderStyle(border); + pr.color = ConvertToCTColor(color); + + int idx = _stylesSource.PutBorder(new XSSFCellBorder(ct)); + _cellXf.borderId = (uint)idx; + _cellXf.applyBorder = true; + } + static CT_Color ConvertToCTColor(XSSFColor xssfColor) + { + CT_Color ctColor = new CT_Color(); + + if (xssfColor != null) + { + ctColor = new CT_Color(); + + if (xssfColor.IsRGB) + { + byte[] rgb = xssfColor.RGB; + ctColor.rgb = rgb; + } + else if (xssfColor.IsIndexed) + { + ctColor.indexed = (uint)xssfColor.Indexed; + } + else if (xssfColor.IsThemed) + { + ctColor.theme = (uint)xssfColor.Theme; + } + else if (xssfColor.IsAuto) + { + ctColor.auto = true; + } + } + + return ctColor; + } + private static ST_BorderStyle ToStBorderStyle(BorderStyle borderStyle) + { + ST_BorderStyle stBorderStyle; + + switch (borderStyle) + { + case BorderStyle.None: + stBorderStyle = ST_BorderStyle.none; + break; + case BorderStyle.Thin: + stBorderStyle = ST_BorderStyle.thin; + break; + case BorderStyle.Medium: + stBorderStyle = ST_BorderStyle.medium; + break; + case BorderStyle.Dashed: + stBorderStyle = ST_BorderStyle.dashed; + break; + case BorderStyle.Dotted: + stBorderStyle = ST_BorderStyle.dotted; + break; + case BorderStyle.Thick: + stBorderStyle = ST_BorderStyle.thick; + break; + case BorderStyle.Double: + stBorderStyle = ST_BorderStyle.@double; + break; + case BorderStyle.Hair: + stBorderStyle = ST_BorderStyle.hair; + break; + case BorderStyle.MediumDashed: + stBorderStyle = ST_BorderStyle.mediumDashed; + break; + case BorderStyle.DashDot: + stBorderStyle = ST_BorderStyle.dashDot; + break; + case BorderStyle.MediumDashDot: + stBorderStyle = ST_BorderStyle.mediumDashDot; + break; + case BorderStyle.DashDotDot: + stBorderStyle = ST_BorderStyle.dashDotDot; + break; + case BorderStyle.MediumDashDotDot: + stBorderStyle = ST_BorderStyle.mediumDashDotDot; + break; + case BorderStyle.SlantedDashDot: + stBorderStyle = ST_BorderStyle.slantDashDot; + break; + default: + stBorderStyle = ST_BorderStyle.none; //Default value + break; + } + return stBorderStyle; + + } + private void ApplyBorderSide(XSSFCellStyle cellStyle, BorderCellSide bSide, ExcelBorder border) + { + if (border != null && border.IsDirty()) + { + if (border.BorderColor.IsDirty()) + { + try + { + BorderSide borderSide = (BorderSide)Enum.Parse(typeof(BorderSide), bSide.ToString()); + cellStyle.SetBorderColor(borderSide, ToColor(border.BorderColor)); + } + catch (ArgumentException) { } + } + if (border.Border != null && border.Border.Length > 0) + { + BorderStyle bs = ConvertToBorderStyle(border.Border); + if (bSide == BorderCellSide.BOTTOM) + { + cellStyle.BorderBottom = bs; + } + else if (bSide == BorderCellSide.TOP) + { + cellStyle.BorderTop = bs; + } + else if (bSide == BorderCellSide.LEFT) + { + cellStyle.BorderLeft = bs; + } + else if (bSide == BorderCellSide.RIGHT) + { + cellStyle.BorderRight = bs; + } + } + } + } + internal BorderStyle ConvertToBorderStyle(string style) + { + style = style.ToUpper(); + switch (style) + { + case "NONE": return BorderStyle.None; + case "DASH_DOT": return BorderStyle.DashDot; + case "DASH_DOT_DOT": return BorderStyle.DashDotDot; + case "DASHED": return BorderStyle.Dashed; + case "DOTTED": return BorderStyle.Dotted; + case "DOUBLE": return BorderStyle.Double; + case "HAIR": return BorderStyle.Hair; + case "MEDIUM": return BorderStyle.Medium; + case "MEDIUM_DASH_DOT": return BorderStyle.MediumDashDot; + case "MEDIUM_DASH_DOT_DOT":return BorderStyle.MediumDashDotDot; + case "MEDIUM_DASHED":return BorderStyle.MediumDashed; + case "SLANTED_DASH_DOT": return BorderStyle.SlantedDashDot; + case "THICK": return BorderStyle.Thick; + case "THIN":return BorderStyle.Thin; + default: throw new ArgumentException("Invalid border style: " + style); + } + } + internal enum BorderCellSide + { + RIGHT, LEFT, TOP, BOTTOM, DIAGONALUP, DIAGONALDOWN + } + + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelSpreadsheet.cs b/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelSpreadsheet.cs new file mode 100644 index 000000000..c74e4046e --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelSpreadsheet.cs @@ -0,0 +1,523 @@ +using System; +using System.Collections.Generic; +using System.IO; +using GeneXus.Application; +using log4net; +using NPOI.SS.UserModel; +using NPOI.Util; +using NPOI.XSSF.UserModel; + +namespace GeneXus.MSOffice.Excel.Poi.Xssf +{ + public class ExcelSpreadsheet : IExcelSpreadsheet + { + private static readonly ILog logger = LogManager.GetLogger(typeof(ExcelSpreadsheet)); + private XSSFWorkbook _workbook; + private string _documentFileName; + private bool _autoFitColumnsOnSave = false; + private IGXError _errorHandler; + private StylesCache _stylesCache; + internal static string DefaultExtension = ".xlsx"; + public ExcelSpreadsheet(IGXError errHandler, string fileName, string template) + { + _errorHandler = errHandler; + if (string.IsNullOrEmpty(Path.GetExtension(fileName))) + { + fileName += DefaultExtension; + } + + if (!string.IsNullOrEmpty(template)) + { + GxFile templateFile = new GxFile(GxContext.StaticPhysicalPath(), template, GxFileType.Private); + if (templateFile.Exists()) + { + _workbook = new XSSFWorkbook(templateFile.GetStream()); + } + else + { + throw new ExcelTemplateNotFoundException(); + } + } + else + { + GxFile file = new GxFile(GxContext.StaticPhysicalPath(), fileName, GxFileType.Private); + if (file.Exists()) + { + _workbook = new XSSFWorkbook(file.GetStream()); + } + else + { + _workbook = new XSSFWorkbook(); + } + } + + _documentFileName = fileName; + + _stylesCache = new StylesCache(_workbook); + } + + public bool Autofit { set => this._autoFitColumnsOnSave = value; } + + public bool Save() + { + return SaveAsImpl(_documentFileName); + } + + private bool SaveAsImpl(string fileName) + { + AutoFitColumns(); + RecalculateFormulas(); + + try + { + using (ByteArrayOutputStream fs = new ByteArrayOutputStream()) + { + _workbook.Write(fs); + + using (MemoryStream inStream = new MemoryStream(fs.ToByteArray())) + { + GxFile file = new GxFile(GxContext.StaticPhysicalPath(), fileName, GxFileType.Private); + file.Create(inStream); + int errCode = file.ErrCode; + file.Close(); + return errCode == 0; + } + } + } + catch (Exception ex) + { + GXLogging.Error(logger, "Save error", ex); + return false; + } + } + + public bool SaveAs(string newFileName) + { + return SaveAsImpl(newFileName); + } + + public bool Close() + { + bool result; + try + { + result = Save(); + _workbook.Close(); + } + catch (Exception ex) + { + GXLogging.Error(logger, "Close error", ex); + return false; + } + return result; + } + + public IExcelCellRange GetCells(IExcelWorksheet worksheet, int startRow, int startCol, int rowCount, int colCount) + { + return new ExcelCells(_errorHandler, this, _workbook, (XSSFSheet)_workbook.GetSheet(worksheet.Name), startRow - 1, startCol - 1, rowCount, colCount, false, _stylesCache); + } + + public IExcelCellRange GetCell(IExcelWorksheet worksheet, int startRow, int startCol) + { + return GetCells(worksheet, startRow, startCol, 1, 1); + } + + + public bool InsertRow(IExcelWorksheet worksheet, int rowIdx, int rowCount) + { + XSSFSheet sheet = (XSSFSheet)GetSheet(worksheet); + + int createNewRowAt = rowIdx; // Add the new row between row 9 and 10 + + if (sheet != null) + { + for (int i = 1; i <= rowCount; i++) + { + int lastRow = Math.Max(0, sheet.LastRowNum); + if (lastRow < rowIdx) + { + for (int j = lastRow; j <= rowIdx; j++) + { + sheet.CreateRow(j); + } + } + else + { + if (sheet.GetRow(createNewRowAt) == null) + { + sheet.CreateRow(createNewRowAt); + } + sheet.ShiftRows(createNewRowAt, lastRow, 1, true, false); + } + } + return true; + } + return false; + } + + public bool InsertColumn(IExcelWorksheet worksheet, int colIdx, int colCount) + { + /* + * XSSFSheet sheet = GetSheet(worksheet); int createNewColumnAt = colIdx; //Add + * the new row between row 9 and 10 + * + * if (sheet != null) { for (int i = 1; i<= colCount; i++) { + * + * int lastRow = sheet.getLastRowNum(); sheet.shi(createNewColumnAt, lastRow, 1, + * true, false); XSSFRow newRow = sheet.createRow(createNewColumnAt); } return + * true; } return false; + */ + return false; // POI not supported + } + + public bool DeleteRow(IExcelWorksheet worksheet, int rowIdx) + { + XSSFSheet sheet = GetSheet(worksheet); + if (sheet != null) + { + XSSFRow row = (XSSFRow)sheet.GetRow(rowIdx); + if (row != null) + { + sheet.RemoveRow(row); + } + int rowIndex = rowIdx; + int lastRowNum = sheet.LastRowNum; + if (rowIndex >= 0 && rowIndex < lastRowNum) + { + sheet.ShiftRows(rowIndex + 1, lastRowNum, -1); + } + } + return sheet != null; + } + + public List GetWorksheets() + { + List list = new List(); + for (int i = 0; i < _workbook.NumberOfSheets; i++) + { + XSSFSheet sheet = (XSSFSheet)_workbook.GetSheetAt(i); + if (sheet != null) + { + list.Add(new ExcelWorksheet(sheet)); + } + } + return list; + } + + public bool InsertWorksheet(string newSheetName, int idx) + { + XSSFSheet newSheet; + if (_workbook.GetSheet(newSheetName) == null) + { + newSheet = (XSSFSheet)_workbook.CreateSheet(newSheetName); + } + else + { + throw new ExcelException(13, "The workbook already contains a sheet named:" + newSheetName); + } + return newSheet != null; + } + + public bool CloneSheet(string sheetName, string newSheetName) + { + int idx = _workbook.GetSheetIndex(sheetName); + if (_workbook.GetSheet(newSheetName) != null) + { + throw new ExcelException(13, "The workbook already contains a sheet named:" + newSheetName); + } + if (idx < 0) + { + throw new ExcelException(14, "The workbook does not contain a sheet named:" + sheetName); + } + _workbook.CloneSheet(idx, newSheetName); + return true; + } + + private XSSFSheet GetSheet(IExcelWorksheet sheet) + { + return (XSSFSheet)_workbook.GetSheet(sheet.Name); + } + + private void RecalculateFormulas() + { + try + { + _workbook.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll(); + _workbook.SetForceFormulaRecalculation(true); + } + catch (Exception e) + { + logger.Error("recalculateFormulas", e); + } + } + + private void AutoFitColumns() + { + if (_autoFitColumnsOnSave) + { + int sheetsCount = _workbook.NumberOfSheets; + for (int i = 0; i < sheetsCount; i++) + { + ISheet sheet = _workbook.GetSheetAt(i); + int columnCount = 0; + for (int j = 0; j <= sheet.LastRowNum; j++) + { + IRow row = sheet.GetRow(j); + if (row != null) + { + columnCount = Math.Max(columnCount, row.LastCellNum); + } + } + for (int j = 0; j < columnCount; j++) + { + sheet.AutoSizeColumn(j); + } + } + } + } + + public bool SetActiveWorkSheet(string name) + { + int idx = _workbook.GetSheetIndex(name); + if (idx >= 0) + { + _workbook.GetSheetAt(idx).IsSelected = true; + _workbook.SetActiveSheet(idx); + _workbook.SetSelectedTab(idx); + } + return idx >= 0; + } + + public ExcelWorksheet GetWorkSheet(string name) + { + XSSFSheet sheet = (XSSFSheet)_workbook.GetSheet(name); + if (sheet != null) + return new ExcelWorksheet(sheet); + return null; + } + + public void SetColumnWidth(IExcelWorksheet worksheet, int colIdx, int width) + { + XSSFSheet sheet = (XSSFSheet)_workbook.GetSheet(worksheet.Name); + if (colIdx >= 1 && sheet != null && width <= 255) + { + sheet.SetColumnWidth(colIdx - 1, 256 * width); + } + } + + public void SetRowHeight(IExcelWorksheet worksheet, int rowIdx, int height) + { + XSSFSheet sheet = (XSSFSheet)_workbook.GetSheet(worksheet.Name); + if (rowIdx >= 1 && sheet != null) + { + rowIdx = rowIdx - 1; + if (sheet.GetRow(rowIdx) == null) + { + sheet.CreateRow(rowIdx); + } + sheet.GetRow(rowIdx).HeightInPoints = (short)height; + } + } + + public bool DeleteColumn(IExcelWorksheet worksheet, int colIdx) + { + XSSFSheet sheet = (XSSFSheet)_workbook.GetSheet(worksheet.Name); + if (colIdx >= 0) + { + return DeleteColumnImpl(sheet, colIdx); + } + return false; + } + + private bool DeleteColumnImpl(XSSFSheet sheet, int columnToDelete) + { + for (int rId = 0; rId <= sheet.LastRowNum; rId++) + { + IRow row = sheet.GetRow(rId); + for (int cID = columnToDelete; row != null && cID <= row.LastCellNum; cID++) + { + ICell cOld = row.GetCell(cID); + if (cOld != null) + { + row.RemoveCell(cOld); + } + ICell cNext = row.GetCell(cID + 1); + if (cNext != null) + { + ICell cNew = row.CreateCell(cID, cNext.CellType); + CloneCell(cNew, cNext); + // Set the column width only on the first row. + // Otherwise, the second row will overwrite the original column width set previously. + if (rId == 0) + { + sheet.SetColumnWidth(cID, sheet.GetColumnWidth(cID + 1)); + } + } + } + } + return true; + } + + private int GetNumberOfRows(XSSFSheet sheet) + { + int rowNum = sheet.LastRowNum + 1; + return rowNum; + } + + public int GetNrColumns(XSSFSheet sheet) + { + IRow headerRow = sheet.GetRow(0); + return headerRow.LastCellNum; + } + + public void InsertNewColumnBefore(XSSFSheet sheet, int columnIndex) + { + IFormulaEvaluator evaluator = _workbook.GetCreationHelper().CreateFormulaEvaluator(); + evaluator.ClearAllCachedResultValues(); + + int nrRows = GetNumberOfRows(sheet); + int nrCols = GetNrColumns(sheet); + + for (int row = 0; row < nrRows; row++) + { + IRow r = sheet.GetRow(row); + + if (r == null) + { + continue; + } + + // Shift to the right + for (int col = nrCols; col > columnIndex; col--) + { + ICell rightCell = r.GetCell(col); + if (rightCell != null) + { + r.RemoveCell(rightCell); + } + + ICell leftCell = r.GetCell(col - 1); + + if (leftCell != null) + { + ICell newCell = r.CreateCell(col, leftCell.CellType); + CloneCell(newCell, leftCell); + } + } + + // Delete old column + CellType cellType = CellType.Blank; + + ICell currentEmptyWeekCell = r.GetCell(columnIndex); + if (currentEmptyWeekCell != null) + { + r.RemoveCell(currentEmptyWeekCell); + } + + // Create new column + r.CreateCell(columnIndex, cellType); + } + + // Adjust the column widths + for (int col = nrCols; col > columnIndex; col--) + { + sheet.SetColumnWidth(col, sheet.GetColumnWidth(col - 1)); + } + } + /* + * Takes an existing Cell and merges all the styles and formula into the new one + */ + private static void CloneCell(ICell cNew, ICell cOld) + { + cNew.CellComment = cOld.CellComment; + cNew.CellStyle = cOld.CellStyle; + + switch (cOld.CellType) + { + case CellType.Boolean: + { + cNew.SetCellValue(cOld.BooleanCellValue); + break; + } + case CellType.Numeric: + { + cNew.SetCellValue(cOld.NumericCellValue); + break; + } + case CellType.String: + { + cNew.SetCellValue(cOld.StringCellValue); + break; + } + case CellType.Error: + { + cNew.SetCellErrorValue(cOld.ErrorCellValue); + break; + } + case CellType.Formula: + { + cNew.CellFormula = cOld.CellFormula; + break; + } + default: + // Ignore + break; + } + } + + public bool DeleteSheet(int sheetIdx) + { + if (_workbook.NumberOfSheets > sheetIdx) + { + _workbook.RemoveSheetAt(sheetIdx); + return true; + } + return false; + } + + public bool DeleteSheet(string sheetName) + { + int sheetIndex = _workbook.GetSheetIndex(sheetName); + if (sheetIndex >= 0) + { + _workbook.RemoveSheetAt(sheetIndex); + return true; + } + return false; + } + + public bool ToggleColumn(IExcelWorksheet worksheet, int colIdx, bool visible) + { + XSSFSheet sheet = _workbook.GetSheet(worksheet.Name) as XSSFSheet; + if (sheet != null) + { + sheet.SetColumnHidden(colIdx, !visible); + return true; + } + return false; + } + + public bool ToggleRow(IExcelWorksheet worksheet, int i, bool visible) + { + XSSFSheet sheet = _workbook.GetSheet(worksheet.Name) as XSSFSheet; + if (sheet != null) + { + IRow row = sheet.GetRow(i) as XSSFRow; + if (row == null) + { + InsertRow(worksheet, i, 1); + row = sheet.GetRow(i) as XSSFRow; + } + if (row != null) + { + ICellStyle style = _workbook.CreateCellStyle(); + style.IsHidden = !visible; + row.RowStyle = style; + row.ZeroHeight = !visible; + } + return true; + } + return false; + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelWorksheet.cs b/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelWorksheet.cs new file mode 100644 index 000000000..f5be1eeca --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/poi/xssf/ExcelWorksheet.cs @@ -0,0 +1,85 @@ +using NPOI.XSSF.UserModel; + +namespace GeneXus.MSOffice.Excel.Poi.Xssf +{ + public class ExcelWorksheet : IExcelWorksheet + { + private XSSFSheet _sheet; + + public ExcelWorksheet() + { + + } + + public ExcelWorksheet(XSSFSheet sheet) + { + _sheet = sheet; + } + + public string Name => _sheet.SheetName; + + public bool Hidden + { + get + { + if (_sheet != null) + { + XSSFWorkbook wb = (XSSFWorkbook)_sheet.Workbook; + return wb.IsSheetHidden(SheetIndex(wb)); + } + return false; + } + + set + { + if (_sheet != null) + { + XSSFWorkbook wb = (XSSFWorkbook)_sheet.Workbook; + wb.SetSheetHidden(SheetIndex(wb), value ? NPOI.SS.UserModel.SheetState.Hidden : NPOI.SS.UserModel.SheetState.Visible); + } + } + } + + public bool Rename(string newName) + { + if (_sheet != null) + { + XSSFWorkbook wb = (XSSFWorkbook)_sheet.Workbook; + int sheetIndex = wb.GetSheetIndex(Name); + wb.SetSheetName(sheetIndex, newName); + return Name == newName; + } + return false; + } + + public bool Copy(string newName) + { + if (_sheet != null) + { + XSSFWorkbook wb = (XSSFWorkbook)_sheet.Workbook; + if (wb.GetSheet(newName) == null) + { + wb.CloneSheet(wb.GetSheetIndex(Name), newName); + return true; + } + } + return false; + } + + public void SetProtected(string password) + { + if (_sheet != null) + { + if (string.IsNullOrEmpty(password)) + _sheet.ProtectSheet(null); + else + _sheet.ProtectSheet(password); + } + } + + private int SheetIndex(XSSFWorkbook wb) + { + return wb.GetSheetIndex(Name); + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/poi/xssf/StylesCache.cs b/dotnet/src/dotnetframework/GxOffice/poi/xssf/StylesCache.cs new file mode 100644 index 000000000..33438bad8 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/poi/xssf/StylesCache.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using NPOI.XSSF.UserModel; + +namespace GeneXus.MSOffice.Excel.Poi.Xssf +{ + public class StylesCache + { + private XSSFWorkbook pWorkbook; + private Dictionary stylesByFont; + private Dictionary stylesByFormat; + + public StylesCache(XSSFWorkbook pWorkbook) + { + this.pWorkbook = pWorkbook; + this.stylesByFont = new Dictionary(); + this.stylesByFormat = new Dictionary(); + } + + public XSSFCellStyle GetCellStyle(XSSFFont newFont) + { + string fontKey = $"{newFont.FontHeightInPoints}{newFont.FontName}{newFont.IsBold}{newFont.IsItalic}{newFont.Underline}{newFont.Color}"; + + if (stylesByFont.ContainsKey(fontKey)) + { + return stylesByFont[fontKey]; + } + + XSSFCellStyle newStyle = (XSSFCellStyle)pWorkbook.CreateCellStyle(); + stylesByFont[fontKey] = newStyle; + return newStyle; + } + + public XSSFCellStyle GetCellStyle(short format) + { + string formatKey = format.ToString(); + + if (stylesByFormat.ContainsKey(formatKey)) + { + return stylesByFormat[formatKey]; + } + + XSSFCellStyle newStyle = (XSSFCellStyle)pWorkbook.CreateCellStyle(); + stylesByFormat[formatKey] = newStyle; + return newStyle; + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/style/ExcelAlignment.cs b/dotnet/src/dotnetframework/GxOffice/style/ExcelAlignment.cs new file mode 100644 index 000000000..2ea1683ed --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/style/ExcelAlignment.cs @@ -0,0 +1,39 @@ +namespace GeneXus.MSOffice.Excel.Style +{ + public class ExcelAlignment : ExcelStyleDimension + { + public const int VERTICAL_ALIGN_MIDDLE = 1; + public const int VERTICAL_ALIGN_TOP = 2; + public const int VERTICAL_ALIGN_BOTTOM = 3; + public const int HORIZONTAL_ALIGN_LEFT = 1; + public const int HORIZONTAL_ALIGN_CENTER = 2; + public const int HORIZONTAL_ALIGN_RIGHT = 3; + + private int horizontalAlignment; + private int verticalAlignment; + + public ExcelAlignment() + { + } + + public int HorizontalAlignment + { + get => horizontalAlignment; + set + { + horizontalAlignment = value; + SetChanged(); + } + } + + public int VerticalAlignment + { + get => verticalAlignment; + set + { + verticalAlignment = value; + SetChanged(); + } + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/style/ExcelBorder.cs b/dotnet/src/dotnetframework/GxOffice/style/ExcelBorder.cs new file mode 100644 index 000000000..1cc921247 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/style/ExcelBorder.cs @@ -0,0 +1,25 @@ +namespace GeneXus.MSOffice.Excel.Style +{ + public class ExcelBorder : ExcelStyleDimension + { + private ExcelColor borderColor; + private string borderStyle = string.Empty; + + public string Border + { + get => borderStyle; + set + { + borderStyle = value; + SetChanged(); + } + } + + public ExcelBorder() + { + borderColor = new ExcelColor(); + } + + public ExcelColor BorderColor { get => borderColor; set => borderColor = value; } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/style/ExcelCellBorder.cs b/dotnet/src/dotnetframework/GxOffice/style/ExcelCellBorder.cs new file mode 100644 index 000000000..90032afae --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/style/ExcelCellBorder.cs @@ -0,0 +1,40 @@ +namespace GeneXus.MSOffice.Excel.Style +{ + public class ExcelCellBorder + { + private ExcelBorder borderTop = new ExcelBorder(); + private ExcelBorder borderBottom = new ExcelBorder(); + private ExcelBorder borderLeft = new ExcelBorder(); + private ExcelBorder borderRight = new ExcelBorder(); + private ExcelBorder borderDiagonalUp = new ExcelBorder(); + private ExcelBorder borderDiagonalDown = new ExcelBorder(); + + public void SetAll(ExcelBorder borderStyle) + { + borderTop = borderStyle; + borderBottom = borderStyle; + borderLeft = borderStyle; + borderRight = borderStyle; + } + + public ExcelBorder BorderBottom { get => borderBottom; set => borderBottom = value; } + + public ExcelBorder BorderTop => borderTop; + public void GetBorderTop(ExcelBorder value) + { + borderTop = value; + } + + public ExcelBorder BorderLeft => borderLeft; + public void GetBorderLeft(ExcelBorder value) + { + borderLeft = value; + } + + public ExcelBorder BorderRight { get => borderRight; set => borderRight = value; } + + public ExcelBorder BorderDiagonalUp { get => borderDiagonalUp; set => borderDiagonalUp = value; } + + public ExcelBorder BorderDiagonalDown { get => borderDiagonalDown; set => borderDiagonalDown = value; } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/style/ExcelColor.cs b/dotnet/src/dotnetframework/GxOffice/style/ExcelColor.cs new file mode 100644 index 000000000..16e2b74a7 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/style/ExcelColor.cs @@ -0,0 +1,49 @@ +namespace GeneXus.MSOffice.Excel.Style +{ + public class ExcelColor : ExcelStyleDimension + { + private int? _alpha = null; + public int? Alpha => _alpha; + + public int? Red => _red; + + public int? Green => _green; + + public int? Blue => _blue; + + private int? _red = null; + private int? _green = null; + private int? _blue = null; + + public ExcelColor() + { + + } + + public ExcelColor(int alpha, int r, int g, int b) + { + SetColorImpl(alpha, r, g, b); + } + + public bool SetColorRGB(int r, int g, int b) + { + SetColorImpl(0, r, g, b); + return true; + } + + public bool SetColorARGB(int alpha, int r, int g, int b) + { + SetColorImpl(alpha, r, g, b); + return true; + } + + private void SetColorImpl(int alpha, int r, int g, int b) + { + _alpha = alpha; + _red = r; + _green = g; + _blue = b; + SetChanged(); + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/style/ExcelFill.cs b/dotnet/src/dotnetframework/GxOffice/style/ExcelFill.cs new file mode 100644 index 000000000..8ad853303 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/style/ExcelFill.cs @@ -0,0 +1,19 @@ +namespace GeneXus.MSOffice.Excel.Style +{ + public class ExcelFill : ExcelStyleDimension + { + private ExcelColor cellBackColor; + + public ExcelFill() + { + cellBackColor = new ExcelColor(); + } + + public ExcelColor CellBackColor => cellBackColor; + + public override bool IsDirty() + { + return base.IsDirty() || cellBackColor.IsDirty(); + } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/style/ExcelFont.cs b/dotnet/src/dotnetframework/GxOffice/style/ExcelFont.cs new file mode 100644 index 000000000..0f9156103 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/style/ExcelFont.cs @@ -0,0 +1,80 @@ +namespace GeneXus.MSOffice.Excel.Style +{ + public class ExcelFont : ExcelStyleDimension + { + private string fontFamily = null; + private bool italic; + private int size; + private bool strike; + private bool underline; + private bool bold; + private ExcelColor color = null; + + public ExcelFont() + { + color = new ExcelColor(); + } + + public string FontFamily + { + get => fontFamily; + set + { + this.fontFamily = value; + SetChanged(); + } + } + + public bool Italic + { + get => italic; + set + { + this.italic = value; + SetChanged(); + } + } + + public int Size + { + get => size; + set + { + this.size = value; + SetChanged(); + } + } + + public bool Strike + { + get => strike; + set + { + this.strike = value; + SetChanged(); + } + } + + public bool Underline + { + get => underline; + set + { + this.underline = value; + SetChanged(); + } + } + + public bool Bold + { + get => bold; + set + { + this.bold = value; + SetChanged(); + } + } + + public ExcelColor Color => color; + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/style/ExcelStyle.cs b/dotnet/src/dotnetframework/GxOffice/style/ExcelStyle.cs new file mode 100644 index 000000000..3ef1fd5bb --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/style/ExcelStyle.cs @@ -0,0 +1,68 @@ +namespace GeneXus.MSOffice.Excel.Style +{ + public class ExcelStyle : ExcelStyleDimension + { + private ExcelFill _cellFill; + private ExcelFont _cellFont; + private bool _locked; + private bool _hidden; + private bool _wrapText; + private bool _shrinkToFit; + private ExcelCellBorder _borders; + private int _indentation = -1; + private int _textRotation; + private string _dataFormat; + private ExcelAlignment _cellAlignment; + + public ExcelStyle() + { + _cellFill = new ExcelFill(); + _cellFont = new ExcelFont(); + _cellAlignment = new ExcelAlignment(); + _borders = new ExcelCellBorder(); + } + + public bool IsLocked() + { + return _locked; + } + + public bool Locked + { + set { _locked = value; } + } + + public bool IsHidden() + { + return _hidden; + } + + public bool Hidden + { + set => _hidden = value; + } + + public ExcelAlignment CellAlignment => _cellAlignment; + + public ExcelFill CellFill => _cellFill; + + public ExcelFont CellFont => _cellFont; + + public override bool IsDirty() + { + return base.IsDirty() || _cellFill.IsDirty() || _cellFont.IsDirty() || _cellAlignment.IsDirty(); + } + + public bool WrapText { get => _wrapText; set => _wrapText = value; } + + public bool ShrinkToFit { get => _shrinkToFit; set => _shrinkToFit = value; } + + public int TextRotation { get => _textRotation; set => _textRotation = value; } + + public ExcelCellBorder Border { get => _borders; set => _borders = value; } + + public int Indentation { get => _indentation; set => _indentation = value; } + + public string DataFormat { get => _dataFormat; set => _dataFormat = value; } + } +} diff --git a/dotnet/src/dotnetframework/GxOffice/style/ExcelStyleDimension.cs b/dotnet/src/dotnetframework/GxOffice/style/ExcelStyleDimension.cs new file mode 100644 index 000000000..0e6dd7178 --- /dev/null +++ b/dotnet/src/dotnetframework/GxOffice/style/ExcelStyleDimension.cs @@ -0,0 +1,17 @@ +namespace GeneXus.MSOffice.Excel.Style +{ + public abstract class ExcelStyleDimension + { + private bool isDirty = false; + + public virtual bool IsDirty() + { + return isDirty; + } + + public void SetChanged() + { + isDirty = true; + } + } +} diff --git a/dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj b/dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj index 1b2383d69..d11494d93 100644 --- a/dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj +++ b/dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj @@ -73,6 +73,7 @@ + diff --git a/dotnet/test/DotNetCoreUnitTest/Excel/ExcelPoiTest.cs b/dotnet/test/DotNetCoreUnitTest/Excel/ExcelPoiTest.cs new file mode 100644 index 000000000..79ea0afee --- /dev/null +++ b/dotnet/test/DotNetCoreUnitTest/Excel/ExcelPoiTest.cs @@ -0,0 +1,1191 @@ +using System; +using System.Collections.Generic; +using System.IO; +using GeneXus.Application; +using GeneXus.MSOffice.Excel; +using GeneXus.MSOffice.Excel.Poi.Xssf; +using GeneXus.MSOffice.Excel.Style; +using GeneXus.Utils; +using NPOI.HPSF; +using Xunit; + +namespace DotNetUnitTest.Excel +{ + public class ExcelPoiTest + { + string basePath; + public ExcelPoiTest() + { + basePath = GxContext.StaticPhysicalPath(); + + } + [Fact] + public void TestNumberFormat1() + { + ExcelSpreadsheetGXWrapper excel = Create("testNumberFormat1"); + excel.GetCells(1, 1, 1, 1).NumericValue=123.456M; + excel.GetCells(2, 1, 1, 1).NumericValue = 1; + excel.GetCells(3, 1, 1, 1).NumericValue = 100; + + excel.GetCells(4, 1, 1, 1).NumericValue = 123.456M; + excel.Save(); + + } + [Fact] + public void TestCellStyle1() + { + ExcelSpreadsheetGXWrapper excel = Create("testCellStyle1"); + excel.SetColumnWidth(1, 100); + excel.GetCells(2, 1, 1, 5).NumericValue = 123.456M; + ExcelStyle newCellStyle = new ExcelStyle(); + newCellStyle.CellFont.Bold = true; + excel.GetCells(2, 1, 1, 5).SetCellStyle(newCellStyle); + + bool ok = excel.Save(); + Assert.True(ok); + } + [Fact] + public void TestCellStyle2() + { + ExcelSpreadsheetGXWrapper excel = Create("testCellStyle2"); + excel.SetColumnWidth(1, 100); + excel.GetCells(2, 1, 5, 5).NumericValue = 123.456M; + ExcelStyle newCellStyle = new ExcelStyle(); + newCellStyle. CellFont. Bold = true; + excel.GetCells(2, 1, 3, 3).SetCellStyle(newCellStyle); + + excel.Save(); + + } + + [Fact] + public void TestInsertSheets() + { + ExcelSpreadsheetGXWrapper excel = Create("testInsertSheets"); + InsertSheet(excel); + } + + [Fact] + public void TestInsertSheetTwice() + { + ExcelSpreadsheetGXWrapper excel = Create("testInsertSheetTwice"); + InsertSheet(excel); + + excel = Open("testInsertSheetTwice"); + bool ok = excel.InsertSheet("test1"); + Assert.False(ok); + ok = excel.InsertSheet("test2"); + Assert.False(ok); + Assert.True(excel.ErrCode != 0); + ok = excel.InsertSheet("test1"); + Assert.False(ok); + Assert.True(excel.ErrCode != 0); + excel.Save(); + excel.Close(); + } + + private void InsertSheet(ExcelSpreadsheetGXWrapper excel) + { + + bool ok = excel.InsertSheet("test1"); + Assert.True(ok); + ok = excel.InsertSheet("test2"); + Assert.True(ok); + ok = excel.InsertSheet("test1"); + Assert.False(ok); + excel.Save(); + excel.Close(); + } + + [Fact] + public void TestInsertDuplicateSheets() + { + ExcelSpreadsheetGXWrapper excel = Create("testInsertDuplicateSheets"); + bool ok = excel.InsertSheet("test1"); + Assert.True(ok); + ok = excel.InsertSheet("test1"); + Assert.False(ok); + LogErrorCodes(excel); + ok = excel.InsertSheet("test1"); + LogErrorCodes(excel); + Assert.False(ok); + excel.Save(); + } + + [Fact] + public void TestActiveWorksheet() + { + ExcelSpreadsheetGXWrapper excel = Create("testActiveWorksheet"); + excel.GetCells(2, 1, 5, 5).NumericValue = 123.456M; + excel.InsertSheet("test1"); + + excel.InsertSheet("test2"); + excel.InsertSheet("test3"); + excel.SetCurrentWorksheetByName("test2"); + excel.GetCells(2, 1, 5, 5).NumericValue=3; + excel.Save(); + + } + + [Fact] + public void TestOpenAndSave() + { + ExcelSpreadsheetGXWrapper excel = Create("testActive"); + try + { + excel.GetCells(2, 1, 5, 5).SetDate(new DateTime()); + } + catch (Exception e) + { + Console.WriteLine(e.StackTrace); + } + excel.Save(); + } + [Fact] + public void TestOpenAndSaveLocked() + { + string filePath = Path.Combine(basePath, "testLocked.xlsx"); + ExcelSpreadsheetGXWrapper newFile = Create("testLocked"); + newFile.Save(); + newFile.Close(); + + try + { + using (FileStream fs = File.OpenWrite(filePath)) + { + + //Excel should be opened. + ExcelSpreadsheetGXWrapper excel = Open("testLocked"); + Assert.Equal(7, excel.ErrCode);//"File is locked" + try + { + excel.GetCells(2, 1, 5, 5).SetDate(new DateTime()); + } + catch (Exception e) + { + Console.WriteLine(e.StackTrace); + } + excel.Save(); + } + } + catch (Exception) { } + } + + [Fact] + + public void TestFolderNotExists() + { + string excel1 = Path.Combine(basePath, "notexistsFolder", "test-active"); + ExcelSpreadsheetGXWrapper excel = new ExcelSpreadsheetGXWrapper(); + excel.Open(excel1); + + try + { + excel.GetCells(2, 1, 5, 5).SetDate(new DateTime()); + } + catch (Exception e) + { + Console.WriteLine(e.StackTrace); + } + bool saved = excel.Save(); + + Assert.False(saved); + Assert.NotEqual(0, excel.ErrCode); + Assert.NotEqual(string.Empty, excel.ErrDescription); + } + + [Fact] + + public void TestWithoutExtensions() + { + string excel1 = Path.Combine(basePath, "testWithoutExtensions"); + EnsureFileDoesNotExists(excel1 + ".xlsx"); + ExcelSpreadsheetGXWrapper excel = new ExcelSpreadsheetGXWrapper(); + excel.Open(excel1); + excel.InsertSheet("genexus0"); + excel.InsertSheet("genexus1"); + excel.InsertSheet("genexus2"); + + List wSheets = excel.GetWorksheets(); + Assert.True(wSheets.Count == 3); + Assert.True(wSheets[0].Name == "genexus0"); + Assert.True(wSheets[1].Name == "genexus1"); + Assert.True(wSheets[2].Name == "genexus2"); + + excel.Save(); + + } + + [Fact] + + public void TestInsertSheet() + { + ExcelSpreadsheetGXWrapper excel = Create("testInsertSheet"); + excel.InsertSheet("genexus0"); + excel.InsertSheet("genexus1"); + excel.InsertSheet("genexus2"); + + List wSheets = excel.GetWorksheets(); + Assert.True(wSheets.Count == 3); + Assert.True(wSheets[0].Name == "genexus0"); + Assert.True(wSheets[1].Name == "genexus1"); + Assert.True(wSheets[2].Name == "genexus2"); + + excel.Save(); + + } + + + [Fact] + + public void TestDeleteSheet() + { + ExcelSpreadsheetGXWrapper excel = Create("testDeleteSheet"); + excel.InsertSheet("gx1"); + excel.InsertSheet("gx2"); + excel.InsertSheet("gx3"); + excel.InsertSheet("gx4"); + + List wSheets = excel.GetWorksheets(); + Assert.True(wSheets.Count == 4); + Assert.True(wSheets[0].Name == "gx1"); + Assert.True(wSheets[1].Name == "gx2"); + Assert.True(wSheets[2].Name == "gx3"); + excel.DeleteSheet(2); + wSheets = excel.GetWorksheets(); + Assert.True(wSheets[0].Name == "gx1"); + Assert.True(wSheets[1].Name == "gx3"); + excel.Save(); + + } + + [Fact] + + public void TestSetCellValues() + { + ExcelSpreadsheetGXWrapper excel = Create("testSetCellValues"); + excel.Autofit = true; + excel.GetCells(1, 1, 1, 1).NumericValue = 100; + excel.GetCells(2, 1, 1, 1).Text="hola!"; + excel.GetCells(3, 1, 1, 1).DateValue=new DateTime(); + excel.GetCells(4, 1, 1, 1).NumericValue = 66.78M; + + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testSetCellValues"); + + Assert.Equal(100, excel.GetCells(1, 1, 1, 1).NumericValue); + + Assert.Equal("hola!", excel.GetCells(2, 1, 1, 1).Text); + excel.Save(); + } + + [Fact] + + public void TestFormulas() + { + ExcelSpreadsheetGXWrapper excel = Create("testFormulas"); + excel.Autofit=true; + excel.GetCell(1, 1).NumericValue = 5; + excel.GetCell(2, 1).NumericValue = 6; + excel.GetCell(3, 1).Text = "=A1+A2"; + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testFormulas"); + + Assert.Equal(11, excel.GetCell(3, 1).NumericValue); + + excel.Save(); + } + + + [Fact] + + public void TestExcelCellRange() + { + ExcelSpreadsheetGXWrapper excel = Create("testExcelCellRange"); + IExcelCellRange cellRange = excel.GetCells(2, 2, 5, 10); + + Assert.Equal(2, cellRange.ColumnStart); + Assert.Equal(11, cellRange.ColumnEnd); + Assert.Equal(2, cellRange.RowStart); + Assert.Equal(6, cellRange.RowEnd); + excel.Close(); + } + + + [Fact] + public void TestSetCurrentWorksheetByName() + { + ExcelSpreadsheetGXWrapper excel = Create("testSetCurrentWorksheetByName"); + excel.InsertSheet("hoja1"); + excel.InsertSheet("hoja2"); + excel.InsertSheet("hoja3"); + excel.Save(); + excel.Close(); + excel = Open("testSetCurrentWorksheetByName"); + excel.SetCurrentWorksheetByName("hoja2"); + Assert.Equal("hoja2", excel.CurrentWorksheet.Name); + excel.GetCell(5, 5).Text = "hola"; + excel.Save(); + excel.Close(); + + + excel = Open("testSetCurrentWorksheetByName"); + excel.SetCurrentWorksheetByName("hoja2"); + Assert.Equal("hola", excel.GetCell(5, 5).Text); + + excel.SetCurrentWorksheetByName("hoja1"); + Assert.Equal("", excel.GetCell(5, 5).Text); + excel.Close(); + } + + [Fact] + + public void TestSetCurrentWorksheetByIdx() + { + ExcelSpreadsheetGXWrapper excel = Create("testSetCurrentWorksheetByIdx"); + excel.InsertSheet("hoja1"); + excel.InsertSheet("hoja2"); + excel.InsertSheet("hoja3"); + excel.Save(); + excel.Close(); + excel = Open("testSetCurrentWorksheetByIdx"); + excel.SetCurrentWorksheet(2); + Assert.Equal("hoja2", excel.CurrentWorksheet.Name); + excel.GetCell(5, 5).Text = "hola"; + excel.Save(); + excel.Close(); + + + excel = Open("testSetCurrentWorksheetByIdx"); + + bool ok = excel.SetCurrentWorksheet(2); + Assert.Equal("hola", excel.GetCell(5, 5).Text); + Assert.True(ok); + + ok = excel.SetCurrentWorksheet(1); + Assert.True(ok); + ok = excel.SetCurrentWorksheet(3); + Assert.True(ok); + ok = excel.SetCurrentWorksheet(4); + Assert.False(ok); + ok = excel.SetCurrentWorksheet(5); + Assert.False(ok); + ok = excel.SetCurrentWorksheet(0); + Assert.False(ok); + excel.Close(); + } + + + [Fact] + + public void TestCopySheet() + { + ExcelSpreadsheetGXWrapper excel = Create("testCopySheet"); + + excel.InsertSheet("hoja1"); + excel.SetCurrentWorksheetByName("hoja1"); + excel.GetCells(1, 1, 3, 3).Text="test"; + excel.InsertSheet("hoja2"); + excel.InsertSheet("hoja3"); + excel.Save(); + excel.Close(); + excel = Open("testCopySheet"); + excel.SetCurrentWorksheetByName("hoja1"); + excel. CurrentWorksheet.Copy("hoja1Copia"); + excel.Save(); + excel.Close(); + excel = Open("testCopySheet"); + excel.SetCurrentWorksheetByName("hoja1Copia"); + Assert.Equal("test", excel.GetCells(1, 1, 3, 3).Text); + excel.Close(); + } + + [Fact] + public void TestCopySheet2() + { + ExcelSpreadsheetGXWrapper excel = Create("testCopySheet"); + + excel.InsertSheet("hoja1"); + excel.SetCurrentWorksheetByName("hoja1"); + excel.GetCells(1, 1, 3, 3).Text="test"; + excel.InsertSheet("hoja2"); + excel.InsertSheet("hoja3"); + excel.Save(); + excel.Close(); + excel = Open("testCopySheet"); + excel.SetCurrentWorksheetByName("hoja1"); + excel. CurrentWorksheet.Copy("hoja1Copia"); + excel. CurrentWorksheet.Copy("hoja1Copia"); + excel. CurrentWorksheet.Copy("hoja1Copia"); + excel.Save(); + excel.Close(); + excel = Open("testCopySheet"); + excel.SetCurrentWorksheetByName("hoja1Copia"); + Assert.Equal("test", excel.GetCells(1, 1, 3, 3).Text); + excel.Close(); + } + + + [Fact] + + public void TestGetWorksheets() + { + ExcelSpreadsheetGXWrapper excel = Create("testGetWorksheets"); + excel.InsertSheet("hoja1"); + excel.InsertSheet("hoja2"); + excel.InsertSheet("hoja3"); + excel.InsertSheet("hoja4"); + excel.Save(); + excel.Close(); + excel = Open("testGetWorksheets"); + List sheets = excel.GetWorksheets(); + Assert.Equal("hoja1", sheets[0].Name); + Assert.Equal("hoja2", sheets[1].Name); + Assert.Equal("hoja3", sheets[2].Name); + Assert.Equal("hoja4", sheets[3].Name); + excel.Close(); + } + + [Fact] + + public void TestHiddenCells() + { + ExcelSpreadsheetGXWrapper excel = Create("testHiddenCells"); + + excel.Autofit = true; + excel.InsertSheet("hoja1"); + excel.SetCurrentWorksheetByName("hoja1"); + excel. CurrentWorksheet.SetProtected("password"); + excel.GetCells(1, 1, 3, 3).Text = "texto no se puede editar"; + ExcelStyle style = new ExcelStyle(); + style.Hidden=true; + excel.GetCells(1, 1, 3, 3).SetCellStyle(style); + + + ExcelCells cells = excel.GetCells(5, 1, 3, 3); + cells.Text = "texto SI se puede editar"; + style = new ExcelStyle(); + style.Locked=false; + cells.SetCellStyle(style); + excel.Save(); + excel.Close(); + } + + [Fact] + + public void TestProtectSheet() + { + ExcelSpreadsheetGXWrapper excel = Create("testProtectSheet"); + excel.Autofit = true; + excel.InsertSheet("hoja1"); + excel.SetCurrentWorksheetByName("hoja1"); + excel. CurrentWorksheet.SetProtected("password"); + excel.GetCells(1, 1, 3, 3).Text="texto no se puede editar"; + ExcelStyle style = new ExcelStyle(); + style.Locked=true; + excel.GetCells(1, 1, 3, 3).SetCellStyle(style); + + + ExcelCells cells = excel.GetCells(5, 1, 3, 3); + cells.Text="texto SI se puede editar"; + style = new ExcelStyle(); + style.Locked=false; + cells.SetCellStyle(style); + excel.Save(); + excel.Close(); + } + + private ExcelSpreadsheetGXWrapper Create(string fileName) + { + string excelPath = Path.Combine(basePath, fileName + ".xlsx"); + EnsureFileDoesNotExists(excelPath); + FileInfo theDir = new FileInfo(basePath); + if (!theDir.Exists) + { + Directory.CreateDirectory(basePath); + } + + ExcelSpreadsheetGXWrapper excel = new ExcelSpreadsheetGXWrapper(); + excel.Open(excelPath); + return excel; + } + + private ExcelSpreadsheetGXWrapper Open(string fileName) + { + string excelPath = Path.Combine(basePath, fileName + ".xlsx"); + ExcelSpreadsheetGXWrapper excel = new ExcelSpreadsheetGXWrapper(); + excel.Open(excelPath); + return excel; + } + + [Fact] + + public void TestHideSheet() + { + ExcelSpreadsheetGXWrapper excel = Create("testHideSheet"); + excel.Autofit=true; + excel.InsertSheet("hoja1"); + excel.InsertSheet("hoja2"); + excel.InsertSheet("hoja3"); + excel.InsertSheet("hoja4"); + excel.InsertSheet("hoja5"); + excel.InsertSheet("hoja6"); + excel.SetCurrentWorksheetByName("hoja2"); + + Assert.False(excel.CurrentWorksheet.Hidden); + Assert.True(excel.CurrentWorksheet.Hidden = true); + Assert.True(excel.CurrentWorksheet.Hidden); + + excel.SetCurrentWorksheet(3); + Assert.True(excel.CurrentWorksheet.Hidden = true); + + excel.SetCurrentWorksheetByName("hoja1"); + excel.Save(); + excel.Close(); + } + + + [Fact] + + public void TestCloneSheet() + { + ExcelSpreadsheetGXWrapper excel = Create("testCloneSheet"); + excel.InsertSheet("hoja1"); + excel.GetCell(1, 1).Text = "1"; + excel.InsertSheet("hoja2"); + excel.GetCell(1, 1).Text = "2"; + excel.InsertSheet("hoja3"); + excel.CloneSheet("hoja2", "cloned_hoja2"); + excel.Save(); + excel.Close(); + excel = Open("testCloneSheet"); + List sheets = excel.GetWorksheets(); + Assert.Equal(4, sheets.Count); + excel.Close(); + } + + [Fact] + + public void TestCloneSheet2() + { + ExcelSpreadsheetGXWrapper excel = Create("testCloneSheet2"); + excel.GetCell(2, 2).Text = "hello"; + bool ok = excel.CloneSheet(excel.CurrentWorksheet.Name, "clonedSheet"); + Assert.True(ok); + excel.Save(); + excel.Close(); + excel = Open("testCloneSheet2"); + List sheets = excel.GetWorksheets(); + Assert.Equal(2, sheets.Count); + excel.Close(); + } + + [Fact] + + public void TestCloneSheetError() + { + ExcelSpreadsheetGXWrapper excel = Create("testCloneSheetError"); + excel.InsertSheet("hoja1"); + excel.GetCell(1, 1).Text = "1"; + excel.InsertSheet("hoja2"); + excel.GetCell(1, 1).Text = "2"; + excel.InsertSheet("hoja3"); + excel.CloneSheet("hoja2", "cloned_hoja2"); + excel.CloneSheet("hoja2", "hoja2"); + + excel.CloneSheet("hoja2", "hoja2"); + excel.CloneSheet("hoja2", "hoja2"); + Assert.True(excel.ErrCode > 0); + excel.CloneSheet("hoja2", "hoja2"); + excel.Save(); + excel.Close(); + excel = Open("testCloneSheetError"); + List sheets = excel.GetWorksheets(); + Assert.Equal(4, sheets.Count); + excel.Close(); + } + + [Fact] + + public void TestWorksheetRename() + { + ExcelSpreadsheetGXWrapper excel = Create("testWorksheetRename"); + excel. CurrentWorksheet.Rename("defaultsheetrenamed"); + excel.InsertSheet("hoja1"); + excel.InsertSheet("hoja2"); + excel.InsertSheet("hoja3"); + excel.InsertSheet("hoja4"); + + excel.Save(); + excel.Close(); + excel = Open("testWorksheetRename"); + excel.GetWorksheets()[3].Rename("modificada"); + excel.Save(); + excel.Close(); + excel = Open("testWorksheetRename"); + List sheets = excel.GetWorksheets(); + Assert.Equal("hoja1", sheets[1].Name); + Assert.Equal("hoja2", sheets[2].Name); + Assert.Equal("modificada", sheets[3].Name); + Assert.Equal("hoja4", sheets[4].Name); + excel.Close(); + } + + [Fact] + + public void TestMergeCells() + { + ExcelSpreadsheetGXWrapper excel = Create("testMergeCells"); + excel.GetCells(2, 10, 10, 5).MergeCells(); + excel.GetCells(2, 10, 10, 5).Text="merged cells"; + excel.Save(); + excel.Close(); + } + + [Fact] + public void TestMergeMultipleCells() + { + ExcelSpreadsheetGXWrapper excel = Create("testMergeCells-2"); + excel.GetCells(1, 1, 2, 5).MergeCells(); + excel.GetCells(1, 1, 2, 5).Text = "merged cells 1"; + + excel.GetCells(5, 1, 2, 5).MergeCells(); + excel.GetCells(5, 1, 2, 5).Text = "merged cells 2"; + + excel.GetCells(8, 1, 2, 5).MergeCells(); + excel.GetCells(8, 1, 2, 5).Text = "merged cells 3"; + + excel.Save(); + excel.Close(); + } + + [Fact] + public void TestMergeMultipleCellsIntersect() + { + ExcelSpreadsheetGXWrapper excel = Create("testMergeCells-3"); + excel.GetCells(1, 1, 8, 5).MergeCells(); + excel.GetCells(1, 1, 8, 5).Text = "merged cells 1"; + + excel.GetCells(5, 1, 8, 5).MergeCells(); + excel.GetCells(5, 1, 8, 5).Text = "merged cells 2"; + + excel.Save(); + excel.Close(); + } + + + [Fact] + public void TestMergeNestedCells() + { + ExcelSpreadsheetGXWrapper excel = Create("testMergeNestedCells"); + excel.GetCells(5, 5, 4, 4).MergeCells(); + excel.GetCells(5, 5, 4, 4).Text = "merged cells"; + excel.GetCells(1, 1, 10, 10).MergeCells(); + excel.Save(); + excel.Close(); + } + + [Fact] + + public void TestMergeCellsError() + { + ExcelSpreadsheetGXWrapper excel = Create("testMergeCellsError"); + excel.GetCells(2, 10, 10, 5).MergeCells(); + excel.GetCells(2, 10, 10, 5).MergeCells(); + excel.GetCells(2, 10, 10, 5).MergeCells(); + excel.GetCells(3, 11, 2, 2).MergeCells(); + excel.GetCells(2, 10, 10, 5).MergeCells(); + + excel.GetCells(2, 10, 10, 5).Text = "merged cells"; + excel.Save(); + excel.Close(); + } + + [Fact] + + public void TestColumnAndRowHeight() + { + ExcelSpreadsheetGXWrapper excel = Create("testColumnAndRowHeight"); + excel.GetCells(1, 1, 5, 5).Text = "texto de las celdas largo"; + excel.SetRowHeight(2, 50); + excel.SetColumnWidth(1, 100); + excel.Save(); + excel.Close(); + } + + [Fact] + + public void TestAlignment() + { + ExcelSpreadsheetGXWrapper excel = Create("testAlignment"); + excel.GetCells(2, 2, 3, 3).Text = "a"; + ExcelStyle style = new ExcelStyle(); + style. CellAlignment. HorizontalAlignment = ExcelAlignment.HORIZONTAL_ALIGN_RIGHT; //center + style. CellAlignment. VerticalAlignment = ExcelAlignment.VERTICAL_ALIGN_MIDDLE; //middle + excel.GetCells(2, 2, 3, 3).SetCellStyle(style); + excel.Save(); + excel.Close(); + + } + + + [Fact] + + public void TestExcelCellStyle() + { + ExcelSpreadsheetGXWrapper excel = Create("testExcelCellStyle"); + + IExcelCellRange cells = excel.GetCells(1, 1, 2, 2); + + ExcelStyle style = new ExcelStyle(); + + cells.Text="texto muy largo"; + style. CellAlignment. HorizontalAlignment = 3; + style. CellFont. Bold = true; + style. CellFont. Italic = true; + style. CellFont. Size = 18; + style. CellFont. Color.SetColorRGB(1, 1, 1); + style. CellFill. CellBackColor.SetColorRGB(210, 180, 140); + style. TextRotation = 5; + + style. + WrapText = true; + cells.SetCellStyle(style); + excel.SetColumnWidth(1, 70); + excel.SetRowHeight(1, 45); + excel.SetRowHeight(2, 45); + + cells = excel.GetCells(5, 2, 4, 4); + + cells.Text = "texto2"; + style = new ExcelStyle(); + style. Indentation = 5; + style. CellFont. Size = 10; + style. CellFont. Color.SetColorRGB(255, 255, 255); + style. CellFill. CellBackColor.SetColorRGB(90, 90, 90); + + cells.SetCellStyle(style); + + + cells = excel.GetCells(10, 2, 2, 2); + cells.Text = "texto3"; + style = new ExcelStyle(); + style. CellFont. Bold = false; + style. CellFont. Size = 10; + style. CellFont. Color.SetColorRGB(180, 180, 180); + style. CellFill. CellBackColor.SetColorRGB(45, 45, 45); + style. TextRotation = -90; + cells.SetCellStyle(style); + + + excel.Save(); + excel.Close(); + + } + + + [Fact] + + public void TestExcelBorderStyle() + { + ExcelSpreadsheetGXWrapper excel = Create("testExcelBorderStyle"); + IExcelCellRange cells = excel.GetCells(5, 2, 4, 4); + cells.Text = "texto2"; + + ExcelStyle style = new ExcelStyle(); + style. CellFont. Size = 10; + + style. + Border. + BorderTop. + Border = "THICK"; + style. Border. BorderTop. BorderColor.SetColorRGB(220, 20, 60); + + style. + Border. + BorderDiagonalUp. + Border = "THIN"; + style. Border. BorderDiagonalUp. BorderColor.SetColorRGB(220, 20, 60); + + style. + Border. + BorderDiagonalDown. + Border = "THIN"; + style. Border. BorderDiagonalDown. BorderColor.SetColorRGB(220, 20, 60); + + cells.SetCellStyle(style); + + cells = excel.GetCells(10, 2, 2, 2); + cells.Text = "texto3"; + style = new ExcelStyle(); + + style. + CellFont. + Bold = false; + style. CellFont. Size = 10; + style. CellFont. Color.SetColorRGB(180, 180, 180); + + cells.SetCellStyle(style); + + + excel.Save(); + excel.Close(); + + } + + [Fact] + + public void TestNumberFormat() + { + ExcelSpreadsheetGXWrapper excel = Create("testNumberFormat"); + ExcelStyle style = new ExcelStyle(); + style. DataFormat = "#.##"; + style. CellFont. Bold = true; + excel.GetCell(1, 1).NumericValue=1.123456789M; + excel.GetCell(1, 1).SetCellStyle(style); + excel.GetCell(2, 1).NumericValue=20000.123456789M; + + excel.Save(); + excel.Close(); + } + + [Fact] + + public void TestInsertRow() + { + ExcelSpreadsheetGXWrapper excel = Create("testInsertRow"); + + excel.GetCell(1, 1).NumericValue=1; + excel.GetCell(2, 1).NumericValue=2; + excel.GetCell(3, 1).NumericValue=3; + excel.GetCell(4, 1).NumericValue=4; + excel.GetCell(5, 1).NumericValue=5; + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testInsertRow"); + + Assert.Equal(2, excel.GetCell(2, 1).NumericValue); + excel.InsertRow(2, 2); + Assert.Equal(2, excel.GetCell(4, 1).NumericValue); + excel.Save(); + } + + + [Fact] + + public void TestDeleteRow() + { + ExcelSpreadsheetGXWrapper excel = Create("testDeleteRow"); + + excel.GetCells(1, 1, 1, 5).NumericValue=1; + excel.GetCells(2, 1, 1, 5).NumericValue=2; + excel.GetCells(3, 1, 1, 5).NumericValue = 3; + excel.GetCells(4, 1, 1, 5).NumericValue = 4; + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testDeleteRow"); + + Assert.Equal(1, excel.GetCell(1, 1).NumericValue); + Assert.Equal(2, excel.GetCell(2, 1).NumericValue); + excel.DeleteRow(2); + excel.Save(); + excel = Open("testDeleteRow"); + Assert.Equal(3, excel.GetCell(2, 1).NumericValue); + excel.Save(); + } + + [Fact] + + public void TestDeleteRow2() + { + ExcelSpreadsheetGXWrapper excel = Create("testDeleteRow2"); + + excel.GetCell(2, 2).Text="hola"; + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testDeleteRow2"); + Assert.Equal("hola", excel.GetCell(2, 2).Text); + bool result = excel.DeleteRow(1); + Assert.True(result); + excel.Save(); + excel.Close(); + excel = Open("testDeleteRow2"); + Assert.Equal("hola", excel.GetCell(1, 2).Text); + excel.Save(); + } + + + [Fact] + + public void TestHideRow() + { + ExcelSpreadsheetGXWrapper excel = Create("testHideRow"); + + excel.GetCell(1, 1).NumericValue = 1; + + excel.GetCell(2, 1).NumericValue = 2; + + excel.GetCell(3, 1).NumericValue = 3; + + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testHideRow"); + + Assert.Equal(1, excel.GetCell(1, 1).NumericValue); + excel.ToggleRow(2, false); + //Assert.Equal(7, excel.GetCell(1, 1).GetNumericValue()); + excel.Save(); + } + + [Fact] + public void TestHideRow2() + { + ExcelSpreadsheetGXWrapper excel = Create("testHideRow2"); + excel.ToggleRow(2, false); + excel.GetCell(1, 1).NumericValue=1; + excel.GetCell(2, 1).NumericValue = 2; + excel.GetCell(3, 1).NumericValue = 3; + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testHideRow2"); + + Assert.Equal(1, excel.GetCell(1, 1).NumericValue); + excel.Save(); + } + + [Fact] + public void TestHideRow3() + { + ExcelSpreadsheetGXWrapper excel = Create("testHideRow3"); + excel.ToggleRow(2, false); + excel.DeleteRow(5); + excel.ToggleRow(7, true); + excel.DeleteRow(8); + excel.GetCell(1, 1).NumericValue = 1; + excel.GetCell(2, 1).NumericValue = 2; + excel.GetCell(3, 1).NumericValue = 3; + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testHideRow3"); + + Assert.Equal(1, excel.GetCell(1, 1).NumericValue); + excel.Save(); + } + + [Fact] + public void TestMixed() + { + ExcelSpreadsheetGXWrapper excel = Open("testMixed"); + + excel.InsertRow(1, 5); + excel.DeleteRow(2); + + excel.InsertSheet("Inserted Sheet"); + excel.ToggleRow(7, false); + excel.ToggleColumn(2, false); + + excel.Save(); + } + + [Fact] + + public void TestHideColumn() + { + ExcelSpreadsheetGXWrapper excel = Create("testHideColumn"); + + excel.GetCell(1, 1).NumericValue = 1; + excel.GetCell(2, 1).NumericValue = 1; + excel.GetCell(3, 1).NumericValue = 1; + + excel.GetCell(1, 2).NumericValue = 2; + excel.GetCell(2, 2).NumericValue = 2; + excel.GetCell(3, 2).NumericValue = 2; + + excel.GetCell(1, 3).NumericValue = 3; + excel.GetCell(2, 3).NumericValue = 3; + excel.GetCell(3, 3).NumericValue = 3; + + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testHideColumn"); + + Assert.Equal(1, excel.GetCell(2, 1).NumericValue); + excel.ToggleColumn(2, false); + //Assert.Equal(7, excel.GetCell(1, 1).GetNumericValue()); + excel.Save(); + } + + [Fact] + + public void TestDeleteColumn() + { + ExcelSpreadsheetGXWrapper excel = Create("testDeleteColumn"); + + excel.GetCell(1, 1).NumericValue = 1; + excel.GetCell(2, 1).NumericValue = 1; + excel.GetCell(3, 1).NumericValue = 1; + + excel.GetCell(1, 2).NumericValue = 2; + excel.GetCell(2, 2).NumericValue = 2; + excel.GetCell(3, 2).NumericValue = 2; + + excel.GetCell(1, 3).NumericValue = 3; + excel.GetCell(2, 3).NumericValue = 3; + excel.GetCell(3, 3).NumericValue = 3; + + excel.Save(); + excel.Close(); + // Verify previous Excel Document + excel = Open("testDeleteColumn"); + + Assert.Equal(2, excel.GetCell(2, 2).NumericValue); + Assert.True(excel.DeleteColumn(2)); + Assert.Equal(3, excel.GetCell(2, 2).NumericValue); + excel.Save(); + } + + [Fact] + + public void TestDeleteColumn2() + { + ExcelSpreadsheetGXWrapper excel = Create("testDeleteColumn2"); + excel.DeleteColumn(2); + excel.Save(); + } + + + [Fact] + public void TestDeleteColumn3() + { + ExcelSpreadsheetGXWrapper excel = Create("testDeleteColumn3"); + excel.GetCells(1, 1, 5, 5).Text="cell"; + excel.InsertRow(3, 5); + excel.DeleteRow(3); + excel.DeleteColumn(2); + excel.Save(); + } + + [Fact] + + public void TestSaveAs() + { + ExcelSpreadsheetGXWrapper excel = Create("testSaveAs"); + excel.GetCells(1, 1, 15, 15).NumericValue=100; + string excelNew = Path.Combine(basePath, "testSaveAsCopy.xlsx"); + excel.SaveAs(excelNew); + excel.Close(); + Assert.True(new FileInfo(excelNew).Exists); + + } + + [Fact] + public void TestAutoFit() + { + ExcelSpreadsheetGXWrapper excel = Create("testAutoFit"); + excel.Autofit=true; + excel.GetCells(1, 2, 1, 1).Text = "LONGTEXTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"; + excel.GetCells(1, 3, 1, 1).Text = "VERYLONGTEXTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"; + excel.GetCells(2, 4, 1, 1).Text = "hola!"; + excel.GetCells(6, 6, 1, 1).Text = "VERYLONGTEXTINDIFFERENTROWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"; + ExcelCells cells = excel.GetCells(7, 7, 1, 1); + ExcelStyle style = new ExcelStyle(); + style. DataFormat = "#.##"; //change style, so it shows the full number not scientific notation + cells.NumericValue=123456789123456789123456789M; + cells.SetCellStyle(style); + excel.Save(); + excel.Close(); + } + [Fact] + public void TestDateFormat() + { + ExcelSpreadsheetGXWrapper excel = Create("testDateFormat"); + excel.Autofit = true; + DateTime date = new DateTime(); + //sets date with default format + ExcelCells cells = excel.GetCells(1, 1, 1, 1); + cells.DateValue=date; + //sets date and apply format after + cells = excel.GetCells(2, 1, 1, 1); + ExcelStyle style = new ExcelStyle(); + cells.DateValue=date; + style. DataFormat = "YYYY/MM/DD hh:mm:ss"; + cells.SetCellStyle(style); + //sets date and apply format before + cells = excel.GetCells(3, 1, 1, 1); + style = new ExcelStyle(); + style. DataFormat = "YYYY/MM/DD hh:mm:ss"; + cells.SetCellStyle(style); + cells.DateValue = date; + + date = DateTimeUtil.ResetTime(date); + //sets date with default format without hours + cells = excel.GetCells(4, 1, 1, 1); + cells.DateValue = date; + //sets date and apply format after + cells = excel.GetCells(5, 1, 1, 1); + style = new ExcelStyle(); + cells.DateValue = date; + style. DataFormat = "YYYY/MM/DD hh:mm:ss"; + cells.SetCellStyle(style); + //sets date and apply format before + cells = excel.GetCells(6, 1, 1, 1); + style = new ExcelStyle(); + style. DataFormat = "YYYY/MM/DD hh:mm:ss"; + cells.SetCellStyle(style); + cells.DateValue = date; + + excel.Save(); + excel.Close(); + } + [Fact] + public void TestTemplate() + { + string excelPath = Path.Combine(basePath, "testTemplate.xlsx"); + string excelTemplatePath = Path.Combine(basePath, "template.xlsx"); + EnsureFileDoesNotExists(excelPath); + EnsureFileDoesNotExists(excelTemplatePath); + FileInfo theDir = new FileInfo(basePath); + if (!theDir.Exists) + { + Directory.CreateDirectory(basePath); + } + ExcelSpreadsheetGXWrapper excel = new ExcelSpreadsheetGXWrapper(); + excel.Open(excelPath, excelTemplatePath); + Assert.Equal(4, excel.ErrCode);//Template not found + excel.Close(); + } + + private void LogErrorCodes(ExcelSpreadsheetGXWrapper excel) + { + // System.out.println(String.format("%s - %s", excel.GetErrCode(), excel.GetErrDescription())); + } + + private void EnsureFileDoesNotExists(string path) + { + try + { + FileInfo file = new FileInfo(path); + if (file.Exists) + { + file.Delete(); + } + } + catch (Exception) + { + + } + } + } +} + diff --git a/dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj b/dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj index 1a1b2e252..d8d055b01 100644 --- a/dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj +++ b/dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj @@ -38,6 +38,7 @@ +