diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..f1f4e7b --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,74 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '38 20 * * 4' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'csharp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/01-GettingStarted/GettingStartedSample.cs b/01-GettingStarted/GettingStartedSample.cs index 98e9c7f..562a798 100644 --- a/01-GettingStarted/GettingStartedSample.cs +++ b/01-GettingStarted/GettingStartedSample.cs @@ -54,7 +54,7 @@ public static string Run() //Add a formula for the value-column worksheet.Cells["E2:E4"].Formula = "C2*D2"; - //Ok now format the values; + //Ok now format the values using (var range = worksheet.Cells[1, 1, 1, 5]) { range.Style.Font.Bold = true; @@ -110,7 +110,7 @@ public static string Run() package.Workbook.Properties.SetCustomPropertyValue("Checked by", "Jan Källman"); package.Workbook.Properties.SetCustomPropertyValue("AssemblyName", "EPPlus"); - var xlFile = FileOutputUtil.GetFileInfo("01-GettingStarted.xlsx"); + var xlFile = FileUtil.GetCleanFileInfo("01-GettingStarted.xlsx"); // Save our new workbook in the output directory and we are done! package.SaveAs(xlFile); diff --git a/02-ReadWorkbook/ReadWorkbookSample.cs b/02-ReadWorkbook/ReadWorkbookSample.cs index b85a9fe..c915a21 100644 --- a/02-ReadWorkbook/ReadWorkbookSample.cs +++ b/02-ReadWorkbook/ReadWorkbookSample.cs @@ -23,7 +23,7 @@ class ReadWorkbookSample { public static void Run() { - var filePath = FileInputUtil.GetFileInfo("02-ReadWorkbook", "ReadWorkbook.xlsx").FullName; + var filePath = FileUtil.GetFileInfo("02-ReadWorkbook", "ReadWorkbook.xlsx").FullName; Console.WriteLine("Reading column 2 of {0}", filePath); Console.WriteLine(); diff --git a/03-UsingAsyncAwait/UsingAsyncAwaitSample.cs b/03-UsingAsyncAwait/UsingAsyncAwaitSample.cs index 7210fd4..700ab64 100644 --- a/03-UsingAsyncAwait/UsingAsyncAwaitSample.cs +++ b/03-UsingAsyncAwait/UsingAsyncAwaitSample.cs @@ -30,7 +30,7 @@ class UsingAsyncAwaitSample /// The connection string to the SQLite database public static async Task RunAsync(string connectionString) { - var file = FileOutputUtil.GetFileInfo("03-AsyncAwait.xlsx"); + var file = FileUtil.GetCleanFileInfo("03-AsyncAwait.xlsx"); using (ExcelPackage package = new ExcelPackage(file)) { var ws = package.Workbook.Worksheets.Add("Sheet1"); @@ -54,10 +54,10 @@ public static async Task RunAsync(string connectionString) await package.LoadAsync(file); var newWs = package.Workbook.Worksheets.Add("AddedSheet2"); - var range = await newWs.Cells["A1"].LoadFromTextAsync(FileInputUtil.GetFileInfo("03-UsingAsyncAwait", "Importfile.txt"), new ExcelTextFormat { Delimiter='\t' }); + var range = await newWs.Cells["A1"].LoadFromTextAsync(FileUtil.GetFileInfo("03-UsingAsyncAwait", "Importfile.txt"), new ExcelTextFormat { Delimiter='\t' }); range.AutoFitColumns(); - await package.SaveAsAsync(FileOutputUtil.GetFileInfo("03-AsyncAwait-LoadedAndModified.xlsx")); + await package.SaveAsAsync(FileUtil.GetCleanFileInfo("03-AsyncAwait-LoadedAndModified.xlsx")); } } } diff --git a/04-LoadingData/LoadingDataFromCollectionWithAttributes.cs b/04-LoadingData/LoadingDataFromCollectionWithAttributes.cs index cffbc0b..3ba76f5 100644 --- a/04-LoadingData/LoadingDataFromCollectionWithAttributes.cs +++ b/04-LoadingData/LoadingDataFromCollectionWithAttributes.cs @@ -40,6 +40,36 @@ internal class Actor2 : Actor } + // classes used to demonstrate this functionality with a complex type property + [EpplusTable(TableStyle = TableStyles.Light14, PrintHeaders = true, AutofitColumns = true, AutoCalculate = true, ShowLastColumn = true)] + internal class Actor3 + { + [EpplusIgnore] + public int Id { get; set; } + + [EpplusNestedTableColumn(Order = 1)] + public ActorName Name { get; set; } + + [EpplusTableColumn(Order = 0, NumberFormat = "yyyy-MM-dd", TotalsRowLabel = "Total")] + public DateTime Birthdate { get; set; } + + [EpplusTableColumn(Order = 2, NumberFormat = "€#,##0.00", TotalsRowFunction = RowFunctions.Sum, TotalsRowNumberFormat = "€#,##0.00")] + public double Salary { get; set; } + + [EpplusTableColumn(Order = 3, NumberFormat = "0%", TotalsRowFormula = "Table1[[#Totals],[Tax amount]]/Table1[[#Totals],[Salary]]", TotalsRowNumberFormat = "0 %")] + public double Tax { get; set; } + } + + internal class ActorName + { + [EpplusTableColumn(Order = 3)] + public string LastName { get; set; } + [EpplusTableColumn(Order = 1, Header = "First name")] + public string FirstName { get; set; } + [EpplusTableColumn(Order = 2)] + public string MiddleName { get; set; } + } + public static class LoadingDataFromCollectionWithAttributes { public static void Run() @@ -59,7 +89,14 @@ public static void Run() new Actor2{ Salary = 315.34, Tax = 0.28, FirstName = "Lisa", MiddleName = "Maria", LastName = "Gonzales", Birthdate = new DateTime(1971, 10, 2)} }; - using (var package = new ExcelPackage(FileOutputUtil.GetFileInfo("04-LoadFromCollectionAttributes.xlsx"))) + var complexTypeActors = new List + { + new Actor3{ Salary = 256.24, Tax = 0.21, Name = new ActorName{ FirstName="John", MiddleName="Bernhard", LastName="Doe" }, Birthdate = new DateTime(1950, 3, 15) }, + new Actor3{ Salary = 278.55, Tax = 0.23, Name = new ActorName{ FirstName="Sven", MiddleName="Bertil", LastName="Svensson" }, Birthdate = new DateTime(1962, 6, 10)}, + new Actor3{ Salary = 315.34, Tax = 0.28, Name = new ActorName{ FirstName="Lisa", MiddleName="Maria", LastName="Gonzales" }, Birthdate = new DateTime(1971, 10, 2)} + }; + + using (var package = new ExcelPackage(FileUtil.GetCleanFileInfo("04-LoadFromCollectionAttributes.xlsx"))) { // using the Actor class above var sheet = package.Workbook.Worksheets.Add("Actors"); @@ -68,7 +105,11 @@ public static void Run() // using a subclass where we have overridden the EpplusTableAttribute (different TableStyle and highlight last column instead of the first). var subclassSheet = package.Workbook.Worksheets.Add("Using subclass with attributes"); subclassSheet.Cells["A1"].LoadFromCollection(subclassActors); - + + // using a subclass where we have overridden the EpplusTableAttribute (different TableStyle and highlight last column instead of the first). + var complexTypePropertySheet = package.Workbook.Worksheets.Add("Complex type property"); + complexTypePropertySheet.Cells["A1"].LoadFromCollection(complexTypeActors); + package.Save(); } } diff --git a/04-LoadingData/LoadingDataWithDynamicObjects.cs b/04-LoadingData/LoadingDataWithDynamicObjects.cs index 1fcd659..d4002a2 100644 --- a/04-LoadingData/LoadingDataWithDynamicObjects.cs +++ b/04-LoadingData/LoadingDataWithDynamicObjects.cs @@ -52,7 +52,7 @@ public static void Run() }; // Create a workbook with a worksheet and load the data into a table - using(var package = new ExcelPackage(FileOutputUtil.GetFileInfo("04-LoadDynamicObjects.xlsx"))) + using(var package = new ExcelPackage(FileUtil.GetCleanFileInfo("04-LoadDynamicObjects.xlsx"))) { var sheet = package.Workbook.Worksheets.Add("Dynamic"); sheet.Cells["A1"].LoadFromDictionaries(items, c => @@ -69,8 +69,8 @@ public static void Run() } // Load data from json (in this case a file) - var jsonItems = JsonConvert.DeserializeObject>(File.ReadAllText(FileInputUtil.GetFileInfo("04-LoadingData", "testdata.json").FullName)); - using (var package = new ExcelPackage(FileOutputUtil.GetFileInfo("04-LoadJsonFromFile.xlsx"))) + var jsonItems = JsonConvert.DeserializeObject>(File.ReadAllText(FileUtil.GetFileInfo("04-LoadingData", "testdata.json").FullName)); + using (var package = new ExcelPackage(FileUtil.GetCleanFileInfo("04-LoadJsonFromFile.xlsx"))) { var sheet = package.Workbook.Worksheets.Add("Dynamic"); sheet.Cells["A1"].LoadFromDictionaries(jsonItems, c => diff --git a/04-LoadingData/LoadingDataWithTablesSample.cs b/04-LoadingData/LoadingDataWithTablesSample.cs index 31fe516..3625468 100644 --- a/04-LoadingData/LoadingDataWithTablesSample.cs +++ b/04-LoadingData/LoadingDataWithTablesSample.cs @@ -33,7 +33,7 @@ public static void Run() var pck = new ExcelPackage(); //Create a datatable with the directories and files from the current directory... - DataTable dt = GetDataTable(FileOutputUtil.GetDirectoryInfo(".")); + DataTable dt = GetDataTable(FileUtil.GetDirectoryInfo(".")); var wsDt = pck.Workbook.Worksheets.Add("FromDataTable"); @@ -108,7 +108,7 @@ orderby file.Name ascending wsList.Cells[wsList.Dimension.Address].AutoFitColumns(); //...and save - var fi = FileOutputUtil.GetFileInfo("04-LoadingData.xlsx"); + var fi = FileUtil.GetCleanFileInfo("04-LoadingData.xlsx"); pck.SaveAs(fi); pck.Dispose(); } diff --git a/05-ImportAndExportCsvFiles/ImportAndExportCsvFilesSample.cs b/05-ImportAndExportCsvFiles/ImportAndExportCsvFilesSample.cs index c0567fb..b9f2a87 100644 --- a/05-ImportAndExportCsvFiles/ImportAndExportCsvFilesSample.cs +++ b/05-ImportAndExportCsvFiles/ImportAndExportCsvFilesSample.cs @@ -37,7 +37,7 @@ public static class ImportAndExportCsvFilesSample /// public static async Task Run() { - FileInfo newFile = FileOutputUtil.GetFileInfo(@"05-LoadDataFromCsvFilesIntoTables.xlsx"); + FileInfo newFile = FileUtil.GetCleanFileInfo(@"05-LoadDataFromCsvFilesIntoTables.xlsx"); using (ExcelPackage package = new ExcelPackage()) { @@ -60,7 +60,7 @@ private static async Task ExportTableAsync(ExcelPackage package) Encoding = new UTF8Encoding(), SkipLinesEnd=1 //Skip the totals row }; - await ws.Cells[tbl.Address.Address].SaveToTextAsync(FileOutputUtil.GetFileInfo("05-ExportedFromEPPlus.csv"), format); + await ws.Cells[tbl.Address.Address].SaveToTextAsync(FileUtil.GetCleanFileInfo("05-ExportedFromEPPlus.csv"), format); Console.WriteLine($"Writing the text file 'ExportedTable.csv'..."); } @@ -79,7 +79,7 @@ private static void LoadFile1(ExcelPackage package) SkipLinesEnd = 1 }; - var file1 = FileInputUtil.GetFileInfo("05-ImportAndExportCsvFiles", "Sample5-1.txt"); + var file1 = FileUtil.GetFileInfo("05-ImportAndExportCsvFiles", "Sample5-1.txt"); //Now read the file into the sheet. Start from cell A1. Create a table with style 27. First row contains the header. Console.WriteLine("Load the text file..."); @@ -150,7 +150,7 @@ private static async Task LoadFile2Async(ExcelPackage package) //Now read the file into the sheet. Console.WriteLine("Load the text file..."); - var file2 = FileInputUtil.GetFileInfo("05-ImportAndExportCsvFiles", "Sample5-2.txt"); + var file2 = FileUtil.GetFileInfo("05-ImportAndExportCsvFiles", "Sample5-2.txt"); var range = await sheet.Cells["A1"].LoadFromTextAsync(file2, format); diff --git a/06-FormulaCalculation/CalculateExistingWorkbook.cs b/06-FormulaCalculation/CalculateExistingWorkbook.cs index 3629410..0e0e853 100644 --- a/06-FormulaCalculation/CalculateExistingWorkbook.cs +++ b/06-FormulaCalculation/CalculateExistingWorkbook.cs @@ -52,7 +52,7 @@ private static void RemoveCalculatedFormulaValues(ExcelWorkbook workbook) public void Run() { //var resourceStream = GetResource("EPPlusSampleApp.Core.FormulaCalculation.FormulaCalcSample.xlsx"); - var filePath = FileInputUtil.GetFileInfo("06-FormulaCalculation", "FormulaCalcSample.xlsx").FullName; + var filePath = FileUtil.GetFileInfo("06-FormulaCalculation", "FormulaCalcSample.xlsx").FullName; using (var package = new ExcelPackage(new FileInfo(filePath))) { // Read the value from the workbook. This is calculated by Excel. diff --git a/07-OpenWorkbookAddDataAndChart/OpenWorkbookAndAddDataAndChart.cs b/07-OpenWorkbookAddDataAndChart/OpenWorkbookAndAddDataAndChart.cs index ee6af09..8d47887 100644 --- a/07-OpenWorkbookAddDataAndChart/OpenWorkbookAndAddDataAndChart.cs +++ b/07-OpenWorkbookAddDataAndChart/OpenWorkbookAndAddDataAndChart.cs @@ -29,8 +29,8 @@ public class OpenWorkbookAndAddDataAndChartSample /// public static string Run() { - FileInfo newFile = FileOutputUtil.GetFileInfo("07-OpenWorkbookAndAddDataAndChartSample.xlsx"); - FileInfo templateFile = FileInputUtil.GetFileInfo("07-OpenWorkbookAddDataAndChart", "ExistingWorkbook.xlsx"); + FileInfo newFile = FileUtil.GetCleanFileInfo("07-OpenWorkbookAndAddDataAndChartSample.xlsx"); + FileInfo templateFile = FileUtil.GetFileInfo("07-OpenWorkbookAddDataAndChart", "ExistingWorkbook.xlsx"); using (ExcelPackage package = new ExcelPackage(newFile, templateFile)) { diff --git a/08-SalesReport/SalesReport.cs b/08-SalesReport/SalesReport.cs index 376fcb7..5695a8a 100644 --- a/08-SalesReport/SalesReport.cs +++ b/08-SalesReport/SalesReport.cs @@ -29,13 +29,15 @@ class SalesReportFromDatabase /// The connection string to the SQLite database public static string Run(string connectionString) { - var file = FileOutputUtil.GetFileInfo("08-Salesreport.xlsx"); + var file = FileUtil.GetCleanFileInfo("08-Salesreport.xlsx"); using (ExcelPackage xlPackage = new ExcelPackage(file)) { ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.Add("Sales"); var namedStyle = xlPackage.Workbook.Styles.CreateNamedStyle("HyperLink"); namedStyle.Style.Font.UnderLine = true; namedStyle.Style.Font.Color.SetColor(Color.Blue); + namedStyle.BuildInId = 8; //This is the id for the build in HyperLink style. + const int startRow = 5; int row = startRow; //Create Headers and format them @@ -43,7 +45,7 @@ public static string Run(string connectionString) using (ExcelRange r = worksheet.Cells["A1:G1"]) { r.Merge = true; - r.Style.Font.SetFromFont(new Font("Britannic Bold", 22, FontStyle.Italic)); + r.Style.Font.SetFromFont("Britannic Bold", 22, false, true); r.Style.Font.Color.SetColor(Color.White); r.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.CenterContinuous; r.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid; @@ -53,7 +55,7 @@ public static string Run(string connectionString) using (ExcelRange r = worksheet.Cells["A2:G2"]) { r.Merge = true; - r.Style.Font.SetFromFont(new Font("Britannic Bold", 18, FontStyle.Italic)); + r.Style.Font.SetFromFont("Britannic Bold", 18, false, true); r.Style.Font.Color.SetColor(Color.Black); r.Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous; r.Style.Fill.PatternType = ExcelFillStyle.Solid; @@ -112,13 +114,10 @@ public static string Run(string connectionString) worksheet.Cells[startRow, 6, row - 1, 6].Style.Numberformat.Format = "[$$-409]#,##0"; //Set column width - worksheet.Column(1).Width = 35; - worksheet.Column(2).Width = 28; - worksheet.Column(3).Width = 28; - worksheet.Column(4).Width = 10; - worksheet.Column(5).Width = 12; - worksheet.Column(6).Width = 12; - worksheet.Column(7).Width = 12; + worksheet.Columns[1,3].Width = 35; + worksheet.Columns[2].Width = 28; + worksheet.Columns[4].Width = 10; + worksheet.Columns[5, 7].Width = 12; } } sqlConn.Close(); @@ -133,9 +132,10 @@ public static string Run(string connectionString) // add the file path to the footer worksheet.HeaderFooter.OddFooter.LeftAlignedText = ExcelHeaderFooter.FilePath + ExcelHeaderFooter.FileName; } - // we had better add some document properties to the spreadsheet - // set some core property values + // We can also add some document properties to the spreadsheet + + // Set some core property values xlPackage.Workbook.Properties.Title = "Sales Report"; xlPackage.Workbook.Properties.Author = "Jan Källman"; xlPackage.Workbook.Properties.Subject = "Sales Report Samples"; @@ -143,11 +143,11 @@ public static string Run(string connectionString) xlPackage.Workbook.Properties.Category = "Sales Report Samples"; xlPackage.Workbook.Properties.Comments = "This sample demonstrates how to create an Excel file from scratch using EPPlus"; - // set some extended property values + // Set some extended property values xlPackage.Workbook.Properties.Company = "Fiction Inc."; xlPackage.Workbook.Properties.HyperlinkBase = new Uri("https://EPPlusSoftware.com"); - // set some custom property values + // Set some custom property values xlPackage.Workbook.Properties.SetCustomPropertyValue("Checked by", "Jan Källman"); xlPackage.Workbook.Properties.SetCustomPropertyValue("EmployeeID", "1"); xlPackage.Workbook.Properties.SetCustomPropertyValue("AssemblyName", "EPPlus"); diff --git a/09-PerformanceAndProtection/PerformanceAndProtectionSample.cs b/09-PerformanceAndProtection/PerformanceAndProtectionSample.cs index ccadbe4..841ca5b 100644 --- a/09-PerformanceAndProtection/PerformanceAndProtectionSample.cs +++ b/09-PerformanceAndProtection/PerformanceAndProtectionSample.cs @@ -29,7 +29,7 @@ class PerformanceAndProtectionSample /// public static string Run(int rows) { - var newFile = FileOutputUtil.GetFileInfo("09-PerformanceAndProtection.xlsx"); + var newFile = FileUtil.GetCleanFileInfo("09-PerformanceAndProtection.xlsx"); using (ExcelPackage package = new ExcelPackage()) { Console.WriteLine("{0:HH.mm.ss}\tStarting...", DateTime.Now); @@ -94,7 +94,7 @@ public static string Run(int rows) Console.WriteLine("{0:HH.mm.ss}\tAutofit columns and lock and format cells...", DateTime.Now); ws.Cells[rows - 100, 1, rows, 5].AutoFitColumns(5); //Auto fit using the last 100 rows with minimum width 5 - ws.Column(5).Width = 15; //We need to set the width for column F manually since the end sum formula is the widest cell in the column (EPPlus don't calculate any forumlas, so no output text is avalible). + ws.Columns[5].Width = 15; //We need to set the width for column F manually since the end sum formula is the widest cell in the column (EPPlus don't calculate any forumlas, so no output text is avalible). //Now we set the sheet protection and a password. ws.Cells[2, 3, rows + 1, 4].Style.Locked = false; diff --git a/10-ReadDataUsingLinq/ReadDataUsingLinq.cs b/10-ReadDataUsingLinq/ReadDataUsingLinq.cs index f4987fe..fec6f67 100644 --- a/10-ReadDataUsingLinq/ReadDataUsingLinq.cs +++ b/10-ReadDataUsingLinq/ReadDataUsingLinq.cs @@ -32,7 +32,7 @@ public static void Run() Console.WriteLine("Now open sample 9 again and perform some Linq queries..."); Console.WriteLine(); - FileInfo existingFile = FileOutputUtil.GetFileInfo("09-PerformanceAndProtection.xlsx", false); + FileInfo existingFile = FileUtil.GetFileInfo("09-PerformanceAndProtection.xlsx"); using (ExcelPackage package = new ExcelPackage(existingFile)) { ExcelWorksheet sheet = package.Workbook.Worksheets[0]; diff --git a/11-ConditionalFormatting/ConditionalFormattingSample.cs b/11-ConditionalFormatting/ConditionalFormattingSample.cs index 0a5583a..02ea9f4 100644 --- a/11-ConditionalFormatting/ConditionalFormattingSample.cs +++ b/11-ConditionalFormatting/ConditionalFormattingSample.cs @@ -33,7 +33,7 @@ class ConditionalFormatting /// public static string Run() { - FileInfo newFile = FileOutputUtil.GetFileInfo("11-ConditionalFormatting.xlsx"); + FileInfo newFile = FileUtil.GetCleanFileInfo("11-ConditionalFormatting.xlsx"); using (ExcelPackage package = new ExcelPackage(newFile)) { // add a new worksheet to the empty workbook diff --git a/12-DataValidation/DataValidationSample.cs b/12-DataValidation/DataValidationSample.cs index 535308b..e3279ff 100644 --- a/12-DataValidation/DataValidationSample.cs +++ b/12-DataValidation/DataValidationSample.cs @@ -26,7 +26,7 @@ class DataValidationSample { public static string Run() { - FileInfo output = FileOutputUtil.GetFileInfo("12-DataValidation.xlsx"); + FileInfo output = FileUtil.GetCleanFileInfo("12-DataValidation.xlsx"); using (var package = new ExcelPackage(output)) { AddIntegerValidation(package); diff --git a/13-Filter/FilterSample.cs b/13-Filter/FilterSample.cs index 092ced6..3f472cd 100644 --- a/13-Filter/FilterSample.cs +++ b/13-Filter/FilterSample.cs @@ -42,7 +42,7 @@ public static async Task RunAsync(string connectionString) //Filter on a pivot table, also see sample 24-Slicers. await PivotTableFilter(connectionString, p); - p.SaveAs(FileOutputUtil.GetFileInfo("13-Filters.xlsx")); + p.SaveAs(FileUtil.GetCleanFileInfo("13-Filters.xlsx")); } private static async Task ValueFilter(string connectionString, ExcelPackage p) diff --git a/14-ShapesAndImages/ShapesAndImagesSample.cs b/14-ShapesAndImages/ShapesAndImagesSample.cs index 8356ba3..f4efe67 100644 --- a/14-ShapesAndImages/ShapesAndImagesSample.cs +++ b/14-ShapesAndImages/ShapesAndImagesSample.cs @@ -27,7 +27,7 @@ public static class ShapesAndImagesSample public static void Run() { //The output package - var outputFile = FileOutputUtil.GetFileInfo("14-ShapesAndImages.xlsx"); + var outputFile = FileUtil.GetCleanFileInfo("14-ShapesAndImages.xlsx"); //Create the template... using (ExcelPackage package = new ExcelPackage(outputFile)) @@ -44,25 +44,25 @@ private static void PictureSample(ExcelPackage package) var ws = package.Workbook.Worksheets.Add("Picture"); //Add an jpg image and apply some effects. - var pic = ws.Drawings.AddPicture("Landscape", FileInputUtil.GetFileInfo("14-ShapesAndImages", "LandscapeView.jpg")); + var pic = ws.Drawings.AddPicture("Landscape", FileUtil.GetFileInfo("14-ShapesAndImages", "LandscapeView.jpg")); pic.SetPosition(2, 0, 1, 0); pic.Effect.SetPresetShadow(ePresetExcelShadowType.OuterBottomRight); pic.Effect.OuterShadow.Distance = 10; pic.Effect.SetPresetSoftEdges(ePresetExcelSoftEdgesType.SoftEdge5Pt); //Add the same image, but with 25 percent of the size. Let the position be absolute. - pic = ws.Drawings.AddPicture("LandscapeSmall", FileInputUtil.GetFileInfo("14-ShapesAndImages", "LandscapeView.jpg")); + pic = ws.Drawings.AddPicture("LandscapeSmall", FileUtil.GetFileInfo("14-ShapesAndImages", "LandscapeView.jpg")); pic.SetPosition(2, 0, 16, 0); pic.SetSize(25); //25% pic.ChangeCellAnchor(eEditAs.Absolute); //Add the same image again, but let the picture move and resize when rows and colums are resized. - pic = ws.Drawings.AddPicture("LandscapeMoveAndResize", FileInputUtil.GetFileInfo("14-ShapesAndImages", "LandscapeView.jpg")); + pic = ws.Drawings.AddPicture("LandscapeMoveAndResize", FileUtil.GetFileInfo("14-ShapesAndImages", "LandscapeView.jpg")); pic.SetPosition(30, 0, 16, 0); pic.ChangeCellAnchor(eEditAs.TwoCell); //Add the image overlapping the first image, but make sure it is behind - pic = ws.Drawings.AddPicture("LandscapeSendToBack", FileInputUtil.GetFileInfo("14-ShapesAndImages", "LandscapeView.jpg")); + pic = ws.Drawings.AddPicture("LandscapeSendToBack", FileUtil.GetFileInfo("14-ShapesAndImages", "LandscapeView.jpg")); pic.SetPosition(8, 0, 8, 0); pic.SetSize(25); //25% pic.SendToBack(); @@ -112,8 +112,7 @@ private static void FillAndColorSamples(ExcelPackage package) drawing.SetSize(250, 250); drawing.Fill.Style = eFillStyle.BlipFill; - var image = new Bitmap(FileInputUtil.GetFileInfo("14-ShapesAndImages", "EPPlusLogo.jpg").FullName); - drawing.Fill.BlipFill.Image = image; + drawing.Fill.BlipFill.Image.SetImage(FileUtil.GetFileInfo("14-ShapesAndImages", "EPPlusLogo.jpg")); drawing.Fill.BlipFill.Stretch = true; drawing.Text = "Blip Fill"; } diff --git a/15-ChartsAndThemes/ChartTemplateSample.cs b/15-ChartsAndThemes/ChartTemplateSample.cs index 227601d..8e6da26 100644 --- a/15-ChartsAndThemes/ChartTemplateSample.cs +++ b/15-ChartsAndThemes/ChartTemplateSample.cs @@ -13,7 +13,7 @@ public static async Task AddAreaChart(string connectionString, ExcelPackage pack //Adds an Area chart from a template file. The crtx file has it's own theme, so it does not change with the theme. //The As property provides an easy type cast for drawing objects - var areaChart = ws.Drawings.AddChartFromTemplate(FileInputUtil.GetFileInfo("15-ChartsAndThemes", "AreaChartStyle3.crtx"), "areaChart") + var areaChart = ws.Drawings.AddChartFromTemplate(FileUtil.GetFileInfo("15-ChartsAndThemes", "AreaChartStyle3.crtx"), "areaChart") .As.Chart.AreaChart; var areaSerie = areaChart.Series.Add(ws.Cells[2, 2, 16, 2], ws.Cells[2, 1, 16, 1]); areaSerie.Header = "Order Value"; diff --git a/15-ChartsAndThemes/ChartsAndThemesSample.cs b/15-ChartsAndThemes/ChartsAndThemesSample.cs index 9c586ef..36554d1 100644 --- a/15-ChartsAndThemes/ChartsAndThemesSample.cs +++ b/15-ChartsAndThemes/ChartsAndThemesSample.cs @@ -66,7 +66,10 @@ public static async Task RunAsync(string connectionString, FileInfo xlFi //Adds a scatter chart with a moving average trendline. ScatterChartSample.Add(package); - + + //Adds a column chart with a legend where we style and remove individual legend items. + await ColumnChartWithLegendSample.Add(connectionString, package); + //Adds a bubble-chartsheet ChartWorksheetSample.Add(package); @@ -79,13 +82,13 @@ public static async Task RunAsync(string connectionString, FileInfo xlFi //Adds a sunburst and a treemap chart await SunburstAndTreemapChartSample.Add(connectionString, package); - //Add a box & whisker and a histogram chart + //Adds a box & whisker and a histogram chart BoxWhiskerHistogramChartSample.Add(package); - // Add a waterfall chart + // Adds a waterfall chart WaterfallChartSample.Add(package); - // Add a funnel chart + // Adds a funnel chart FunnelChartSample.Add(package); await RegionMapChartSample.Add(connectionString, package); diff --git a/15-ChartsAndThemes/ColumnChartsWithLegendSample.cs b/15-ChartsAndThemes/ColumnChartsWithLegendSample.cs new file mode 100644 index 0000000..19552f3 --- /dev/null +++ b/15-ChartsAndThemes/ColumnChartsWithLegendSample.cs @@ -0,0 +1,40 @@ +using OfficeOpenXml; +using OfficeOpenXml.Drawing; +using OfficeOpenXml.Drawing.Chart; +using OfficeOpenXml.Drawing.Chart.Style; +using System.Drawing; +using System.Threading.Tasks; + +namespace EPPlusSamples +{ + public class ColumnChartWithLegendSample : ChartSampleBase + { + public static async Task Add(string connectionString, ExcelPackage package) + { + var ws = package.Workbook.Worksheets.Add("ColumnCharts"); + + var range = await LoadFromDatabase(connectionString, ws); + + //Add a line chart + var chart = ws.Drawings.AddBarChart("ColumnChartWithLegend", eBarChartType.ColumnStacked); + var serie1 = chart.Series.Add(ws.Cells[2, 2, 16, 2], ws.Cells[2, 1, 16, 1]); + serie1.Header = "Order Value"; + var serie2 = chart.Series.Add(ws.Cells[2, 3, 16, 3], ws.Cells[2, 1, 16, 1]); + serie2.Header = "Tax"; + var serie3 = chart.Series.Add(ws.Cells[2, 4, 16, 4], ws.Cells[2, 1, 16, 1]); + serie3.Header = "Freight"; + chart.SetPosition(0, 0, 6, 0); + chart.SetSize(1200, 400); + chart.Title.Text = "Column chart"; + + //Set style 10 + chart.StyleManager.SetChartStyle(ePresetChartStyle.ColumnChartStyle10); + + chart.Legend.Entries[0].Font.Fill.Color = Color.Red; + chart.Legend.Entries[1].Font.Fill.Color = Color.Green; + chart.Legend.Entries[2].Deleted = true; + + range.AutoFitColumns(0); + } + } +} diff --git a/16-Sparklines/SparklinesSample.cs b/16-Sparklines/SparklinesSample.cs index d7e60e2..bc42d64 100644 --- a/16-Sparklines/SparklinesSample.cs +++ b/16-Sparklines/SparklinesSample.cs @@ -43,7 +43,7 @@ public static void Run() // Add a new worksheet to the empty workbook and load the fx rates from the text var ws = package.Workbook.Worksheets.Add("SEKRates"); - + //Load the sample data with a Swedish culture setting ws.Cells["A1"].LoadFromText(txt, new ExcelTextFormat() { Delimiter = ';', Culture = CultureInfo.GetCultureInfo("sv-SE") }, TableStyles.Light10, true); ws.Cells["A2:A12"].Style.Numberformat.Format = "yyyy-mm-dd"; @@ -52,7 +52,7 @@ public static void Run() ws.Cells["A15"].Value = "Column"; var sparklineCol = ws.SparklineGroups.Add(eSparklineType.Column, ws.Cells["B15:Q15"], ws.Cells["B2:Q12"]); sparklineCol.High = true; - sparklineCol.ColorHigh.SetColor(Color.Red); + sparklineCol.ColorHigh.SetColor(Color.Red); // Add a line sparkline for all currencies ws.Cells["A16"].Value = "Line"; @@ -72,11 +72,9 @@ public static void Run() ws.Cells["A15:A17"].Style.Font.Bold = true; ws.Cells.AutoFitColumns(); - ws.Row(15).Height = 40; - ws.Row(16).Height = 40; - ws.Row(17).Height = 40; + ws.Rows[15, 17].Height = 40; - package.SaveAs(FileOutputUtil.GetFileInfo("16-Sparklines.xlsx")); + package.SaveAs(FileUtil.GetCleanFileInfo("16-Sparklines.xlsx")); } } } diff --git a/17-FXReportFromDatabase/FXReportFromDatabase.cs b/17-FXReportFromDatabase/FXReportFromDatabase.cs index 720a594..d7ccd0a 100644 --- a/17-FXReportFromDatabase/FXReportFromDatabase.cs +++ b/17-FXReportFromDatabase/FXReportFromDatabase.cs @@ -23,11 +23,20 @@ Date Author Change using System.Drawing; using System.Data.SQLite; using OfficeOpenXml.Drawing.Chart.Style; - +using System.Linq; namespace EPPlusSamples.FXReportFromDatabase { class FxReportFromDatabase { + public class FxRates + { + public DateTime? Date { get; set; } + public double UsdSek { get; set; } + public double UsdEur { get; set; } + public double UsdInr { get; set; } + public double UsdCny { get; set; } + public double UsdDkk { get; set; } + } /// /// This sample creates a new workbook from a template file containing a chart and populates it with Exchange rates from /// the database and set the three series on the chart. @@ -38,7 +47,7 @@ class FxReportFromDatabase /// public static string Run(string connectionString) { - FileInfo template = FileInputUtil.GetFileInfo("17-FXReportFromDatabase", "GraphTemplate.xlsx"); + FileInfo template = FileUtil.GetFileInfo("17-FXReportFromDatabase", "GraphTemplate.xlsx"); using (ExcelPackage p = new ExcelPackage(template, true)) { @@ -132,14 +141,28 @@ public static string Run(string connectionString) chart.Legend.Position = eLegendPosition.Bottom; + //Set Font bold on USD/EUR in the legend. + chart.Legend.Entries[1].Font.Bold = true; + //Set the chart style chart.StyleManager.SetChartStyle(236); + + var query = (from cell in ws.Cells["A22:A" + (row - 1).ToString()] + select new FxRates + { + Date = cell.GetCellValue(), + UsdSek = cell.GetCellValue(1), + UsdEur = cell.GetCellValue(2), + UsdInr = cell.GetCellValue(3), + UsdCny = cell.GetCellValue(4), + UsdDkk = cell.GetCellValue(5), + }).ToList(); } - + //Get the documet as a byte array from the stream and save it to disk. (This is useful in a webapplication) ... var bin = p.GetAsByteArray(); - FileInfo file = FileOutputUtil.GetFileInfo("17-FxReportFromDatabase.xlsx"); + FileInfo file = FileUtil.GetCleanFileInfo("17-FxReportFromDatabase.xlsx"); File.WriteAllBytes(file.FullName, bin); return file.FullName; } diff --git a/18-PivotTables/PivotTablesSample.cs b/18-PivotTables/PivotTablesSample.cs index 5bb9d96..f267c5c 100644 --- a/18-PivotTables/PivotTablesSample.cs +++ b/18-PivotTables/PivotTablesSample.cs @@ -46,7 +46,7 @@ public static string Run(string connectionStr) { var list = GetDataFromSQL(connectionStr); - FileInfo newFile = FileOutputUtil.GetFileInfo("18-PivotTables.xlsx"); + FileInfo newFile = FileUtil.GetCleanFileInfo("18-PivotTables.xlsx"); using (ExcelPackage pck = new ExcelPackage(newFile)) { // get the handle to the existing worksheet @@ -311,17 +311,17 @@ private static ExcelPivotTable CreatePivotTableWithDataFieldsUsingShowAs(ExcelPa df2.Name = "Order value % of total"; df2.ShowDataAs.SetPercentOfColumn(); df2.Format = "0.0%;"; - + var df3 = pivotTable5.DataFields.Add(pivotTable5.Fields["OrderValue"]); df3.Name = "Count Difference From Previous"; df3.ShowDataAs.SetDifference(rowField1, ePrevNextPivotItem.Previous); df3.Function = DataFieldFunctions.Count; df3.Format = "#,##0"; - + pivotTable5.SetCompact(false); pivotTable5.ColumnHeaderCaption = "Data"; - pivotTable5.ShowColumnStripes = true; - wsPivot5.Column(1).Width = 30; + pivotTable5.ShowColumnStripes = true; + wsPivot5.Columns[1].Width = 30; return pivotTable5; } diff --git a/18-PivotTables/PivotTablesStylingSample.cs b/18-PivotTables/PivotTablesStylingSample.cs index 8518bd7..e055928 100644 --- a/18-PivotTables/PivotTablesStylingSample.cs +++ b/18-PivotTables/PivotTablesStylingSample.cs @@ -35,8 +35,8 @@ public static class PivotTablesStylingSample { public static string Run() { - FileInfo templateFile = FileOutputUtil.GetFileInfo("18-PivotTables.xlsx", false); - FileInfo newFile = FileOutputUtil.GetFileInfo("18-PivotTables-Styling.xlsx"); + FileInfo templateFile = FileUtil.GetFileInfo("18-PivotTables.xlsx"); + FileInfo newFile = FileUtil.GetFileInfo("18-PivotTables-Styling.xlsx"); using ( ExcelPackage pck = new ExcelPackage(newFile, templateFile)) { //These two sample shows how to style different parts on the pivot table using pivot areas. diff --git a/19-EncryptionAndProtection/EncryptionAndProtectionSample.cs b/19-EncryptionAndProtection/EncryptionAndProtectionSample.cs index 96fc316..b5c0f30 100644 --- a/19-EncryptionAndProtection/EncryptionAndProtectionSample.cs +++ b/19-EncryptionAndProtection/EncryptionAndProtectionSample.cs @@ -26,12 +26,12 @@ public static class DrawingsSample public static void Run() { //Create a Sample 19 directory... - var outputDir = FileOutputUtil.GetDirectoryInfo("19-EncryptionAndProtection"); + var outputDir = FileUtil.GetDirectoryInfo("19-EncryptionAndProtection"); //create the three FileInfo objects... - FileInfo templateFile = FileOutputUtil.GetFileInfo(outputDir, "template.xlsx"); - FileInfo answerFile = FileOutputUtil.GetFileInfo(outputDir, "answers.xlsx"); - FileInfo JKAnswerFile = FileOutputUtil.GetFileInfo(outputDir, "JKAnswers.xlsx"); + FileInfo templateFile = FileUtil.GetFileInfo(outputDir, "template.xlsx"); + FileInfo answerFile = FileUtil.GetFileInfo(outputDir, "answers.xlsx"); + FileInfo JKAnswerFile = FileUtil.GetFileInfo(outputDir, "JKAnswers.xlsx"); //Create the template... using (ExcelPackage package = new ExcelPackage(templateFile)) @@ -66,9 +66,9 @@ public static void Run() sheet.Cells["A1"].Style.Font.Size = 18; sheet.Cells["A3"].Value = "Enter your name:"; - sheet.Column(1).Width = 30; - sheet.Column(2).Width = 80; - sheet.Column(3).Width = 20; + sheet.Columns[1].Width = 30; + sheet.Columns[2].Width = 80; + sheet.Columns[3].Width = 20; sheet.Cells["A7"].Value = "What is the name of the capital of Sweden?"; sheet.Cells["A9"].Value = "At which place did the Swedish team end up in the Soccer Worldcup 1994?"; diff --git a/20-CreateFileSystemReport/CreateAFileSystemReport.cs b/20-CreateFileSystemReport/CreateAFileSystemReport.cs index f88feeb..d4a63de 100644 --- a/20-CreateFileSystemReport/CreateAFileSystemReport.cs +++ b/20-CreateFileSystemReport/CreateAFileSystemReport.cs @@ -64,7 +64,7 @@ public static string Run(DirectoryInfo dir, int depth, bool skipIcons) { _maxLevels = depth; - FileInfo newFile = FileOutputUtil.GetFileInfo("20-CreateAFileSystemReport.xlsx"); + FileInfo newFile = FileUtil.GetCleanFileInfo("20-CreateAFileSystemReport.xlsx"); //Create the workbook ExcelPackage pck = new ExcelPackage(newFile); @@ -73,17 +73,14 @@ public static string Run(DirectoryInfo dir, int depth, bool skipIcons) ws.View.ShowGridLines = false; - ws.Column(1).Width = 2.5; - ws.Column(2).Width = 60; - ws.Column(3).Width = 16; - ws.Column(4).Width = 20; - ws.Column(5).Width = 20; + ws.Columns[1].Width = 2.5; + ws.Columns[2].Width = 60; + ws.Columns[3].Width = 16; + ws.Columns[4, 5].Width = 20; //This set the outline for column 4 and 5 and hide them - ws.Column(4).OutlineLevel = 1; - ws.Column(4).Collapsed = true; - ws.Column(5).OutlineLevel = 1; - ws.Column(5).Collapsed = true; + ws.Columns[4, 5].OutlineLevel = 1; + ws.Columns[4, 5].Collapsed = true; ws.OutLineSummaryRight = true; //Headers @@ -101,8 +98,7 @@ public static string Run(DirectoryInfo dir, int depth, bool skipIcons) int row = 2; //Load the directory content to sheet 1 - row = AddDirectory(ws, dir, row, height, 0, skipIcons); - + row = AddDirectory(ws, dir, row, height, skipIcons); ws.OutLineSummaryBelow = false; //Format columns @@ -114,8 +110,8 @@ public static string Run(DirectoryInfo dir, int depth, bool skipIcons) var shape = ws.Drawings.AddShape("txtDesc", eShapeStyle.Rect); shape.SetPosition(1, 5, 6, 5); shape.SetSize(400, 200); - - shape.Text = "This example demonstrates how to create various drawing objects like pictures, shapes and charts.\n\r\n\rThe first sheet contains all subdirectories and files with an icon, name, size and dates.\n\r\n\rThe second sheet contains statistics about extensions and the top-10 largest files."; + shape.EditAs = eEditAs.Absolute; + shape.Text = "This example demonstrates how to create various drawing objects like pictures, shapes and charts.\n\r\n\rThe first sheet contains all subdirectories and files with an icon, name, size and dates.\r\n\r\nThe second sheet contains statistics about extensions and the top-10 largest files."; shape.Fill.Style = eFillStyle.SolidFill; shape.Fill.Color = Color.DarkSlateGray; shape.Fill.Transparancy = 20; @@ -132,12 +128,22 @@ public static string Run(DirectoryInfo dir, int depth, bool skipIcons) //Add the graph sheet AddGraphs(pck, row, dir.FullName); - //Add a HyperLink to the statistics sheet. - var namedStyle = pck.Workbook.Styles.CreateNamedStyle("HyperLink"); //This one is language dependent - namedStyle.Style.Font.UnderLine = true; - namedStyle.Style.Font.Color.SetColor(Color.Blue); - ws.Cells["K13"].Hyperlink = new ExcelHyperLink("Statistics!A1", "Statistics"); - ws.Cells["K13"].StyleName = "HyperLink"; + + //Add a drawing with a HyperLink to the statistics sheet. + //We add the hyperlink as a drawing here, as we don't want it to move when we expand and collapse rows.. + var hl =ws.Drawings.AddShape("HyperLink", eShapeStyle.Rect); + hl.Hyperlink = new ExcelHyperLink("Statistics!A1", "Statistics"); + hl.SetPosition(13, 0, 9, 0); + hl.SetSize(70, 30); + hl.EditAs = eEditAs.Absolute; + hl.Border.Fill.Style = eFillStyle.NoFill; + hl.Fill.Style = eFillStyle.NoFill; + hl.Text = "Statistics"; + hl.Font.UnderLine = eUnderLineType.Single; + hl.Font.Fill.Color = Color.Blue; + + // Collaps children to level 1 for each row under the root. + ws.Rows[2].SetVisibleOutlineLevel(1); //Printer settings ws.PrinterSettings.FitToPage = true; @@ -208,7 +214,7 @@ private static void AddGraphs(ExcelPackage pck, int rows, string dir) using (ExcelRange r = ws.Cells["A1:O1"]) { r.Merge = true; - r.Style.Font.SetFromFont(new Font("Arial", 22, FontStyle.Regular)); + r.Style.Font.SetFromFont("Arial", 22); r.Style.Font.Color.SetColor(Color.White); r.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.CenterContinuous; r.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid; @@ -309,7 +315,7 @@ private static int AddStatRows(ExcelWorksheet ws, List lst, int startR using (ExcelRange r = ws.Cells[row, 1, row, 2]) { r.Merge = true; - r.Style.Font.SetFromFont(new Font("Arial", 16, FontStyle.Italic)); + r.Style.Font.SetFromFont("Arial", 16, false,true); r.Style.Font.Color.SetColor(Color.White); r.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.CenterContinuous; r.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid; @@ -324,7 +330,7 @@ private static int AddStatRows(ExcelWorksheet ws, List lst, int startR ws.Cells[row, 2].Value = propertyName; using (ExcelRange r = ws.Cells[row, 1, row, 2]) { - r.Style.Font.SetFromFont(new Font("Arial", 12, FontStyle.Bold)); + r.Style.Font.SetFromFont("Arial", 12, true); } row++; @@ -397,7 +403,7 @@ private static void AlterColor(ExcelWorksheet ws, int row) } } - private static int AddDirectory(ExcelWorksheet ws, DirectoryInfo dir, int row, double height, int level, bool skipIcons) + private static int AddDirectory(ExcelWorksheet ws, DirectoryInfo dir, int row, double height, bool skipIcons) { //Get the icon as a bitmap Console.WriteLine("Directory " + dir.Name); @@ -405,12 +411,16 @@ private static int AddDirectory(ExcelWorksheet ws, DirectoryInfo dir, int row, d { Bitmap icon = GetIcon(dir.FullName); - ws.Row(row).Height = height; + ws.Rows[row].Height = height; //Add the icon as a picture if (icon != null) { - ExcelPicture pic = ws.Drawings.AddPicture("pic" + (row).ToString(), icon); - pic.SetPosition((int)20 * (row - 1) + 2, 0); + using (var ms = new MemoryStream()) + { + icon.Save(ms, ImageFormat.Bmp); + ExcelPicture pic = ws.Drawings.AddPicture("pic" + (row).ToString(), ms); + pic.SetPosition((int)20 * (row - 1) + 2, 0); + } } } ws.Cells[row, 2].Value = dir.Name; @@ -418,17 +428,15 @@ private static int AddDirectory(ExcelWorksheet ws, DirectoryInfo dir, int row, d ws.Cells[row, 5].Value = dir.LastAccessTime; ws.Cells[row, 2, row, 5].Style.Font.Bold = true; - //Sets the outline depth - ws.Row(row).OutlineLevel = level; int prevRow = row; row++; //Add subdirectories foreach (DirectoryInfo subDir in dir.GetDirectories()) { - if (level < _maxLevels) + if (ws.Rows[prevRow].OutlineLevel < _maxLevels) { - row = AddDirectory(ws, subDir, row, height, level + 1, skipIcons); + row = AddDirectory(ws, subDir, row, height, skipIcons); } } @@ -439,11 +447,15 @@ private static int AddDirectory(ExcelWorksheet ws, DirectoryInfo dir, int row, d { Bitmap fileIcon = GetIcon(file.FullName); - ws.Row(row).Height = height; + ws.Rows[row].Height = height; if (fileIcon != null) { - ExcelPicture pic = ws.Drawings.AddPicture("pic" + (row).ToString(), fileIcon); - pic.SetPosition((int)20 * (row - 1) + 2, 0); + using (var ms = new MemoryStream()) + { + fileIcon.Save(ms, ImageFormat.Bmp); + ExcelPicture pic = ws.Drawings.AddPicture("pic" + (row).ToString(), ms); + pic.SetPosition((int)20 * (row - 1) + 2, 0); + } } } @@ -452,13 +464,17 @@ private static int AddDirectory(ExcelWorksheet ws, DirectoryInfo dir, int row, d ws.Cells[row, 4].Value = file.CreationTime; ws.Cells[row, 5].Value = file.LastAccessTime; - ws.Row(row).OutlineLevel = level+1; - AddStatistics(file); row++; } + //If the directory has children, group them. The Group method adds one to the Outline level. + if (prevRow < row - 1) + { + ws.Rows[prevRow + 1, row - 1].Group(); + } + //Add a subtotal for the directory if (row -1 > prevRow) { diff --git a/21-VBA/SampleCertificate.pfx b/21-VBA/SampleCertificate.pfx new file mode 100644 index 0000000..2e03b01 Binary files /dev/null and b/21-VBA/SampleCertificate.pfx differ diff --git a/21-VBA/SigningYourVBAProject.cs b/21-VBA/SigningYourVBAProject.cs new file mode 100644 index 0000000..440fdc4 --- /dev/null +++ b/21-VBA/SigningYourVBAProject.cs @@ -0,0 +1,48 @@ +using OfficeOpenXml; +using OfficeOpenXml.VBA; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; + +namespace EPPlusSamples +{ + class SigningYourVBAProject + { + /// + /// Opens the Battleships sample and sign it with the certificate from the pfx file. + /// + public static void Run() + { + //Load our test certificate from the pfx file. + //In a real production environment, make to store your certificate in a secure way. + var cert = new X509Certificate2(FileUtil.GetRootDirectory() + "\\21-VBA\\SampleCertificate.pfx", "EPPlus"); + + //Open the workbook created in the previous sample. + using (var p = new ExcelPackage(FileUtil.GetFileInfo("21.3-CreateABattleShipsGameVba.xlsm"))) + { + var signature = p.Workbook.VbaProject.Signature; + + //The only thing you need to do to sign your project is to set the signatures 'Certificate' property with your code-signing certificate. + //The certificate must have access to the private key to sign the project. + signature.Certificate = cert; + + //If the file is unsigned, EPPlus will by default create all three signatures - Legacy, Agile and V3. + //You can use the property 'CreateSignatureOnSave' to decide which signature version you want to create on saving the workbook. + //For example 'signature.LegacySignature.CreateSignatureOnSave = false' to remove the legacy signature. + + //You can also set the hash algorithm for each signature version. + //The Excel and EPPlus default is MD5 for the legacy signature and SHA1 for the Agile and V3 signature. + //We want to change it to SHA256 to get better and more modern hash algorithm. + signature.LegacySignature.HashAlgorithm = VbaSignatureHashAlgorithm.SHA256; + signature.AgileSignature.HashAlgorithm = VbaSignatureHashAlgorithm.SHA256; + signature.V3Signature.HashAlgorithm = VbaSignatureHashAlgorithm.SHA256; + + p.SaveAs(FileUtil.GetFileInfo("21.4-Signed-CreateABattleShipsGameVba.xlsm")); + } + } + + } +} diff --git a/21-VBA/WorkingWithVbaSample.cs b/21-VBA/WorkingWithVbaSample.cs index 6d1d1ce..27dec37 100644 --- a/21-VBA/WorkingWithVbaSample.cs +++ b/21-VBA/WorkingWithVbaSample.cs @@ -53,12 +53,12 @@ private static void SimpleVba() pck.Workbook.CodeModule.Code = sb.ToString(); //And Save as xlsm - FileInfo fi = FileOutputUtil.GetFileInfo("21.1-SimpleVba.xlsm"); + FileInfo fi = FileUtil.GetCleanFileInfo("21.1-SimpleVba.xlsm"); pck.SaveAs(fi); } private static void AddABubbleChart() { - FileInfo sample1File = FileOutputUtil.GetFileInfo("01-GettingStarted.xlsx", false); + FileInfo sample1File = FileUtil.GetFileInfo("01-GettingStarted.xlsx"); //Open Sample 1 again ExcelPackage pck = new ExcelPackage(sample1File); var p = new ExcelPackage(); @@ -88,7 +88,7 @@ private static void AddABubbleChart() //pck.Workbook.VbaProject.Signature.Certificate = store.Certificates[0]; //And Save as xlsm - FileInfo fi =FileOutputUtil.GetFileInfo("21.2-AddABubbleChartVba.xlsm"); + FileInfo fi =FileUtil.GetCleanFileInfo("21.2-AddABubbleChartVba.xlsm"); pck.SaveAs(fi); } private static void CreateABattleShipsGame() @@ -123,7 +123,7 @@ private static void CreateABattleShipsGame() //Password protect your code pck.Workbook.VbaProject.Protection.SetPassword("EPPlus"); - var codeDir = FileInputUtil.GetSubDirectory("21-VBA", "VBA-Code"); + var codeDir = FileUtil.GetSubDirectory("21-VBA", "VBA-Code"); //Add all the code from the textfiles in the Vba-Code sub-folder. pck.Workbook.CodeModule.Code = GetCodeModule(codeDir, "ThisWorkbook.txt"); @@ -170,7 +170,7 @@ private static void CreateABattleShipsGame() //Set the headers. ws.SetValue("B1", "Computer Grid"); ws.SetValue("M1", "Your Grid"); - ws.Row(1).Style.Font.Size = 18; + ws.Rows[1].Style.Font.Size = 18; AddChart(ws.Cells["B13"], "chtHitPercent", "Player"); AddChart(ws.Cells["M13"], "chtComputerHitPercent", "Computer"); @@ -198,13 +198,13 @@ private static void CreateABattleShipsGame() // } //} - var fi = FileOutputUtil.GetFileInfo(@"21.3-CreateABattleShipsGameVba.xlsm"); + var fi = FileUtil.GetCleanFileInfo(@"21.3-CreateABattleShipsGameVba.xlsm"); pck.SaveAs(fi); } private static string GetCodeModule(DirectoryInfo codeDir, string fileName) { - return File.ReadAllText(FileOutputUtil.GetFileInfo(codeDir, fileName, false).FullName); + return File.ReadAllText(FileUtil.GetFileInfo(codeDir, fileName, false).FullName); } private static void AddChart(ExcelRange rng,string name, string prefix) diff --git a/22-IgnoreErrors/IgnoreErrorsSample.cs b/22-IgnoreErrors/IgnoreErrorsSample.cs index 9d02355..1a4447f 100644 --- a/22-IgnoreErrors/IgnoreErrorsSample.cs +++ b/22-IgnoreErrors/IgnoreErrorsSample.cs @@ -52,7 +52,7 @@ public static void Run() ie = ws.IgnoredErrors.Add(ws.Cells["D2,D4"]); ie.Formula = true; // Ignore the inconsistant formula error - p.SaveAs(FileOutputUtil.GetFileInfo("22-IgnoreErrors.xlsx")); + p.SaveAs(FileUtil.GetCleanFileInfo("22-IgnoreErrors.xlsx")); } } } diff --git a/23-Comments/CommentsSample.cs b/23-Comments/CommentsSample.cs index b01db16..65a102c 100644 --- a/23-Comments/CommentsSample.cs +++ b/23-Comments/CommentsSample.cs @@ -20,7 +20,7 @@ public static void Run() // Threaded comments var sheet2 = package.Workbook.Worksheets.Add("ThreadedComments"); AddAndReadThreadedComments(sheet2); - package.SaveAs(FileOutputUtil.GetFileInfo("23-Comments.xlsx")); + package.SaveAs(FileUtil.GetCleanFileInfo("23-Comments.xlsx")); } } diff --git a/24-Slicers/SlicerSample.cs b/24-Slicers/SlicerSample.cs index 84391f3..e27849b 100644 --- a/24-Slicers/SlicerSample.cs +++ b/24-Slicers/SlicerSample.cs @@ -26,7 +26,7 @@ public static void Run(string connectionString) //Create three slicers and two pivot tables, one that connects to both tables and two that connect to each of the tables. PivotTableOneSlicerToMultiplePivotTables(p); - p.SaveAs(FileOutputUtil.GetFileInfo("24-Slicers.xlsx")); + p.SaveAs(FileUtil.GetCleanFileInfo("24-Slicers.xlsx")); } } diff --git a/26-FormControls/FormControlsSample.cs b/26-FormControls/FormControlsSample.cs index d0b8cc2..89f02ba 100644 --- a/26-FormControls/FormControlsSample.cs +++ b/26-FormControls/FormControlsSample.cs @@ -118,7 +118,7 @@ public static void Run() code.AppendLine("End Sub"); module.Code = code.ToString(); - package.SaveAs(FileOutputUtil.GetFileInfo("26-FormControls.xlsm")); + package.SaveAs(FileUtil.GetCleanFileInfo("26-FormControls.xlsm")); } } @@ -128,13 +128,11 @@ private static ExcelWorksheet CreateFormSheet(ExcelPackage package) formSheet.Cells["A1"].Value = "Room booking"; formSheet.Cells["A1"].Style.Font.Size = 18; formSheet.Cells["A1"].Style.Font.Bold = true; - formSheet.Column(1).Width = 30; - formSheet.Column(2).Width = 60; + formSheet.Columns[1].Width = 30; + formSheet.Columns[2].Width = 60; formSheet.Cells.Style.Fill.SetBackground(Color.Gray); - for (int row = 1; row <= 18; row++) - { - formSheet.Row(row).Height = 25; - } + + formSheet.Rows[1, 18].Height = 25; return formSheet; } diff --git a/27-CustomNamedStyles/TableSlicerStyleSample.cs b/27-CustomNamedStyles/TableSlicerStyleSample.cs index ca69a6f..3857ae1 100644 --- a/27-CustomNamedStyles/TableSlicerStyleSample.cs +++ b/27-CustomNamedStyles/TableSlicerStyleSample.cs @@ -22,7 +22,7 @@ public static void Run(string connectionString) CreatePivotTableStyles(p); CreateSlicerStyles(p); - p.SaveAs(FileOutputUtil.GetFileInfo("27-TableAndSlicerStyles.xlsx")); + p.SaveAs(FileUtil.GetCleanFileInfo("27-TableAndSlicerStyles.xlsx")); } } diff --git a/28-Tables/SortingTablesSample.cs b/28-Tables/SortingTablesSample.cs index 314d10c..b4839de 100644 --- a/28-Tables/SortingTablesSample.cs +++ b/28-Tables/SortingTablesSample.cs @@ -16,7 +16,7 @@ public static class SortingTablesSample { public static async Task RunAsync(string connectionString) { - var file = FileOutputUtil.GetFileInfo("28-SortingTables.xlsx"); + var file = FileUtil.GetCleanFileInfo("28-SortingTables.xlsx"); using (ExcelPackage package = new ExcelPackage(file)) { // Sheet 1 diff --git a/28-Tables/TablesSample.cs b/28-Tables/TablesSample.cs index c6fc7fd..46ddc4a 100644 --- a/28-Tables/TablesSample.cs +++ b/28-Tables/TablesSample.cs @@ -23,7 +23,7 @@ public static async Task RunAsync(string connectionString) await StyleTablesAsync(connectionString, p).ConfigureAwait(false); await CreateTableFilterAndSlicerAsync(connectionString, p).ConfigureAwait(false); - p.SaveAs(FileOutputUtil.GetFileInfo("28-Tables.xlsx")); + p.SaveAs(FileUtil.GetCleanFileInfo("28-Tables.xlsx")); } } /// @@ -96,7 +96,7 @@ private static async Task StyleTablesAsync(string connectionString, ExcelPackage var ws = p.Workbook.Worksheets.Add("StyleTables"); var range1 = await LoadDataAsync(connectionString, ws).ConfigureAwait(false); - + SetEmailAsHyperlink(range1); //Add the table and set some styles and properties. var tbl1 = ws.Tables.Add(range1, "StyleTable1"); tbl1.TableStyle = TableStyles.Medium24; @@ -133,6 +133,19 @@ private static async Task StyleTablesAsync(string connectionString, ExcelPackage tbl2.Range.AutoFitColumns(); } + + private static void SetEmailAsHyperlink(ExcelRangeBase range) + { + for(int row=1;row<=range.Rows;row++) + { + var cell = range.Offset(row, 2,1,1); + if (cell.Value != null) + { + cell.Hyperlink = new Uri($"mailto:{cell.Value}"); + } + } + } + /// /// This sample creates a table and a slicer. /// diff --git a/29-ExternalLinks/ExternalLinksSample.cs b/29-ExternalLinks/ExternalLinksSample.cs index cd5e9e6..1257c4f 100644 --- a/29-ExternalLinks/ExternalLinksSample.cs +++ b/29-ExternalLinks/ExternalLinksSample.cs @@ -17,7 +17,7 @@ public static void Run() ReadFileWithExternalLink(); //Sample file 1 adds external links to another workbook. - var sampleFile1 = FileOutputUtil.GetFileInfo("29-ExternalLinks-1.xlsx"); + var sampleFile1 = FileUtil.GetCleanFileInfo("29-ExternalLinks-1.xlsx"); using (var p = new ExcelPackage(sampleFile1)) { @@ -38,7 +38,7 @@ public static void Run() /// private static void ReadFileWithExternalLink() { - var externalFile = FileInputUtil.GetFileInfo("29-ExternalLinks", "WorkbookWithExternalLinks.xlsx"); + var externalFile = FileUtil.GetFileInfo("29-ExternalLinks", "WorkbookWithExternalLinks.xlsx"); using (var p = new ExcelPackage(externalFile)) { //This worksheet contains references to an external workbook. @@ -72,7 +72,7 @@ private static void ReadFileWithExternalLink() //To avoid this behavior you can load the external workbook before doing the calculate. //This is only an issue in special cases where the function needs information not available in the cache, as for example hidden cells and numeric formats. var externalReference = p.Workbook.ExternalLinks[0].As.ExternalWorkbook; - p.Workbook.ExternalLinks.Directories.Add(FileInputUtil.GetSubDirectory("29-ExternalLinks","Data")); + p.Workbook.ExternalLinks.Directories.Add(FileUtil.GetSubDirectory("29-ExternalLinks","Data")); externalReference.Load(); ws.ClearFormulaValues(); @@ -91,7 +91,7 @@ private static void ReadFileWithExternalLink() private static void AddWorksheetWithExternalReferences(ExcelPackage p) { //Add a reference to the file created by sample 28. - var externalLinkFile = FileOutputUtil.GetFileInfo("28-Tables.xlsx", false); + var externalLinkFile = FileUtil.GetFileInfo("28-Tables.xlsx"); var externalWorkbook = p.Workbook.ExternalLinks.AddExternalWorkbook(externalLinkFile); var ws = p.Workbook.Worksheets.Add("Sheet1"); @@ -116,7 +116,7 @@ private static void AddWorksheetWithExternalReferences(ExcelPackage p) } private static void AddWorksheetWithExternalReferencesInFormulas(ExcelPackage p) { - var externalLinkFile = FileOutputUtil.GetFileInfo("01-GettingStarted.xlsx", false); + var externalLinkFile = FileUtil.GetFileInfo("01-GettingStarted.xlsx"); var externalWorkbook = p.Workbook.ExternalLinks.AddExternalWorkbook(externalLinkFile); var ws = p.Workbook.Worksheets.Add("Sheet2"); @@ -151,7 +151,7 @@ private static void BreakLinks(FileInfo sampleFile1) Console.WriteLine($"Now break links to the workbook {p.Workbook.ExternalLinks[0].As.ExternalWorkbook.File.FullName}"); p.Workbook.ExternalLinks.RemoveAt(0); - var newFile = FileOutputUtil.GetFileInfo("29-ExternalLinks-Link1Removed.xlsx", false); + var newFile = FileUtil.GetFileInfo("29-ExternalLinks-Link1Removed.xlsx"); p.SaveAs(newFile); } } diff --git a/30-SortingRanges/Readme.md b/30-SortingRanges/Readme.md deleted file mode 100644 index 9fcc681..0000000 --- a/30-SortingRanges/Readme.md +++ /dev/null @@ -1,5 +0,0 @@ -# 30 - Sorting ranges -These samples demonstrates how to sort ranges with EPPlus. Contains one example for sorting top to bottom and one for left to right using a custom list. -### [SortingRangesSample.cs](SortingRangesSample.cs) ---- -[Back to overview](/Readme.md) \ No newline at end of file diff --git a/30-WorkingWithRanges/CopyRangeSample.cs b/30-WorkingWithRanges/CopyRangeSample.cs new file mode 100644 index 0000000..b4aec32 --- /dev/null +++ b/30-WorkingWithRanges/CopyRangeSample.cs @@ -0,0 +1,127 @@ +/************************************************************************************************* + Required Notice: Copyright (C) EPPlus Software AB. + This software is licensed under PolyForm Noncommercial License 1.0.0 + and may only be used for noncommercial purposes + https://polyformproject.org/licenses/noncommercial/1.0.0/ + + A commercial license to use this software can be purchased at https://epplussoftware.com + ************************************************************************************************* + Date Author Change + ************************************************************************************************* + 10/13/2021 EPPlus Software AB Initial release EPPlus 5 + *************************************************************************************************/ + +using OfficeOpenXml; +using System; +using System.Collections.Generic; +using System.Data.SQLite; +using System.Drawing; +using System.Threading.Tasks; + +namespace EPPlusSamples +{ + public static class CopyRangeSample + { + //This sample demonstrates how to copy entire worksheet, ranges and how to exclude different cell properties. + public static void Run() + { + using (var p = new ExcelPackage()) + { + var sourceFile = FileUtil.GetFileInfo("08-Salesreport.xlsx"); + var sourcePackage = new ExcelPackage(sourceFile); + var sourceWs = sourcePackage.Workbook.Worksheets[0]; + + //Copy the entire source worksheet to a new worksheet. + CopyEntireWorksheet(p, sourceWs); + //Copy a range from the source worksheet to the new worksheet. + //This samples demonstrates how to exclude different options to exclude different parts of the cell properties + CopyRange(p, sourceWs); + //Copy a range with values only, removing any formula. + CopyValues(p); + //Copy styles + CopyStyles(p, sourceWs); + + p.SaveAs(FileUtil.GetCleanFileInfo("30-CopyRangeSamples.xlsx")); + } + } + + private static void CopyValues(ExcelPackage p) + { + var ws = p.Workbook.Worksheets.Add("CopyValues"); + //Add some numbers and formulas and calculate the worksheet + ws.Cells["A1:A10"].FillNumber(1); + ws.Cells["B1:B9"].Formula = "A1+A2"; + ws.Cells["B10"].Formula = "Sum(B1:B9)"; + ws.Calculate(); + + //Now, copy the values starting at cell D1 without the formulas. + ws.Cells["A1:B10"].Copy(ws.Cells["D1"], ExcelRangeCopyOptionFlags.ExcludeFormulas); + } + + private static void CopyEntireWorksheet(ExcelPackage p, ExcelWorksheet sourceWs) + { + //To copy the entire worksheet just add the source worksheet as parameter 2 when adding the new worksheet. + p.Workbook.Worksheets.Add("CopySalesReport", sourceWs); + } + + private static void CopyRange(ExcelPackage p, ExcelWorksheet sourceWs) + { + var ws = p.Workbook.Worksheets.Add("CopyRangeOfReport"); + + //Use the first 10 rows of the sales report in sample 8 as the source. + var sourceRange = sourceWs.Cells["A1:G10"]; + + //Copy the source full range starting from C1. + //Copy always start from the top left cell of the destination range and copies the full range. + sourceRange.Copy(ws.Cells["C1"]); + + //Copy the same source range to C15 and exclude the hyperlinks. + //We also remove the Hyperlink style from the range containing the hyperlinks. + sourceRange.Copy(ws.Cells["C15"], ExcelRangeCopyOptionFlags.ExcludeHyperLinks); + ws.Cells["D19:D24"].StyleName = "Normal"; + + //Copy the values only, excluding merged cells, styles and hyperlinks. + sourceRange.Copy(ws.Cells["C30"], ExcelRangeCopyOptionFlags.ExcludeMergedCells, ExcelRangeCopyOptionFlags.ExcludeStyles , ExcelRangeCopyOptionFlags.ExcludeHyperLinks); + + //Copy styles and merged cells, excluding values and hyperlinks. + sourceRange.Copy(ws.Cells["C45"], ExcelRangeCopyOptionFlags.ExcludeValues, ExcelRangeCopyOptionFlags.ExcludeHyperLinks); + + ws.Cells.AutoFitColumns(); + } + private static void CopyStyles(ExcelPackage p, ExcelWorksheet sourceWs) + { + var ws = p.Workbook.Worksheets.Add("CopyStyles"); + + //Create a new random report + FillRangeWithRandomData(ws); + + //Copy the styles from the sales report. + //If the destination range is larger that the source range styles are filled down and right using the last column/row the source range of the source range. + sourceWs.Cells["A1:G5"].CopyStyles(ws.Cells["A1:G50"]); + + ws.Cells.AutoFitColumns(); + } + + private static void FillRangeWithRandomData(ExcelWorksheet ws) + { + ws.Cells["A1"].Value = "EPPlus"; + ws.Cells["A2"].Value = "New Random Report"; + ws.Cells["A4"].Value = "Color"; + ws.Cells["B4"].Value = "Category"; + ws.Cells["C4"].Value = "Country"; + ws.Cells["D4"].Value = "Id"; + ws.Cells["E4"].Value = "Date"; + ws.Cells["F4"].Value = "Amount"; + ws.Cells["G4"].Value = "Currency"; + + ws.Cells["A5:A50"].FillList(new string[] { "Red", "Green", "Blue", "Pink", "Black" }); + ws.Cells["B5:B50"].FillList(new string[] { "New", "Old" }); + ws.Cells["C5:C50"].FillList(new string[] { "Usa", "France", "India" }); + + ws.Cells["D5:D50"].FillNumber(1, 10); + ws.Cells["E5:E50"].FillDateTime(DateTime.Today); + ws.Cells["F5:F50"].FillNumber(1000, 50); + ws.Cells["G5:G50"].FillList(new string[] { "USD", "EUR", "INR" }); + } + } +} diff --git a/30-WorkingWithRanges/FillRangeSample.cs b/30-WorkingWithRanges/FillRangeSample.cs new file mode 100644 index 0000000..a340f6c --- /dev/null +++ b/30-WorkingWithRanges/FillRangeSample.cs @@ -0,0 +1,168 @@ +/************************************************************************************************* + Required Notice: Copyright (C) EPPlus Software AB. + This software is licensed under PolyForm Noncommercial License 1.0.0 + and may only be used for noncommercial purposes + https://polyformproject.org/licenses/noncommercial/1.0.0/ + + A commercial license to use this software can be purchased at https://epplussoftware.com + ************************************************************************************************* + Date Author Change + ************************************************************************************************* + 10/13/2021 EPPlus Software AB Initial release EPPlus 5 + *************************************************************************************************/ + +using OfficeOpenXml; +using System; +using System.Collections.Generic; + +namespace EPPlusSamples +{ + public static class FillRangeSample + { + public static void Run() + { + using (var p = new ExcelPackage()) + { + FillNumber(p); + FillDate(p); + FillList(p); + p.SaveAs(FileUtil.GetCleanFileInfo("30-FillRangeSamples.xlsx")); + } + } + /// + /// Several samples how to use the FillNumber method + /// + /// The package + private static void FillNumber(ExcelPackage p) + { + var ws = p.Workbook.Worksheets.Add("FillNumber Samples"); + + ws.SetValue(1, 1, "FillNumber Default"); + ws.SetValue(2, 1, 50); + //Fill the range by adding 1 for each cell starting from the value in the top-left cell. + ws.Cells["A2:A20"].FillNumber(); + + ws.SetValue(1, 2, "FillNumber, Start 30, Step -2"); + //Fill the range by subtracting 2 from the initial value 30. + ws.Cells["B2:B20"].FillNumber(30, -2); + + ws.SetValue(1, 4, "FillNumber, Multiply add 5% row-wise"); + //Fill by starting with 100 and increase 5% for each cell. Fill to the left by row + ws.Cells["E1:AA1"].FillNumber(x => + { + x.CalculationMethod = eCalculationMethod.Multiply; + x.StartValue = 100; + x.StepValue = 1.05; + x.Direction = eFillDirection.Row; + }); + + ws.Cells["A1:D1"].Style.Font.Bold = true; + ws.Cells.AutoFitColumns(); + } + /// + /// Several samples how to use the FillDate method + /// + /// The package + private static void FillDate(ExcelPackage p) + { + var ws = p.Workbook.Worksheets.Add("FillDateTime Samples"); + + //Fill dates starting from the value in the first cell. By default a 1 day increase is assumed and fill is performed per column downwards. + ws.SetValue("A1", "FillDateTime-Default"); + ws.SetValue("A2", new DateTime(2021, 1, 1)); + ws.Cells["A2:A60"].FillDateTime(); + + + ws.SetValue("B1", "FillDateTime-Step two months"); + //Fill dates using the starting value from a fixed start value instead of using the first cell. Increase with 2 months. + ws.Cells["B2:B60"].FillDateTime(new DateTime(2021, 6, 30), eDateTimeUnit.Month, 2); + + ws.Cells[2, 1, 60, 2].Style.Numberformat.Format = "yyyy-mm-dd"; + + ws.SetValue("C1", "FillDateTime-Month, exclude weekends and holidays"); + //Fill dates per last day of the quarter. If the start value is the last day of the month, this is used for all dates in the fill. + //This sample exclude weekends and adds some holiday dates. + //Column C2 and D2 are used as start values. + ws.Cells["C2"].Value = new DateTime(2015, 6, 30); + ws.Cells["D2"].Value = new DateTime(2009, 2, 28); + ws.Cells["C2:D60"].FillDateTime(x => + { + x.DateTimeUnit = eDateTimeUnit.Month; + x.StepValue = 3; + x.NumberFormat = "yyyy-mm-dd"; + x.SetExcludedWeekdays(DayOfWeek.Saturday, DayOfWeek.Sunday); //We exclude weekends. The day before is used instead. + x.SetExcludedDates( //These dates are also excluded. The day before is used instead. + new DateTime(2010, 12, 31), + new DateTime(2012, 12, 31), + new DateTime(2013, 12, 31), + new DateTime(2014, 12, 31), + new DateTime(2015, 12, 31), + new DateTime(2015, 12, 31), + new DateTime(2018, 12, 31), + new DateTime(2019, 12, 31), + new DateTime(2020, 12, 31), + new DateTime(2021, 12, 31), + new DateTime(2024, 12, 31), + new DateTime(2025, 12, 31), + new DateTime(2026, 12, 31), + new DateTime(2027, 12, 31), + new DateTime(2029, 12, 31) + ); + }); + + ws.SetValue("F1", "FillDateTime-By Row from Right-to-Left"); + //You can also fill row-wise and fill right-to-left. + //Note that as row 4 don't have a start value it's left blank in the fill. + //We also set an end value where the fill will stop. + ws.Cells["AA1"].Value = new DateTime(2030, 1, 1); + ws.Cells["AA2"].Value = new DateTime(2030, 1, 5); + ws.Cells["AA4"].Value = new DateTime(2030, 1, 10); + ws.Cells["H1:AA4"].FillDateTime(x => + { + x.Direction = eFillDirection.Row; + x.StartPosition = eFillStartPosition.BottomRight; + x.EndValue = new DateTime(2030, 1, 20); + x.NumberFormat = "yyyy-mm-dd"; + }); + ws.Cells["A1:F1"].Style.Font.Bold = true; + ws.Columns[1, 27].AutoFit(); + + } + /// + /// Several samples how to use the FillList method + /// + /// The package + private static void FillList(ExcelPackage p) + { + var ws = p.Workbook.Worksheets.Add("Fill List Samples"); + + var list = new[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + ws.SetValue("A1", "FillList-Default"); + //FillList repeates the list. Default starts from the first item at position 0 + ws.Cells["A2:A20"].FillList(list); + + ws.SetValue("B1", "FillList-Start index 6"); + //Starts at position 6 in the list + ws.Cells["B2:B20"].FillList(list, x=> { x.StartIndex=6; }); + + ws.SetValue("E1", "FillList-Per row"); + //Fill per row + ws.Cells["F1:AA1"].FillList(list, x => + { + x.Direction = eFillDirection.Row; + }); + + ws.SetValue("C1", "FillList-Primes, bottom up"); + //Fill the list of primes starting from the bottom-up. + //We set the range to the size of the list so it's not repeated. + var primes = new List{ 2,5,7,11,13,17,19,23,29,997,1009 }; + ws.Cells[2,3,primes.Count+1, 3].FillList(primes, x => + { + x.NumberFormat = "#,##0"; + x.StartPosition = eFillStartPosition.BottomRight; + }); + ws.Cells["A1:E1"].Style.Font.Bold = true; + ws.Columns[1, 27].AutoFit(); + } + } +} \ No newline at end of file diff --git a/30-WorkingWithRanges/Readme.md b/30-WorkingWithRanges/Readme.md new file mode 100644 index 0000000..b12a178 --- /dev/null +++ b/30-WorkingWithRanges/Readme.md @@ -0,0 +1,10 @@ +# 30 - Working with ranges +These samples demonstrates how to fill, copy and sort ranges with EPPlus. +- Fill-Demonstrated the different Fill methods: FillNumber, FillDateTime and FillList +- Copy-Shows how to Copy an entire worksheet, copy a range and exclude some cell properties. Also shows how to copy styles. +- Sorting-Contains one example for sorting top to bottom and one for left to right using a custom list. +### [FillRangeSample.cs](FillRangeSample.cs) +### [CopyRangeSample.cs](CopyRangeSample.cs) +### [SortingRangesSample.cs](SortingRangesSample.cs) +--- +[Back to overview](/Readme.md) \ No newline at end of file diff --git a/30-SortingRanges/SortingRangesSample.cs b/30-WorkingWithRanges/SortingRangesSample.cs similarity index 97% rename from 30-SortingRanges/SortingRangesSample.cs rename to 30-WorkingWithRanges/SortingRangesSample.cs index 1c199ce..681ce48 100644 --- a/30-SortingRanges/SortingRangesSample.cs +++ b/30-WorkingWithRanges/SortingRangesSample.cs @@ -27,7 +27,7 @@ public static void Run() // Sort the range left to right by row 0 (using a custom list), then by row 1 sheet2.Cells["A3:K5"].Sort(x => x.SortLeftToRightBy.Row(0).UsingCustomList("S", "M", "L", "XL", "XXL").ThenSortBy.Row(1)); - p.SaveAs(FileOutputUtil.GetFileInfo("30-SortingRanges.xlsx")); + p.SaveAs(FileUtil.GetCleanFileInfo("30-SortingRanges.xlsx")); } } diff --git a/31-HtmlExport/HtmlRangeExportSample.cs b/31-HtmlExport/HtmlRangeExportSample.cs new file mode 100644 index 0000000..46c982d --- /dev/null +++ b/31-HtmlExport/HtmlRangeExportSample.cs @@ -0,0 +1,135 @@ +using OfficeOpenXml; +using OfficeOpenXml.Export.HtmlExport; +using System.Drawing; +using System.IO; +using System.Threading.Tasks; + +namespace EPPlusSamples +{ + public static class HtmlRangeExportSample + { + //This sample demonstrates how to copy entire worksheet, ranges and how to exclude different cell properties. + //More advanced samples using charts and json exports are available in our samples web site available + //here: https://samples.epplussoftware.com/HtmlExport, https://samples.epplussoftware.com/JsonExport + public async static Task RunAsync() + { + var outputFolder = FileUtil.GetDirectoryInfo("HtmlOutput"); + + await ExportGettingStartedAsync(outputFolder); + + ExportSalesReport(outputFolder); + + await ExcludeCssAsync(outputFolder); + + ExportMultipleRanges(outputFolder); + } + + private static async Task ExportGettingStartedAsync(DirectoryInfo outputFolder) + { + //Start by using the excel file generated in sample 8 + using (var p = new ExcelPackage(FileUtil.GetFileInfo("01-GettingStarted.xlsx"))) + { + var ws = p.Workbook.Worksheets["Inventory"]; + //Will create the html exporter for min and max bounds of the worksheet (ws.Dimensions) + var exporter = ws.Cells.CreateHtmlExporter(); + + //Get the html and styles in one call. + var html=await exporter.GetSinglePageAsync(); + await File.WriteAllTextAsync(FileUtil.GetFileInfo(outputFolder, "Range-01-GettingStarted.html", true).FullName, + html); + } + } + + private static void ExportSalesReport(DirectoryInfo outputFolder) + { + //Start by using the excel file generated in sample 8 + using (var p = new ExcelPackage(FileUtil.GetFileInfo("08-Salesreport.xlsx"))) + { + var ws = p.Workbook.Worksheets["Sales"]; + var exporter = ws.Cells.CreateHtmlExporter(); //Will create the html exporter for min and max bounds of the worksheet (ws.Dimensions) + exporter.Settings.HeaderRows = 4; //We have three header rows. + exporter.Settings.TableId = "my-table"; //We can set an id of the worksheet if we want to use it in css or javascript. + + //By default EPPlus include the normal font in the css for the table. This can be tuned off and replaces by your own settings. + exporter.Settings.Css.IncludeNormalFont = false; + //AdditionalCssElements is a collection where you can add your own styles for the table. You can also clear default styles set by EPPlus. + exporter.Settings.Css.AdditionalCssElements.Add("font-family", "verdana"); + + //EPPlus will not set column width and row heights by default, as this doesn't go well with todays responsive designs. + //If you want fixed widths/heights set the proprties below to true... + //Note that individual width and height are set direcly on the colspan-elements and tr-elements. + //Default width and heights are set via the classes epp-dcw and epp-drh (with default StyleClassPrefix.). + exporter.Settings.SetColumnWidth = true; + exporter.Settings.SetRowHeight = true; + + //Get the html... + var htmlTable = exporter.GetHtmlString(); + //...and the styles + var cssTable = exporter.GetCssString(); + + //EPPlus will not add the Excel grid lines, but you can easily add your own in the css... + cssTable += "#my-table th,td {border:solid thin lightgray}"; + + var html = $"{htmlTable}"; + + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Range-02-Salesreport.html", true).FullName, + html); + } + } + private static async Task ExcludeCssAsync(DirectoryInfo outputFolder) + { + //Start by using the excel file generated in sample 20 + using (var p = new ExcelPackage(FileUtil.GetFileInfo("20-CreateAFileSystemReport.xlsx"))) + { + var ws = p.Workbook.Worksheets[0]; + var range = ws.Cells[1, 1, 5, ws.Dimension.End.Column]; + + var exporter = range.CreateHtmlExporter(); + //Css can be excluded on style level, if you don't want some style or you want to add your own. + exporter.Settings.Css.CssExclude.Font = eFontExclude.Bold | eFontExclude.Italic | eFontExclude.Underline; + + var html = await exporter.GetSinglePageAsync(); + await File.WriteAllTextAsync(FileUtil.GetFileInfo(outputFolder, "Range-03-ExcludeCss.html", true).FullName, + html); + } + } + private static void ExportMultipleRanges(DirectoryInfo outputFolder) + { + //Start by using the excel file generated in sample 15 + using (var p = new ExcelPackage(FileUtil.GetFileInfo("15-ChartsAndThemes.xlsx"))) + { + //Now we will use the sample 15 and read two ranges from two different worksheets and combine them to use the same CSS. + //To do so we create an HTML exporter on the workbook level and adds the ranges we want to use. + var ws3D = p.Workbook.Worksheets["3D Charts"]; + var wsStock = p.Workbook.Worksheets["Stock Chart"]; + + //We mark the top and bottom two values with red and green. + ws3D.Cells["B13,B7"].Style.Fill.SetBackground(Color.Green); + ws3D.Cells["B14,B5"].Style.Fill.SetBackground(Color.Red); + + //We mark the top and bottom two rows with red and green. + wsStock.Cells["A3:E4"].Style.Fill.SetBackground(Color.Green); + wsStock.Cells["A7:E8"].Style.Fill.SetBackground(Color.Red); + + var tblChartData = p.Workbook.Worksheets["ChartData"].Tables[0]; + + //Create the exporter. The workbook exporter exports ranges and tables, if the range corresponds to the table range.. + var rngExporter = p.Workbook.CreateHtmlExporter( + ws3D.Cells["A1:D16"], + wsStock.Cells["A1:E11"], + tblChartData.Range); //If you want to export a table, the exact table range must be used. + + //Get the html for the ranges in the HTML. The argument index referece to the ranges supplied when creating the exporter. + var html3D = rngExporter.GetHtmlString(0); + var htmlStock = rngExporter.GetHtmlString(1); + var tblHtml = rngExporter.GetHtmlString(2); + var css = rngExporter.GetCssString(); + + //We also exports a table and merge the css the range css. + var htmlTemplate = "\r\n\r\n\r\n\r\n{1}
{2}
{3}\r\n"; + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Range-04-MultipleRanges.html", true).FullName, + string.Format(htmlTemplate, css, html3D, htmlStock, tblHtml)); + } + } + } +} \ No newline at end of file diff --git a/31-HtmlExport/HtmlTableExportSample.cs b/31-HtmlExport/HtmlTableExportSample.cs new file mode 100644 index 0000000..8ec1692 --- /dev/null +++ b/31-HtmlExport/HtmlTableExportSample.cs @@ -0,0 +1,169 @@ +using OfficeOpenXml; +using OfficeOpenXml.Export.HtmlExport; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace EPPlusSamples +{ + public static class HtmlTableExportSample + { + //This sample demonstrates how to export html from a table. + //More advanced samples using charts and json exports are available in our samples web site available + //here: https://samples.epplussoftware.com/HtmlExport, https://samples.epplussoftware.com/JsonExport + public static void Run() + { + var outputFolder = FileUtil.GetDirectoryInfo("HtmlOutput"); + //Start by using the excel file generated in sample 28 + using (var p = new ExcelPackage(FileUtil.GetFileInfo("28-Tables.xlsx"))) + { + var wsSimpleTable = p.Workbook.Worksheets["SimpleTable"]; + + ExportSimpleTable1(outputFolder, wsSimpleTable); + ExportSimpleTable2(outputFolder, wsSimpleTable); + + var wsStyleTables = p.Workbook.Worksheets["StyleTables"]; + ExportStyleTables(outputFolder, wsStyleTables); + + //This samples exports the filtered table from the slicer sample. + var wsSlicer = p.Workbook.Worksheets["Slicer"]; + ExportSlicerTables1(outputFolder, wsSlicer); + + //Exports three tables and combine the html and css + ExportMultipleTables(outputFolder); + } + } + private static void ExportSimpleTable1(DirectoryInfo outputFolder, ExcelWorksheet wsSimpleTable) + { + var table1 = wsSimpleTable.Tables[0]; + //Create the exporter for the table. + var htmlExporter = table1.CreateHtmlExporter(); + + //EPPlus will minify the css and html by default, but for this sample we want it easier to read. + htmlExporter.Settings.Minify = false; + + // The GetSinglePage method generates en single page. You can also add a string parameter with your own HTML where where the styles and table html is inserted. + var fullHtml = htmlExporter.GetSinglePage(); + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-01-Table1_SinglePage.html", true).FullName, + fullHtml); + + //In most cases you want to keep the html and the styles separated, so you will retrive the html and the css in separate calls... + var tableHtml = htmlExporter.GetHtmlString(); + var tableCss = htmlExporter.GetCssString(); + + //First create the html file and reference the the css. + var html = $"{tableHtml}"; + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-01-Table1.html", true).FullName, + html); + + //The css is written to a separate file. + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-01-Table1.css", true).FullName, tableCss); + } + private static void ExportSimpleTable2(DirectoryInfo outputFolder, ExcelWorksheet wsSimpleTable) + { + var table2 = wsSimpleTable.Tables[1]; + + //Create the exporter for the table. + var htmlExporter = table2.CreateHtmlExporter(); + //EPPlus will generate Accessibility and data attributes by default, but you can turn it of in the settings. + htmlExporter.Settings.Accessibility.TableSettings.AddAccessibilityAttributes = false; + htmlExporter.Settings.RenderDataAttributes = false; + + var html = htmlExporter.GetSinglePage(); + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-02-Table2.html", true).FullName, + html); + + //We can also change the table style to get a different styling. + //Here we change to Medium15... + table2.TableStyle = OfficeOpenXml.Table.TableStyles.Medium15; + html = htmlExporter.GetSinglePage(); + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-02-table2_Medium15.html", true).FullName, + html); + + //...Here we use Dark2... + table2.TableStyle = OfficeOpenXml.Table.TableStyles.Dark2; + html = htmlExporter.GetSinglePage(); + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-02-table2_Dark2.html", true).FullName, + html); + } + + private static void ExportStyleTables(DirectoryInfo outputFolder, ExcelWorksheet wsStyleTables) + { + //The last row of the cell contains uncalculated cell (they calculate when opened in Excel), + //but in EPPlus we need to calculate them first to get a result in cell A254 in the totals row. + wsStyleTables.Calculate(); + + var table1 = wsStyleTables.Tables[0]; + var htmlExporter = table1.CreateHtmlExporter(); + + //This sample exports the table as well as some individually cell styles. The headers have font italic and the totals row has a custom formatted text. + //Also note that Column 2 has hyper links create for the mail addresses. + var html = htmlExporter.GetSinglePage(); + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-02-Styling_table1_with_hyperlinks.html", true).FullName, + html); + + var table2 = wsStyleTables.Tables[1]; + htmlExporter = table2.CreateHtmlExporter(); + + //Table 2 contains a custom table style. + html = htmlExporter.GetSinglePage(); + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-02-Styling_table2.html", true).FullName, + html); + } + private static void ExportSlicerTables1(DirectoryInfo outputFolder, ExcelWorksheet wsSlicer) + { + var table1 = wsSlicer.Tables[0]; + var htmlExporter = table1.CreateHtmlExporter(); + + //This sample exports the table filtered by the selection in the slicer (that applies the filter on the table). + //By default EPPlus will remove hidden rows. + var html = htmlExporter.GetSinglePage(); + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-03-Slicer.html", true).FullName, + html); + + //You can change this option by setting eHiddenState.Include in the settings. + //You can also set the it to eHiddenState.IncludeButHide if you want to apply your own filtering. + htmlExporter.Settings.HiddenRows = eHiddenState.Include; + html = htmlExporter.GetSinglePage(); + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-03-Slicer_table_all_rows.html", true).FullName, + html); + } + private static void ExportMultipleTables(DirectoryInfo outputFolder) + { + using (var p = new ExcelPackage(FileUtil.GetFileInfo("04-LoadingData.xlsx"))) + { + //Now we will use the third worksheet from sample 4, that contains three tables with different styles. + var wsList = p.Workbook.Worksheets["FromList"]; + + var tbl1 = wsList.Tables[0]; + var exporter1 = tbl1.CreateHtmlExporter(); + var tbl1Html = exporter1.GetHtmlString(); + var tbl1Css = exporter1.GetCssString(); + + var tbl2 = wsList.Tables[1]; + var exporter2 = tbl2.CreateHtmlExporter(); + var tbl2Html = exporter2.GetHtmlString(); + //We have already exported the css once, so we don't want shared css classes to be added again. + exporter2.Settings.Css.IncludeSharedClasses = false; + var tbl2Css = exporter2.GetCssString(); + + var tbl3 = wsList.Tables[2]; + var exporter3 = tbl3.CreateHtmlExporter(); + var tbl3Html = exporter3.GetHtmlString(); + exporter3.Settings.Css.IncludeSharedClasses = false; + + var tbl3Css = exporter3.GetCssString(); + + //As the tables have different table styles we add all of the css's. + //If multiple tables have the same table style, you should only add one of them. + var css = tbl1Css + tbl2Css + tbl3Css; + + var htmlTemplate = "\r\n\r\n\r\n\r\n{1}
{2}
{3}\r\n"; + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "Table-04-MultipleTables.html", true).FullName, + string.Format(htmlTemplate, css, tbl1Html, tbl2Html, tbl3Html)); + } + } + + } +} \ No newline at end of file diff --git a/31-HtmlExport/Readme.md b/31-HtmlExport/Readme.md new file mode 100644 index 0000000..7208216 --- /dev/null +++ b/31-HtmlExport/Readme.md @@ -0,0 +1,11 @@ +# 31 - Html export from ranges and tables +These samples demonstrates Export ranges and tables as HTML in EPPlus. +EPPlus supports exporting cell values, styles, and hyper links as html. +EPPlus also exports tables with there selected table style, both build-in table styles and custom table styles are supported. +More advanced samples using charts and json exports are available in our samples web site available +here: https://samples.epplussoftware.com/HtmlExport, https://samples.epplussoftware.com/JsonExport + +### [HtmlTableExportSample.cs](HtmlTableExportSample.cs) +### [HtmlRangeExportSample.cs](HtmlRangeExportSample.cs) +--- +[Back to overview](/Readme.md) \ No newline at end of file diff --git a/32-JsonExport/JsonExportSample.cs b/32-JsonExport/JsonExportSample.cs new file mode 100644 index 0000000..925bb3d --- /dev/null +++ b/32-JsonExport/JsonExportSample.cs @@ -0,0 +1,66 @@ +using OfficeOpenXml; +using System.IO; +using System.Threading.Tasks; + +namespace EPPlusSamples +{ + public static class JsonExportSample + { + //This sample demonstrates how to export html from a table. + //More advanced samples using charts and json exports are available in our samples web site available + //here: https://samples.epplussoftware.com/JsonExport + public static async Task RunAsync() + { + var outputFolder = FileUtil.GetDirectoryInfo("JsonOutput"); + + //Start by using the excel file generated in sample 28 + using (var p = new ExcelPackage(FileUtil.GetFileInfo("28-Tables.xlsx"))) + { + var wsSimpleTable = p.Workbook.Worksheets["SimpleTable"]; + + ExportTable1(outputFolder, wsSimpleTable); + + var wsStyleTables = p.Workbook.Worksheets["StyleTables"]; + await ExportTableWithHyperlink(outputFolder, wsStyleTables); + } + } + + private static void ExportTable1(DirectoryInfo outputFolder, ExcelWorksheet wsSimpleTable) + { + var table1 = wsSimpleTable.Tables[0]; + + //First export the table directly from the table object. + //When exporting a table the data type is set on the column. + var json = table1.ToJson(x => + { + x.Minify = false; + }); + + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "TableSample1_As_Table.json", true).FullName, json); + + //When exporting the range data types are set on the cell level. + //You can alter this by AddDataTypesOn, --> x.AddDataTypesOn=eDataTypeOn.OnColumn + json = table1.Range.ToJson(x => + { + x.Minify = false; + }); + + File.WriteAllText(FileUtil.GetFileInfo(outputFolder, "TableSample1_As_Range.json", true).FullName, json); + } + private static async Task ExportTableWithHyperlink(DirectoryInfo outputFolder, ExcelWorksheet wsStyleTables) + { + var table1 = wsStyleTables.Tables[0]; + + + using (var fs = new FileStream(FileUtil.GetFileInfo(outputFolder, "TableSample2_hyperlinks.json", true).FullName, FileMode.Create, FileAccess.Write)) + { + await table1.SaveToJsonAsync(fs, x => + { + x.AddDataTypesOn = eDataTypeOn.NoDataTypes; //Skip data types. + x.Minify = false; + }); + fs.Close(); + } + } + } +} \ No newline at end of file diff --git a/32-JsonExport/Readme.md b/32-JsonExport/Readme.md new file mode 100644 index 0000000..66dcb67 --- /dev/null +++ b/32-JsonExport/Readme.md @@ -0,0 +1,7 @@ +# 32 - Json export +This samples demonstrates Export ranges and tables as json in EPPlus. +Json export for ranges and table looks slightly different. +EPPlus also exports tables with there selected table style, both build-in table styles and custom table styles are supported. +### [JsonExportSample.cs](JsonExportSample.cs) +--- +[Back to overview](/Readme.md) \ No newline at end of file diff --git a/33-ToCollection/Readme.md b/33-ToCollection/Readme.md new file mode 100644 index 0000000..65f8611 --- /dev/null +++ b/33-ToCollection/Readme.md @@ -0,0 +1,6 @@ +# 33 - ToCollection and ToCollectionWithMappings +This samples demonstrates Export ranges and tables into an IEnumerable<T> where T is a class type. +### [ToCollectionSample.cs](ToCollectionSample.cs) +### [ToCollectionClasses.cs](ToCollectionClasses.cs) (sample data) +--- +[Back to overview](/Readme.md) diff --git a/33-ToCollection/ToCollectionClasses.cs b/33-ToCollection/ToCollectionClasses.cs new file mode 100644 index 0000000..7914624 --- /dev/null +++ b/33-ToCollection/ToCollectionClasses.cs @@ -0,0 +1,90 @@ +using OfficeOpenXml.Attributes; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EPPlusSamples +{ + public class ToCollectionSamplePerson + { + public ToCollectionSamplePerson() + { + + } + + public ToCollectionSamplePerson(string firstName, string lastName, int height, DateTime birthDate) + { + FirstName = firstName; + LastName = lastName; + Height = height; + BirthDate = birthDate; + } + + public string FirstName { get; set; } + + public string LastName { get; set; } + + public int Height { get; set; } + + public DateTime BirthDate { get; set; } + } + + public class ToCollectionSamplePersonAttr + { + public ToCollectionSamplePersonAttr() + { + + } + + public ToCollectionSamplePersonAttr(string firstName, string lastName, int height, DateTime birthDate) + { + FirstName = firstName; + LastName = lastName; + Height = height; + BirthDate = birthDate; + } + + [DisplayName("The persons first name")] + public string FirstName { get; set; } + + [Description("The persons last name")] + public string LastName { get; set; } + + [EpplusTableColumn(Header ="Height of the person")] + public int Height { get; set; } + + public DateTime BirthDate { get; set; } + } + + public static class ToCollectionSampleData + { + public static IEnumerable Persons + { + get + { + return new List + { + new ToCollectionSamplePerson("John", "Doe", 176, new DateTime(1978, 3, 15)), + new ToCollectionSamplePerson("Sven", "Svensson", 183, new DateTime(1995, 11, 3)), + new ToCollectionSamplePerson("Jane", "Doe", 168, new DateTime(1989, 2, 26)) + }; + } + } + + public static IEnumerable PersonsWithAttributes + { + get + { + return new List + { + new ToCollectionSamplePersonAttr("John", "Doe", 176, new DateTime(1978, 3, 15)), + new ToCollectionSamplePersonAttr("Sven", "Svensson", 183, new DateTime(1995, 11, 3)), + new ToCollectionSamplePersonAttr("Jane", "Doe", 168, new DateTime(1989, 2, 26)) + }; + } + } + } +} diff --git a/33-ToCollection/ToCollectionSample.cs b/33-ToCollection/ToCollectionSample.cs new file mode 100644 index 0000000..bd860d7 --- /dev/null +++ b/33-ToCollection/ToCollectionSample.cs @@ -0,0 +1,140 @@ +using OfficeOpenXml; +using OfficeOpenXml.Table; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EPPlusSamples +{ + public static class ToCollectionSample + { + public static void Run() + { + using(var package = new ExcelPackage()) + { + var ws = package.Workbook.Worksheets.Add("Persons"); + // Load the sample data into the worksheet + var range = ws.Cells["A1"].LoadFromCollection(ToCollectionSampleData.Persons, options => + { + options.PrintHeaders = true; + options.TableStyle = TableStyles.Dark1; + }); + + /********************************************************** + * ToCollection. Automaps cell data to class instance * + **********************************************************/ + + Console.WriteLine("******* Sample 33 - ToCollection ********\n"); + + // export the data loaded into the worksheet above to a collection + var exportedPersons = range.ToCollection(); + + foreach(var person in exportedPersons) + { + Console.WriteLine("***************************"); + Console.WriteLine($"Name: {person.FirstName} {person.LastName}"); + Console.WriteLine($"Height: {person.Height} cm"); + Console.WriteLine($"Birthdate: {person.BirthDate.ToShortDateString()}"); + } + + Console.WriteLine(); + + /********************************************************** + * ToCollectionWithMappings. Use this method to manually * + * map all or just some of the cells to your class. * + **********************************************************/ + + Console.WriteLine("******* Sample 33 - ToCollectionWithMappings ********\n"); + + var exportedPersons2 = ws.Cells["A1:D4"].ToCollectionWithMappings( + row => + { + // this runs once per row in the range + + // Create an instance of the exported class + var person = new ToCollectionSamplePerson(); + + // If some of the cells can be automapped, start by automapping the row data to the class + row.Automap(person); + + // Note that you can only use column names as below + // if options.HeaderRow is set to the 0-based row index + // of the header row. + person.FirstName = row.GetValue("FirstName"); + + // get value by the 0-based column index + person.Height = row.GetValue(2); + + // return the class instance + return person; + }, + options => options.HeaderRow = 0); + + foreach (var person in exportedPersons2) + { + Console.WriteLine("***************************"); + Console.WriteLine($"Name: {person.FirstName} {person.LastName}"); + Console.WriteLine($"Height: {person.Height} cm"); + Console.WriteLine($"Birthdate: {person.BirthDate.ToShortDateString()}"); + } + + Console.WriteLine(); + + /********************************************************** + * ToCollection. Using property attributes for mappings, * + * see the ToCollectionSamplePersonAttr class * + **********************************************************/ + + // Load the sample data into a new worksheet + var ws2 = package.Workbook.Worksheets.Add("Ws2"); + var range2 = ws2.Cells["A1"].LoadFromCollection(ToCollectionSampleData.PersonsWithAttributes, options => + { + options.PrintHeaders = true; + options.TableStyle = TableStyles.Dark1; + }); + + Console.WriteLine("******* Sample 33 - ToCollection using attributes ********\n"); + + // export the data loaded into the worksheet above to a collection + var exportedPersons3 = range2.ToCollection(); + + foreach (var person in exportedPersons3) + { + Console.WriteLine("***************************"); + Console.WriteLine($"Name: {person.FirstName} {person.LastName}"); + Console.WriteLine($"Height: {person.Height} cm"); + Console.WriteLine($"Birthdate: {person.BirthDate.ToShortDateString()}"); + } + + Console.WriteLine(); + + /********************************************************** + * ToCollection from a table * + **********************************************************/ + Console.WriteLine("******* Sample 33 - ToCollection from a table ********\n"); + // Load the sample data a new worksheet + var ws3 = package.Workbook.Worksheets.Add("Ws3"); + var tableRange = ws3.Cells["A1"].LoadFromCollection(ToCollectionSampleData.Persons, options => + { + options.PrintHeaders = true; + options.TableStyle = TableStyles.Dark1; + }); + var table = ws3.Tables.GetFromRange(tableRange); + // export the data loaded into the worksheet above to a collection + var exportedPersons4 = table.ToCollection(); + + foreach (var person in exportedPersons4) + { + Console.WriteLine("***************************"); + Console.WriteLine($"Name: {person.FirstName} {person.LastName}"); + Console.WriteLine($"Height: {person.Height} cm"); + Console.WriteLine($"Birthdate: {person.BirthDate.ToShortDateString()}"); + } + + Console.WriteLine(); + } + } + } +} diff --git a/EPPlusSampleApp.Core.csproj b/EPPlusSampleApp.Core.csproj index 9e2ad9c..02b5d17 100644 --- a/EPPlusSampleApp.Core.csproj +++ b/EPPlusSampleApp.Core.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net6.0 EPPlusSamples @@ -15,11 +15,11 @@ - - + + - - + + diff --git a/EPPlusSampleApp.Core.sln b/EPPlusSampleApp.Core.sln index 37b416a..836ded2 100644 --- a/EPPlusSampleApp.Core.sln +++ b/EPPlusSampleApp.Core.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29709.97 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31912.275 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EPPlusSampleApp.Core", "EPPlusSampleApp.Core.csproj", "{68677B2E-EA58-4EA5-88CC-479E0B2B286C}" EndProject diff --git a/FileInputUtil.cs b/FileInputUtil.cs deleted file mode 100644 index ae7a087..0000000 --- a/FileInputUtil.cs +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************************************* - Required Notice: Copyright (C) EPPlus Software AB. - This software is licensed under PolyForm Noncommercial License 1.0.0 - and may only be used for noncommercial purposes - https://polyformproject.org/licenses/noncommercial/1.0.0/ - - A commercial license to use this software can be purchased at https://epplussoftware.com - ************************************************************************************************* - Date Author Change - ************************************************************************************************* - 01/27/2020 EPPlus Software AB Initial release EPPlus 5 - *************************************************************************************************/using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace EPPlusSamples -{ - public class FileInputUtil - { - - /// - /// Returns a fileinfo with the full path of the requested file - /// - /// A subdirectory - /// - /// - public static FileInfo GetFileInfo(string directory, string file) - { - var rootDir = GetRootDirectory().FullName; - return new FileInfo(Path.Combine(rootDir, directory, file)); - } - - public static DirectoryInfo GetRootDirectory() - { - var currentDir = AppDomain.CurrentDomain.BaseDirectory; - while (!currentDir.EndsWith("bin")) - { - currentDir = Directory.GetParent(currentDir).FullName.TrimEnd('\\'); - } - return new DirectoryInfo(currentDir).Parent; - } - - public static DirectoryInfo GetSubDirectory(string directory, string subDirectory) - { - var currentDir = GetRootDirectory().FullName; - return new DirectoryInfo(Path.Combine(currentDir, directory, subDirectory)); - } - } -} diff --git a/FileOutputUtil.cs b/FileUtil.cs similarity index 61% rename from FileOutputUtil.cs rename to FileUtil.cs index 7082ac0..00534fc 100644 --- a/FileOutputUtil.cs +++ b/FileUtil.cs @@ -10,10 +10,11 @@ Date Author Change ************************************************************************************************* 01/27/2020 EPPlus Software AB Initial release EPPlus 5 *************************************************************************************************/ +using System; using System.IO; namespace EPPlusSamples { - public class FileOutputUtil + public class FileUtil { static DirectoryInfo _outputDir = null; public static DirectoryInfo OutputDir @@ -31,15 +32,20 @@ public static DirectoryInfo OutputDir } } } - public static FileInfo GetFileInfo(string file, bool deleteIfExists = true) + public static FileInfo GetCleanFileInfo(string file) { var fi = new FileInfo(OutputDir.FullName + Path.DirectorySeparatorChar + file); - if (deleteIfExists && fi.Exists) + if (fi.Exists) { fi.Delete(); // ensures we create a new workbook } return fi; - } + } + public static FileInfo GetFileInfo(string file) + { + return new FileInfo(OutputDir.FullName + Path.DirectorySeparatorChar + file); + } + public static FileInfo GetFileInfo(DirectoryInfo altOutputDir, string file, bool deleteIfExists = true) { var fi = new FileInfo(altOutputDir.FullName + Path.DirectorySeparatorChar + file); @@ -60,5 +66,32 @@ internal static DirectoryInfo GetDirectoryInfo(string directory) } return di; } + /// + /// Returns a fileinfo with the full path of the requested file + /// + /// A subdirectory + /// + /// + public static FileInfo GetFileInfo(string directory, string file) + { + var rootDir = GetRootDirectory().FullName; + return new FileInfo(Path.Combine(rootDir, directory, file)); + } + + public static DirectoryInfo GetRootDirectory() + { + var currentDir = AppDomain.CurrentDomain.BaseDirectory; + while (!currentDir.EndsWith("bin")) + { + currentDir = Directory.GetParent(currentDir).FullName.TrimEnd('\\'); + } + return new DirectoryInfo(currentDir).Parent; + } + + public static DirectoryInfo GetSubDirectory(string directory, string subDirectory) + { + var currentDir = GetRootDirectory().FullName; + return new DirectoryInfo(Path.Combine(currentDir, directory, subDirectory)); + } } } diff --git a/Readme.md b/Readme.md index 644cbed..ca07bb5 100644 --- a/Readme.md +++ b/Readme.md @@ -1,4 +1,5 @@ -# EPPlus samples +## This sample project is for EPPlus 6, a newer sample for EPPlus 7 is available here... [C#](https://github.com/EPPlusSoftware/EPPlus.Samples.CSharp) or [VB](https://github.com/EPPlusSoftware/EPPlus.Samples.VB) +## EPPlus samples ### EPPlus samples for .Net Core @@ -32,7 +33,7 @@ dotnet run |17|[FX report](/17-FXReportFromDatabase/)|Exchange rates report with data from a SQL database. Demonstrates some of the chart capabilities of EPPlus| |18|[Pivot tables](/18-PivotTables/)|Demonstrates the Pivot table functionality of EPPlus.| |19|[Encryption and protection](/19-EncryptionAndProtection/)|This sample produces a quiz, where the template workbook is encrypted and password protected.| -|20|[Create filesystem report](/20-CreateFileSystemReport/)|Demonstrates usage of styling, printer settings, rich text, pie-, doughnut- and bar-charts, freeze panes| +|20|[Create filesystem report](/20-CreateFileSystemReport/)|Demonstrates usage of styling, printer settings, rich text, pie-, doughnut- and bar-charts, freeze panes and row/column outlines| |21|[VBA - Visual Basic for Applications](/21-VBA/)|Demonstrates EPPlus support for VBA, includes a battleship game| |22|[Ignore errors](/22-IgnoreErrors/)|Various samples on how to ignore error on cells.| |23|[Comments](/23-Comments/)|Sample showing how to add notes and threaded comments.| @@ -42,26 +43,12 @@ dotnet run |27|[Custom styles for tables and slicers](/27-CustomNamedStyles)|Sample showing how to create custom styles from tables, pivot tables and slicers. |28|[Tables](/28-Tables)|Sample showing how to work with tables. |29|[External links](/29-ExternalLinks)|Shows how to work with links to external workbooks -|30|[Sorting Ranges](/30-SortingRanges)|Shows how to work with the Sort method for ranges and tables +|30|[Sorting Ranges](/30-WorkingWithRanges)|Shows how to work with the Sort method for ranges and tables +|31|[Html Export](/31-HtmlExport)|Shows how to export tables and ranges to HTML +|32|[Json Export](/32-JsonExport)|Shows how to export tables and ranges to JSON +|33|[ToCollection](/33-ToCollection)|Shows how to export data from worksheets and tables into an IEnumerable<T> where T is a class. ### Output files The samples above produces some workbooks - the name of each workbook indicates which sample that generated it. These workbooks are located in a subdirectory - named "SampleApp" - to the output directory of the sample project. - -### Non windows operating systems. -Non-windows operating systems will requires libgdiplus to be installed. -Please use your favorite package manager to install it. -For example: - -Homebrew on MacOS: -``` -brew install mono-libgdiplus -``` - -apt-get: -``` -apt-get install libgdiplus -``` -For Docker, see our [Docker file samples]( https://github.com/EPPlusSoftware/EPPlus/wiki/EPPlus-and-Docker) - Also see wiki on https://github.com/EPPlusSoftware/EPPlus/wiki for more details diff --git a/Sample_Main.cs b/Sample_Main.cs index b99a429..93eb438 100644 --- a/Sample_Main.cs +++ b/Sample_Main.cs @@ -36,7 +36,7 @@ static async Task Main(string[] args) { try { - //EPPlus 5 uses a dual licens model. This requires you to specifiy the License you are using to be able to use the library. + //EPPlus 5 uses a dual license model. This requires you to specifiy the License you are using to be able to use the library. //This sample sets the LicenseContext in the appsettings.json file. An alternative is the commented row below. //ExcelPackage.LicenseContext = LicenseContext.NonCommercial; //See https://epplussoftware.com/Developers/LicenseException for more info. @@ -44,7 +44,7 @@ static async Task Main(string[] args) string connectionStr = "Data Source=EPPlusSample.sqlite;Version=3;"; //Set the output directory to the SampleApp folder where the app is running from. - FileOutputUtil.OutputDir = new DirectoryInfo($"{AppDomain.CurrentDomain.BaseDirectory}SampleApp"); + FileUtil.OutputDir = new DirectoryInfo($"{AppDomain.CurrentDomain.BaseDirectory}SampleApp"); // Sample 1 - Simply creates a new workbook from scratch // containing a worksheet that adds a few numbers together @@ -62,21 +62,21 @@ static async Task Main(string[] args) //Sample 3 - Load and save using async methods Console.WriteLine("Running sample 3-Async-Await"); await UsingAsyncAwaitSample.RunAsync(connectionStr); - Console.WriteLine("Sample 3 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 3 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 4 - Shows a few ways to load data (Datatable, IEnumerable and more). Console.WriteLine("Running sample 4 - LoadingDataWithTables"); LoadingDataWithTablesSample.Run(); - Console.WriteLine("Sample 4 (LoadingDataWithTables) created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 4 (LoadingDataWithTables) created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 4 - Shows how to load dynamic/ExpandoObject LoadingDataWithDynamicObjects.Run(); - Console.WriteLine("Sample 4 (LoadingDataWithDynamicObjects) created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 4 (LoadingDataWithDynamicObjects) created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); // Sample 4 - LoadFromCollectionWithAttributes LoadingDataFromCollectionWithAttributes.Run(); - Console.WriteLine("Sample 4 (LoadingDataFromCollectionWithAttributes) created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 4 (LoadingDataFromCollectionWithAttributes) created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 5 Loads two csv files into tables and creates an area chart and a Column/Line chart on the data. @@ -89,7 +89,7 @@ static async Task Main(string[] args) //Sample 6 Calculate - Shows how to calculate formulas in the workbook. Console.WriteLine("Sample 6 - Calculate formulas"); CalculateFormulasSample.Run(); - Console.WriteLine("Sample 6 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 6 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 7 @@ -123,7 +123,7 @@ static async Task Main(string[] args) //Sample 11 - Conditional Formatting Console.WriteLine("Running sample 11"); ConditionalFormatting.Run(); - Console.WriteLine("Sample 11 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 11 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 12 - Data validation @@ -135,32 +135,32 @@ static async Task Main(string[] args) //Sample 13 - Filter Console.WriteLine("Running sample 13-Filter"); await Filter.RunAsync(connectionStr); - Console.WriteLine("Sample 13 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 13 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 14 - Shapes & Images Console.WriteLine("Running sample 14-Shapes & Images"); ShapesAndImagesSample.Run(); - Console.WriteLine("Sample 14 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 14 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 15 - Themes and Chart styling Console.WriteLine("Running sample 15-Theme and Chart styling"); //Run the sample with the default office theme await ChartsAndThemesSample.RunAsync(connectionStr, - FileOutputUtil.GetFileInfo("15-ChartsAndThemes.xlsx"), null); + FileUtil.GetFileInfo("15-ChartsAndThemes.xlsx"), null); //Run the sample with the integral theme. Themes can be exported as thmx files from Excel and can then be applied to a package. await ChartsAndThemesSample.RunAsync(connectionStr, - FileOutputUtil.GetFileInfo("15-ChartsAndThemes-IntegralTheme.xlsx"), - FileInputUtil.GetFileInfo("15-ChartsAndThemes", "integral.thmx")); - Console.WriteLine("Sample 15 created {0}", FileOutputUtil.OutputDir.Name); + FileUtil.GetFileInfo("15-ChartsAndThemes-IntegralTheme.xlsx"), + FileUtil.GetFileInfo("15-ChartsAndThemes", "integral.thmx")); + Console.WriteLine("Sample 15 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 16 - Shows how to add sparkline charts. Console.WriteLine("Running sample 16-Sparklines"); SparkLinesSample.Run(); - Console.WriteLine("Sample 16 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 16 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); // Sample 17 - Creates a workbook based on a template. @@ -182,7 +182,7 @@ await ChartsAndThemesSample.RunAsync(connectionStr, //Sample 19 Swedish Quiz : Shows Encryption, workbook- and worksheet protection. Console.WriteLine("Running sample 19"); DrawingsSample.Run(); - Console.WriteLine("Sample 19 created: {0}", FileOutputUtil.OutputDir.FullName); + Console.WriteLine("Sample 19 created: {0}", FileUtil.OutputDir.FullName); Console.WriteLine(); //Sample 20 @@ -194,28 +194,29 @@ await ChartsAndThemesSample.RunAsync(connectionStr, Console.WriteLine("Sample 20 created:", output); Console.WriteLine(); - //Sample 21 - Shows how to work with macro-enabled workbooks(VBA). + //Sample 21 - Shows how to work with macro-enabled workbooks(VBA) and how to sign the code with a certificate. Console.WriteLine("Running sample 21-VBA"); WorkingWithVbaSample.Run(); - Console.WriteLine("Sample 21 created {0}", FileOutputUtil.OutputDir.Name); + SigningYourVBAProject.Run(); + Console.WriteLine("Sample 21 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 22 - Ignore cell errors using the IngnoreErrors Collection Console.WriteLine("Running sample 22-Suppress Errors"); IgnoreErrorsSample.Run(); - Console.WriteLine("Sample 22 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 22 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 23 - Comments and Threaded comments Console.WriteLine("Running sample 23-Comments/Notes and Threaded Comments"); CommentsSample.Run(); - Console.WriteLine("Sample 23 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 23 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 24 - Table slicers and Pivot table slicers Console.WriteLine("Running sample 24-Table and Pivot Table Slicers"); SlicerSample.Run(connectionStr); - Console.WriteLine("Sample 24 created {0}", FileOutputUtil.OutputDir.Name); + Console.WriteLine("Sample 24 created {0}", FileUtil.OutputDir.Name); Console.WriteLine(); //Sample 25 - Import and Export DataTable @@ -250,11 +251,39 @@ await ChartsAndThemesSample.RunAsync(connectionStr, Console.WriteLine("Sample 29 finished."); Console.WriteLine(); - // Sample 30 - Sort ranges - Console.WriteLine("Running sample 30 - Sort ranges"); + // Sample 30 - Working with ranges + Console.WriteLine("Running sample 30 - Working with ranges"); + CopyRangeSample.Run(); + FillRangeSample.Run(); SortingRangesSample.Run(); Console.WriteLine("Sample 30 finished."); Console.WriteLine(); + + // Sample 31 - Html Export + //This sample shows basic html export functionality. + //For more advanced samples using charts see https://samples.epplussoftware.com/HtmlExport + Console.WriteLine("Running sample 31 - Html export"); + HtmlTableExportSample.Run(); + await HtmlRangeExportSample.RunAsync(); + Console.WriteLine("Sample 31 finished."); + Console.WriteLine(); + + //Sample 32 - Json Export + //This sample shows the json export functionality. + //For more a samples exporting to chart librays see https://samples.epplussoftware.com/JsonExport + Console.WriteLine("Running sample 32 - json export"); + await JsonExportSample.RunAsync(); + Console.WriteLine("Sample 32 finished."); + Console.WriteLine(); + + // Sample 33 - ToCollection and ToCollectionWithMappings + // This sample shows how to export data from a worksheet + // to a IEnumerable where T is a class. + Console.WriteLine("Running sample 33 - ToCollection and ToCollectionWithMappings"); + ToCollectionSample.Run(); + Console.WriteLine("Sample 33 finished."); + Console.WriteLine(); + } catch (Exception ex) { @@ -262,7 +291,7 @@ await ChartsAndThemesSample.RunAsync(connectionStr, } var prevColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine($"Genereted sample workbooks can be found in {FileOutputUtil.OutputDir.FullName}"); + Console.WriteLine($"Genereted sample workbooks can be found in {FileUtil.OutputDir.FullName}"); Console.ForegroundColor = prevColor; Console.WriteLine();