diff --git a/CM.Data.EpplusFixCalcsEdition/CM.Data.EpplusFreeFixCalcsEdition.vbproj b/CM.Data.EpplusFixCalcsEdition/CM.Data.EpplusFreeFixCalcsEdition.vbproj index d8f1a0e..ad5213c 100644 --- a/CM.Data.EpplusFixCalcsEdition/CM.Data.EpplusFreeFixCalcsEdition.vbproj +++ b/CM.Data.EpplusFixCalcsEdition/CM.Data.EpplusFreeFixCalcsEdition.vbproj @@ -2,7 +2,7 @@ - net48;net6.0 + net48;netstandard2.0;net6.0;net8.0 2005-2026 CompuMaster GmbH CompuMaster.Data.EpplusFreeFixCalcsEdition logo_64x64.png diff --git a/CM.Data.EpplusFixCalcsEdition/README.md b/CM.Data.EpplusFixCalcsEdition/README.md index 9c77dd5..256bfa8 100644 --- a/CM.Data.EpplusFixCalcsEdition/README.md +++ b/CM.Data.EpplusFixCalcsEdition/README.md @@ -2,7 +2,7 @@ A library to write and read System.Data.DataTable or System.Data.DataSet -Use Epplus 4.5 with LGPL license for solutions targetting .NET Framework 4.8 or .NET 6 or higher +Use EPPlus 4.5 with LGPL license for solutions targeting .NET Framework 4.8, .NET Standard 2.0, .NET 6, or .NET 8 and higher. ## Quick & dirty engine comparison / why you shouldn't use MS Excel for all situations diff --git a/CM.Data.EpplusFixCalcsEdition/XlsEpplusFixCalcsEdition.vb b/CM.Data.EpplusFixCalcsEdition/XlsEpplusFixCalcsEdition.vb index d7090e3..40e10d6 100644 --- a/CM.Data.EpplusFixCalcsEdition/XlsEpplusFixCalcsEdition.vb +++ b/CM.Data.EpplusFixCalcsEdition/XlsEpplusFixCalcsEdition.vb @@ -26,7 +26,31 @@ Namespace CompuMaster.Data ''' [adminwezel] 30.05.2005 Created ''' ''' ----------------------------------------------------------------------------- - Public Class XlsEpplusFixCalcsEdition + Public NotInheritable Class XlsEpplusFixCalcsEdition + + Private Sub New() + End Sub + + Private Enum VariantType + Empty + [Object] + [Error] + [Boolean] + [Byte] + [Short] + [Integer] + [Long] + [Single] + [Double] + [Decimal] + [Currency] + [Date] + [String] + [Char] + End Enum + + Private Shared ReadOnly CarriageReturn As String = Char.ConvertFromUtf32(13) + Private Shared ReadOnly LineFeed As String = Char.ConvertFromUtf32(10) Private Shared _ErrorLevel As Byte = 0 ''' ----------------------------------------------------------------------------- @@ -341,14 +365,14 @@ Namespace CompuMaster.Data For RowCounter As Integer = 0 To dataTable.Rows.Count - 1 For ColCounter As Integer = 0 To dataTable.Columns.Count - 1 Dim value As Object = dataTable.Rows(RowCounter)(ColCounter) - If IsDBNull(value) Then + If Convert.IsDBNull(value) Then WorkSheet.Cells(RowCounter + 1 + 1, ColCounter + 1).Value = Nothing ElseIf value.GetType Is GetType(String) Then 'Excel requires line-breaks to be an LF character only, not a windows typical CR+LF Dim cell As CompuMaster.Epplus4.ExcelRange = WorkSheet.Cells(RowCounter + 1 + 1, ColCounter + 1) If CType(value, String) <> "" Then - value = Replace(CType(value, String), ControlChars.CrLf, ControlChars.Lf) 'Windows line breaks - value = Replace(CType(value, String), ControlChars.Cr, ControlChars.Lf) 'Mac or Linux line break + value = CType(value, String).Replace(CarriageReturn & LineFeed, LineFeed) 'Windows line breaks + value = CType(value, String).Replace(CarriageReturn, LineFeed) 'Mac or Linux line break End If cell.Formula = "" cell.Value = value @@ -442,7 +466,6 @@ Namespace CompuMaster.Data Excel2007Macro = 2 End Enum -#Disable Warning CA1822 ' Mark members as static ''' ''' Updates or creates an Excel file, writes data into it, and saves the file to the output stream. ''' @@ -451,8 +474,7 @@ Namespace CompuMaster.Data ''' Some datatables to write into the workbook ''' The name the sheets which shall be updated/added in the order as defined by parameter dataTables ''' - Public Sub WriteDataTableToXlsStream(ByVal inputPath As String, ByVal outputStream As System.IO.Stream, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal fileFormat As FileFormat) -#Enable Warning CA1822 ' Mark members as static + Public Shared Sub WriteDataTableToXlsStream(ByVal inputPath As String, ByVal outputStream As System.IO.Stream, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal fileFormat As FileFormat) Dim exportWorkbook As CompuMaster.Epplus4.ExcelPackage exportWorkbook = OpenAndWriteDataTableToXlsFile(inputPath, dataTables, sheetNames, SpecialSheet.AsDefinedInSheetNamesCollection) If exportWorkbook Is Nothing Then @@ -468,39 +490,71 @@ Namespace CompuMaster.Data End If End Sub - '''' - '''' Directly send the new workbook file to the browser - '''' - '''' An optional path to a template - '''' Some datatables to write into the workbook - '''' The name the sheets which shall be updated/added in the order as defined by parameter dataTables - '''' The current HTTP context - '''' - 'Public Sub WriteDataTableToXlsHttpResponse(ByVal inputPath As String, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal httpContext As System.Web.HttpContext, ByVal fileFormat As FileFormat) - ' If dataTables Is Nothing Then - ' Throw New ArgumentNullException("dataTables") - ' End If - - ' Dim exportWorkbook As EpplusFreeOfficeOpenXml.ExcelPackage - ' exportWorkbook = OpenAndWriteDataTableToXlsFile(inputPath, dataTables, sheetNames, SpecialSheet.AsDefinedInSheetNamesCollection) - ' If exportWorkbook Is Nothing Then - ' Throw New Exception("Workbook creation failed - missing workbook") - ' End If - - ' ' compatible with Excel 97/2000/XP/2003/2007. - ' httpContext.Response.Clear() - ' httpContext.Response.ContentType = "application/vnd.ms-excel" - ' httpContext.Response.AddHeader("Content-Disposition", "attachment; filename=report.xls") - ' If fileFormat = FileFormat.Excel2007 Then - ' 'Excel 2007 format - ' exportWorkbook.SaveAs(httpContext.Response.OutputStream) - ' ElseIf fileFormat = FileFormat.Excel2007Macro Then - ' 'Excel 2007 format - ' exportWorkbook.SaveAs(httpContext.Response.OutputStream) - ' Else - ' Throw New NotSupportedException("value for fileformat is invalid") - ' End If - 'End Sub + ''' + ''' Writes a data table to an HTTP response. + ''' + ''' The data table to write. + ''' The worksheet name. + ''' The HTTP listener context receiving the response. + ''' The workbook file format. + ''' The file name suggested to the browser. + Public Shared Sub WriteDataTableToXlsHttpResponse(ByVal dataTable As System.Data.DataTable, ByVal sheetName As String, ByVal httpContext As System.Net.HttpListenerContext, ByVal fileFormat As FileFormat, ByVal suggestedFileNameToBrowser As String) + WriteDataTableToXlsHttpResponse(String.Empty, New DataTable() {dataTable}, New String() {sheetName}, httpContext, fileFormat, suggestedFileNameToBrowser) + End Sub + + ''' + ''' Updates or creates a workbook and writes it to an HTTP response. + ''' + ''' An optional path to a template. + ''' The data tables to write. + ''' The worksheet names corresponding to . + ''' The HTTP listener context receiving the response. + ''' The workbook file format. + Public Shared Sub WriteDataTableToXlsHttpResponse(ByVal inputPath As String, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal httpContext As System.Net.HttpListenerContext, ByVal fileFormat As FileFormat) + WriteDataTableToXlsHttpResponse(inputPath, dataTables, sheetNames, httpContext, fileFormat, String.Empty) + End Sub + + ''' + ''' Updates or creates a workbook and writes it to an HTTP response. + ''' + ''' An optional path to a template. + ''' The data tables to write. + ''' The worksheet names corresponding to . + ''' The HTTP listener context receiving the response. + ''' The workbook file format. + ''' The file name suggested to the browser. The default is report.xlsx or report.xlsm. + ''' or is . + ''' The workbook could not be created. + ''' is not supported. + Public Shared Sub WriteDataTableToXlsHttpResponse(ByVal inputPath As String, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal httpContext As System.Net.HttpListenerContext, ByVal fileFormat As FileFormat, ByVal suggestedFileNameToBrowser As String) + If dataTables Is Nothing Then + Throw New ArgumentNullException(NameOf(dataTables)) + End If + If httpContext Is Nothing Then + Throw New ArgumentNullException(NameOf(httpContext)) + End If + + Dim exportWorkbook = OpenAndWriteDataTableToXlsFile(inputPath, dataTables, sheetNames, SpecialSheet.AsDefinedInSheetNamesCollection) + If exportWorkbook Is Nothing Then + Throw New InvalidOperationException("Workbook creation failed - missing workbook") + End If + + httpContext.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + If String.IsNullOrEmpty(suggestedFileNameToBrowser) Then + If fileFormat = FileFormat.Excel2007Macro Then + suggestedFileNameToBrowser = "report.xlsm" + Else + suggestedFileNameToBrowser = "report.xlsx" + End If + End If + httpContext.Response.AddHeader("Content-Disposition", "attachment; filename=" & System.Net.WebUtility.UrlEncode(suggestedFileNameToBrowser)) + + If fileFormat = FileFormat.Excel2007 OrElse fileFormat = FileFormat.Excel2007Macro Then + exportWorkbook.SaveAs(httpContext.Response.OutputStream) + Else + Throw New NotSupportedException("value for fileformat is invalid") + End If + End Sub ''' ----------------------------------------------------------------------------- ''' @@ -661,7 +715,7 @@ Namespace CompuMaster.Data 'Save the changed worksheet importWorkbook = LoadWorkbookFile(inputPath) - Dim Sheet As CompuMaster.Epplus4.ExcelWorksheet = importWorkbook.Workbook.Worksheets(1) + Dim Sheet As CompuMaster.Epplus4.ExcelWorksheet = importWorkbook.Workbook.Worksheets(0) 'Detect the column types which must be used Dim Result As DataTable = ReadDataTableFromXlsFileCreateDataTableSuggestion(Sheet, Sheet.Name, startReadingAtRowIndex, firstRowContainsColumnNames) @@ -1060,8 +1114,8 @@ Namespace CompuMaster.Data Case VariantType.String Dim cellValue As String cellValue = CType(sheet.Cells(rowCounter + 1, colCounter + 1).Value, String) - If cellValue <> "" AndAlso System.Environment.NewLine <> ControlChars.Lf Then - cellValue = Replace(cellValue, ControlChars.Lf, System.Environment.NewLine, , , CompareMethod.Binary) + If cellValue <> "" AndAlso System.Environment.NewLine <> LineFeed Then + cellValue = cellValue.Replace(LineFeed, System.Environment.NewLine) End If value = cellValue Case VariantType.Date diff --git a/CM.Data.EpplusPolyformEdition/XlsEpplusPolyformEdition.vb b/CM.Data.EpplusPolyformEdition/XlsEpplusPolyformEdition.vb index c015755..bc28744 100644 --- a/CM.Data.EpplusPolyformEdition/XlsEpplusPolyformEdition.vb +++ b/CM.Data.EpplusPolyformEdition/XlsEpplusPolyformEdition.vb @@ -26,7 +26,31 @@ Namespace CompuMaster.Data ''' [adminwezel] 30.05.2005 Created ''' ''' ----------------------------------------------------------------------------- - Public Class XlsEpplusPolyformEdition + Public NotInheritable Class XlsEpplusPolyformEdition + + Private Sub New() + End Sub + + Private Enum VariantType + Empty + [Object] + [Error] + [Boolean] + [Byte] + [Short] + [Integer] + [Long] + [Single] + [Double] + [Decimal] + [Currency] + [Date] + [String] + [Char] + End Enum + + Private Shared ReadOnly CarriageReturn As String = Char.ConvertFromUtf32(13) + Private Shared ReadOnly LineFeed As String = Char.ConvertFromUtf32(10) Private Shared _ErrorLevel As Byte = 0 ''' ----------------------------------------------------------------------------- @@ -341,14 +365,14 @@ Namespace CompuMaster.Data For RowCounter As Integer = 0 To dataTable.Rows.Count - 1 For ColCounter As Integer = 0 To dataTable.Columns.Count - 1 Dim value As Object = dataTable.Rows(RowCounter)(ColCounter) - If IsDBNull(value) Then + If Convert.IsDBNull(value) Then WorkSheet.Cells(RowCounter + 1 + 1, ColCounter + 1).Value = Nothing ElseIf value.GetType Is GetType(String) Then 'Excel requires line-breaks to be an LF character only, not a windows typical CR+LF Dim cell As OfficeOpenXml.ExcelRange = WorkSheet.Cells(RowCounter + 1 + 1, ColCounter + 1) If CType(value, String) <> "" Then - value = Replace(CType(value, String), ControlChars.CrLf, ControlChars.Lf) 'Windows line breaks - value = Replace(CType(value, String), ControlChars.Cr, ControlChars.Lf) 'Mac or Linux line break + value = CType(value, String).Replace(CarriageReturn & LineFeed, LineFeed) 'Windows line breaks + value = CType(value, String).Replace(CarriageReturn, LineFeed) 'Mac or Linux line break End If cell.Formula = "" cell.Value = value @@ -442,7 +466,6 @@ Namespace CompuMaster.Data Excel2007Macro = 2 End Enum -#Disable Warning CA1822 ' Mark members as static ''' ''' Updates or creates an Excel file, writes data into it, and saves the file to the output stream. ''' @@ -451,8 +474,7 @@ Namespace CompuMaster.Data ''' Some datatables to write into the workbook ''' The name the sheets which shall be updated/added in the order as defined by parameter dataTables ''' - Public Sub WriteDataTableToXlsStream(ByVal inputPath As String, ByVal outputStream As System.IO.Stream, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal fileFormat As FileFormat) -#Enable Warning CA1822 ' Mark members as static + Public Shared Sub WriteDataTableToXlsStream(ByVal inputPath As String, ByVal outputStream As System.IO.Stream, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal fileFormat As FileFormat) Dim exportWorkbook As OfficeOpenXml.ExcelPackage exportWorkbook = OpenAndWriteDataTableToXlsFile(inputPath, dataTables, sheetNames, SpecialSheet.AsDefinedInSheetNamesCollection) If exportWorkbook Is Nothing Then @@ -468,39 +490,71 @@ Namespace CompuMaster.Data End If End Sub - '''' - '''' Directly send the new workbook file to the browser - '''' - '''' An optional path to a template - '''' Some datatables to write into the workbook - '''' The name the sheets which shall be updated/added in the order as defined by parameter dataTables - '''' The current HTTP context - '''' - 'Public Sub WriteDataTableToXlsHttpResponse(ByVal inputPath As String, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal httpContext As System.Web.HttpContext, ByVal fileFormat As FileFormat) - ' If dataTables Is Nothing Then - ' Throw New ArgumentNullException("dataTables") - ' End If - - ' Dim exportWorkbook As EpplusFreeOfficeOpenXml.ExcelPackage - ' exportWorkbook = OpenAndWriteDataTableToXlsFile(inputPath, dataTables, sheetNames, SpecialSheet.AsDefinedInSheetNamesCollection) - ' If exportWorkbook Is Nothing Then - ' Throw New Exception("Workbook creation failed - missing workbook") - ' End If - - ' ' compatible with Excel 97/2000/XP/2003/2007. - ' httpContext.Response.Clear() - ' httpContext.Response.ContentType = "application/vnd.ms-excel" - ' httpContext.Response.AddHeader("Content-Disposition", "attachment; filename=report.xls") - ' If fileFormat = FileFormat.Excel2007 Then - ' 'Excel 2007 format - ' exportWorkbook.SaveAs(httpContext.Response.OutputStream) - ' ElseIf fileFormat = FileFormat.Excel2007Macro Then - ' 'Excel 2007 format - ' exportWorkbook.SaveAs(httpContext.Response.OutputStream) - ' Else - ' Throw New NotSupportedException("value for fileformat is invalid") - ' End If - 'End Sub + ''' + ''' Writes a data table to an HTTP response. + ''' + ''' The data table to write. + ''' The worksheet name. + ''' The HTTP listener context receiving the response. + ''' The workbook file format. + ''' The file name suggested to the browser. + Public Shared Sub WriteDataTableToXlsHttpResponse(ByVal dataTable As System.Data.DataTable, ByVal sheetName As String, ByVal httpContext As System.Net.HttpListenerContext, ByVal fileFormat As FileFormat, ByVal suggestedFileNameToBrowser As String) + WriteDataTableToXlsHttpResponse(String.Empty, New DataTable() {dataTable}, New String() {sheetName}, httpContext, fileFormat, suggestedFileNameToBrowser) + End Sub + + ''' + ''' Updates or creates a workbook and writes it to an HTTP response. + ''' + ''' An optional path to a template. + ''' The data tables to write. + ''' The worksheet names corresponding to . + ''' The HTTP listener context receiving the response. + ''' The workbook file format. + Public Shared Sub WriteDataTableToXlsHttpResponse(ByVal inputPath As String, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal httpContext As System.Net.HttpListenerContext, ByVal fileFormat As FileFormat) + WriteDataTableToXlsHttpResponse(inputPath, dataTables, sheetNames, httpContext, fileFormat, String.Empty) + End Sub + + ''' + ''' Updates or creates a workbook and writes it to an HTTP response. + ''' + ''' An optional path to a template. + ''' The data tables to write. + ''' The worksheet names corresponding to . + ''' The HTTP listener context receiving the response. + ''' The workbook file format. + ''' The file name suggested to the browser. The default is report.xlsx or report.xlsm. + ''' or is . + ''' The workbook could not be created. + ''' is not supported. + Public Shared Sub WriteDataTableToXlsHttpResponse(ByVal inputPath As String, ByVal dataTables As System.Data.DataTable(), ByVal sheetNames As String(), ByVal httpContext As System.Net.HttpListenerContext, ByVal fileFormat As FileFormat, ByVal suggestedFileNameToBrowser As String) + If dataTables Is Nothing Then + Throw New ArgumentNullException(NameOf(dataTables)) + End If + If httpContext Is Nothing Then + Throw New ArgumentNullException(NameOf(httpContext)) + End If + + Dim exportWorkbook = OpenAndWriteDataTableToXlsFile(inputPath, dataTables, sheetNames, SpecialSheet.AsDefinedInSheetNamesCollection) + If exportWorkbook Is Nothing Then + Throw New InvalidOperationException("Workbook creation failed - missing workbook") + End If + + httpContext.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + If String.IsNullOrEmpty(suggestedFileNameToBrowser) Then + If fileFormat = FileFormat.Excel2007Macro Then + suggestedFileNameToBrowser = "report.xlsm" + Else + suggestedFileNameToBrowser = "report.xlsx" + End If + End If + httpContext.Response.AddHeader("Content-Disposition", "attachment; filename=" & System.Net.WebUtility.UrlEncode(suggestedFileNameToBrowser)) + + If fileFormat = FileFormat.Excel2007 OrElse fileFormat = FileFormat.Excel2007Macro Then + exportWorkbook.SaveAs(httpContext.Response.OutputStream) + Else + Throw New NotSupportedException("value for fileformat is invalid") + End If + End Sub ''' ----------------------------------------------------------------------------- ''' @@ -661,7 +715,7 @@ Namespace CompuMaster.Data 'Save the changed worksheet importWorkbook = LoadWorkbookFile(inputPath) - Dim Sheet As OfficeOpenXml.ExcelWorksheet = importWorkbook.Workbook.Worksheets(1) + Dim Sheet As OfficeOpenXml.ExcelWorksheet = importWorkbook.Workbook.Worksheets(0) 'Detect the column types which must be used Dim Result As DataTable = ReadDataTableFromXlsFileCreateDataTableSuggestion(Sheet, Sheet.Name, startReadingAtRowIndex, firstRowContainsColumnNames) @@ -1060,8 +1114,8 @@ Namespace CompuMaster.Data Case VariantType.String Dim cellValue As String cellValue = CType(sheet.Cells(rowCounter + 1, colCounter + 1).Value, String) - If cellValue <> "" AndAlso System.Environment.NewLine <> ControlChars.Lf Then - cellValue = Replace(cellValue, ControlChars.Lf, System.Environment.NewLine, , , CompareMethod.Binary) + If cellValue <> "" AndAlso System.Environment.NewLine <> LineFeed Then + cellValue = cellValue.Replace(LineFeed, System.Environment.NewLine) End If value = cellValue Case VariantType.Date diff --git a/Epplus-FixCalcsEdition/EPPlus/Compatibility/CompatibilitySettings.cs b/Epplus-FixCalcsEdition/EPPlus/Compatibility/CompatibilitySettings.cs index 1545c2a..2cb4eaa 100644 --- a/Epplus-FixCalcsEdition/EPPlus/Compatibility/CompatibilitySettings.cs +++ b/Epplus-FixCalcsEdition/EPPlus/Compatibility/CompatibilitySettings.cs @@ -47,35 +47,10 @@ internal CompatibilitySettings(ExcelPackage excelPackage) { this.excelPackage = excelPackage; } -#if Core /// - /// If the worksheets collection of the ExcelWorkbook class is 1 based. - /// This property can be set from appsettings.json file. - /// - /// { - /// "EPPlus": { - /// "ExcelPackage": { - /// "Compatibility": { - /// "IsWorksheets1Based": false //Default value is false - /// } - /// } - /// } - /// } - /// + /// Gets or sets whether the worksheets collection of the class is one-based. + /// The CompuMaster edition initializes this property to on every target framework. /// -#else - /// - /// If the worksheets collection of the ExcelWorkbook class is 1 based. - /// This property can be set from app.config file. - /// - /// - /// - /// - /// - /// - /// -#endif - public bool IsWorksheets1Based { get diff --git a/Epplus-FixCalcsEdition/EPPlus/EPPlus45-FixCalcsEdition.MultiTarget.csproj b/Epplus-FixCalcsEdition/EPPlus/EPPlus45-FixCalcsEdition.MultiTarget.csproj index 26b1b76..5ccda9b 100644 --- a/Epplus-FixCalcsEdition/EPPlus/EPPlus45-FixCalcsEdition.MultiTarget.csproj +++ b/Epplus-FixCalcsEdition/EPPlus/EPPlus45-FixCalcsEdition.MultiTarget.csproj @@ -1,7 +1,7 @@  - net48;net6.0 + net48;netstandard2.0;net6.0;net8.0 true https://github.com/CompuMasterGmbH/CompuMaster.Excel/ @@ -32,11 +32,11 @@ Core;STANDARD20 - + Core - + Core @@ -81,37 +81,7 @@ - - - - - 4.7.0 - - - - - - - - - - - - - - - 4.7.0 - - - - - - - - - - - + @@ -129,8 +99,13 @@ \ - - - + + + + + + + + diff --git a/Epplus-FixCalcsEdition/EPPlus/ExcelPackage.cs b/Epplus-FixCalcsEdition/EPPlus/ExcelPackage.cs index b34bc98..1c9b486 100644 --- a/Epplus-FixCalcsEdition/EPPlus/ExcelPackage.cs +++ b/Epplus-FixCalcsEdition/EPPlus/ExcelPackage.cs @@ -43,12 +43,8 @@ using CompuMaster.Epplus4.FormulaParsing; using CompuMaster.Epplus4.Encryption; using CompuMaster.Epplus4.Utils.CompundDocument; -using System.Configuration; using CompuMaster.Epplus4.Compatibility; using System.Text; -#if (Core) -using Microsoft.Extensions.Configuration; -#endif namespace CompuMaster.Epplus4 { /// @@ -528,23 +524,7 @@ private void Init() DoAdjustDrawings = true; #if (Core) Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); //Add Support for codepage 1252 - - var build = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", true,false); - var c = build.Build(); - - //var v = c["EPPlus:ExcelPackage:Compatibility:IsWorksheets1Based"]; -#else - //var v = ConfigurationManager.AppSettings["EPPlus:ExcelPackage.Compatibility.IsWorksheets1Based"]; #endif - //if (v != null) - //{ - // if(Boolean.TryParse(v.ToLowerInvariant(), out bool value)) - // { - // Compatibility.IsWorksheets1Based = value; - // } - //} Compatibility.IsWorksheets1Based = false; } /// diff --git a/Epplus-FixCalcsEdition/EPPlus/ExcelWorksheets.cs b/Epplus-FixCalcsEdition/EPPlus/ExcelWorksheets.cs index 5ba9c5a..6b49463 100644 --- a/Epplus-FixCalcsEdition/EPPlus/ExcelWorksheets.cs +++ b/Epplus-FixCalcsEdition/EPPlus/ExcelWorksheets.cs @@ -32,7 +32,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Security.Cryptography.Xml; using System.Text; using System.Xml; using System.IO; diff --git a/Epplus-FixCalcsEdition/EPPlus/Properties/AssemblyInfo.cs b/Epplus-FixCalcsEdition/EPPlus/Properties/AssemblyInfo.cs index 7739e3f..7777487 100644 --- a/Epplus-FixCalcsEdition/EPPlus/Properties/AssemblyInfo.cs +++ b/Epplus-FixCalcsEdition/EPPlus/Properties/AssemblyInfo.cs @@ -65,5 +65,7 @@ // [assembly: AssemblyVersion("4.6.2022.0110")] // //[assembly: AssemblyFileVersion("4.5.0.0")] //#endif +#if (!Core) [assembly: AllowPartiallyTrustedCallers] +#endif //[assembly: AssemblyTitle("EPPlus CompuMaster-Edition")] diff --git a/Epplus-FixCalcsEdition/EPPlus/README.md b/Epplus-FixCalcsEdition/EPPlus/README.md index 4003bd1..b4675d7 100644 --- a/Epplus-FixCalcsEdition/EPPlus/README.md +++ b/Epplus-FixCalcsEdition/EPPlus/README.md @@ -15,10 +15,8 @@ More information on the license change on [our website]( https://www.epplussoftw * Bug fixes and minor changes, see below and visit https://github.com/JanKallman/EPPlus for tutorials, samples and the latest information ## Important Notes: -Breaking change in .NET Core: The Worksheets collection will be zero based as default. -This can be altered by setting the ExcelPackage.Compatibility.IsWorksheets1Based to true. -.NET Core will have this property set to false, and .Net 3.5 and .Net 4 version will have this property set to true for backward compatibility reasons. -This property can also be set via the appsettings.json file in .Net Core or the app.config file. See sample project for examples! +The CompuMaster edition initializes the Worksheets collection as zero-based on every target framework. +This can be altered programmatically by setting ExcelPackage.Compatibility.IsWorksheets1Based to true after constructing the package. .NET Core uses a preview of System.Drawing.Common, so be aware of that. We will update it as Microsoft releases newer versions. System.Drawing.Common requires libgdiplus to be installed on non-Windows operating systems. diff --git a/Epplus-FixCalcsEdition/SampleApp.Core/appsettings.json b/Epplus-FixCalcsEdition/SampleApp.Core/appsettings.json deleted file mode 100644 index 6bf2b7e..0000000 --- a/Epplus-FixCalcsEdition/SampleApp.Core/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "EPPlus": { - "ExcelPackage": { - "Compatibility": { - "IsWorksheets1Based": false //Default value is false - } - } - } -} diff --git a/Epplus-FixCalcsEdition/SampleApp/app.config b/Epplus-FixCalcsEdition/SampleApp/app.config index 64d5096..e64236b 100644 --- a/Epplus-FixCalcsEdition/SampleApp/app.config +++ b/Epplus-FixCalcsEdition/SampleApp/app.config @@ -1,8 +1,4 @@  - - - - diff --git a/ExcelOpsTest/Data/CmDataXlsEpplusFixCalcsEditionContractTest.vb b/ExcelOpsTest/Data/CmDataXlsEpplusFixCalcsEditionContractTest.vb new file mode 100644 index 0000000..a8b1278 --- /dev/null +++ b/ExcelOpsTest/Data/CmDataXlsEpplusFixCalcsEditionContractTest.vb @@ -0,0 +1,111 @@ +Option Explicit On +Option Strict On + +Imports System.Data +Imports System.IO +Imports System.Linq +Imports System.Reflection +Imports NUnit.Framework + +Namespace Data + + Public Class CmDataXlsEpplusFixCalcsEditionContractTest + + ''' + ''' Verifies that the utility API cannot accidentally regain instance-only entry points. + ''' + + Public Sub PublicApiIsStaticOnly() + Dim apiType = GetType(CompuMaster.Data.XlsEpplusFixCalcsEdition) + Dim instanceMethods = apiType.GetMethods(BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly) + Dim httpMethods = apiType.GetMethods(BindingFlags.Public Or BindingFlags.Static Or BindingFlags.DeclaredOnly). + Where(Function(methodInfo) methodInfo.Name = NameOf(CompuMaster.Data.XlsEpplusFixCalcsEdition.WriteDataTableToXlsHttpResponse)). + ToArray() + + Assert.That(apiType.IsSealed, [Is].True) + Assert.That(apiType.GetConstructors(BindingFlags.Public Or BindingFlags.Instance), [Is].Empty) + Assert.That(instanceMethods, [Is].Empty) + Assert.That(httpMethods, Has.Length.EqualTo(3)) + Assert.That(FindHttpOverload(apiType, GetType(DataTable), GetType(String), GetType(System.Net.HttpListenerContext), GetType(CompuMaster.Data.XlsEpplusFixCalcsEdition.FileFormat), GetType(String)), [Is].Not.Null) + Assert.That(FindHttpOverload(apiType, GetType(String), GetType(DataTable()), GetType(String()), GetType(System.Net.HttpListenerContext), GetType(CompuMaster.Data.XlsEpplusFixCalcsEdition.FileFormat)), [Is].Not.Null) + Assert.That(FindHttpOverload(apiType, GetType(String), GetType(DataTable()), GetType(String()), GetType(System.Net.HttpListenerContext), GetType(CompuMaster.Data.XlsEpplusFixCalcsEdition.FileFormat), GetType(String)), [Is].Not.Null) + End Sub + + ''' + ''' Verifies that the shared stream API creates a readable workbook. + ''' + + Public Sub WriteDataTableToXlsStreamCreatesWorkbook() + Dim table = CreateSampleTable() + + Using output As New MemoryStream() + CompuMaster.Data.XlsEpplusFixCalcsEdition.WriteDataTableToXlsStream( + Nothing, + output, + New DataTable() {table}, + New String() {"StreamSheet"}, + CompuMaster.Data.XlsEpplusFixCalcsEdition.FileFormat.Excel2007) + + Assert.That(output.Length, [Is].GreaterThan(0)) + output.Position = 0 + + Using workbook As New CompuMaster.Epplus4.ExcelPackage(output) + Assert.That(workbook.Workbook.Worksheets.Count, [Is].EqualTo(1)) + Assert.That(workbook.Workbook.Worksheets(0).Name, [Is].EqualTo("StreamSheet")) + End Using + End Using + End Sub + + ''' + ''' Verifies that the first worksheet is addressed by its zero-based index. + ''' + + Public Sub ReadSingleWorksheetWithStartRowOverload() + Dim inputPath = TestEnvironment.FullPathOfExistingTestFile("test_data", "SampleTable01.xlsx") + + Dim result = CompuMaster.Data.XlsEpplusFixCalcsEdition.ReadDataTableFromXlsFile(inputPath, 0, False) + + Assert.That(result, [Is].Not.Null) + Assert.That(result.Rows.Count, [Is].GreaterThan(0)) + End Sub + + ''' + ''' Verifies that mismatched table and worksheet arrays are rejected before a file is written. + ''' + + Public Sub WriteDataTablesRejectsMismatchedWorksheetNames() + Dim outputPath = TestEnvironment.FullPathOfDynTestFile(GetType(CmDataXlsEpplusFixCalcsEditionContractTest), "test_data", "MismatchedArrays.xlsx") + Dim tables = New DataTable() {CreateSampleTable()} + + Dim exception = Assert.Throws(Of ArgumentException)( + Sub() + CompuMaster.Data.XlsEpplusFixCalcsEdition.WriteDataTableToXlsFile( + Nothing, + outputPath, + tables, + Array.Empty(Of String)()) + End Sub) + + Assert.That(exception.ParamName, [Is].EqualTo("sheetnames")) + End Sub + + Private Shared Function CreateSampleTable() As DataTable + Dim table As New DataTable("Data") + table.Columns.Add("Id", GetType(Integer)) + table.Columns.Add("Value", GetType(String)) + table.Rows.Add(1, "One") + Return table + End Function + + Private Shared Function FindHttpOverload(ByVal apiType As Type, ParamArray parameterTypes As Type()) As MethodInfo + Return apiType.GetMethod( + NameOf(CompuMaster.Data.XlsEpplusFixCalcsEdition.WriteDataTableToXlsHttpResponse), + BindingFlags.Public Or BindingFlags.Static, + Nothing, + parameterTypes, + Nothing) + End Function + + End Class + +End Namespace diff --git a/README.md b/README.md index ccf5ce2..3ae0ed2 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ A bunch of libraries to access and edit Excel files with common interface for se * **CompuMaster.Excel.MicrosoftExcel** * Use Microsoft.Office.Interop.Excel v15 (MS Office 2013) or higher, for solutions targetting .NET Framework 4.8 or .NET 6 or higher * **CompuMaster.Excel.EpplusFreeFixCalcsEdition** - * Use Epplus 4.5 with LGPL license for solutions targetting .NET Framework 4.8 or .NET 6 or higher + * Use EPPlus 4.5 with LGPL license for solutions targeting .NET Framework 4.8, .NET Standard 2.0, .NET 6, or .NET 8 and higher * **CompuMaster.Excel.EpplusPolyformEdition** * Use latest Epplus with Epplus Software's polyform license for solutions targetting .NET Framework 4.8 or .NET 6 or higher * **CompuMaster.Excel.FreeSpireXls** diff --git a/clone-build-files.ps1 b/clone-build-files.ps1 index fd5ff67..0292d3d 100644 --- a/clone-build-files.ps1 +++ b/clone-build-files.ps1 @@ -73,7 +73,7 @@ Write-SourceCodeTargetFileWithReadonlyFlag -TargetFile $TargetFile -SourceCode $ "TASK 4: INCLUDE LATEST LOGIC FROM XlsEpplusFixCalcsEdition edition into XlsEpplusPolyformEdition edition" # clone files XlsEpplusFixCalcsEdition => XlsEpplusPolyformEdition -$SourceCode = (gc -Raw CM.Data.EpplusFixCalcsEdition/XlsEpplusFixCalcsEdition.vb) -replace 'Public Class XlsEpplusFixCalcsEdition', 'Public Class XlsEpplusPolyformEdition' -replace 'CompuMaster.Epplus4', 'OfficeOpenXml' +$SourceCode = (gc -Raw CM.Data.EpplusFixCalcsEdition/XlsEpplusFixCalcsEdition.vb) -replace 'Public NotInheritable Class XlsEpplusFixCalcsEdition', 'Public NotInheritable Class XlsEpplusPolyformEdition' -replace 'CompuMaster.Epplus4', 'OfficeOpenXml' $TargetFile = 'CM.Data.EpplusPolyformEdition/XlsEpplusPolyformEdition.vb' Write-SourceCodeTargetFileWithReadonlyFlag -TargetFile $TargetFile -SourceCode $SourceCode -SetReadOnly