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 @@
+