diff --git a/FileFormat.Cells.sln b/FileFormat.Cells.sln index 168c736..fdd15dc 100644 --- a/FileFormat.Cells.sln +++ b/FileFormat.Cells.sln @@ -1,24 +1,29 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 25.0.1705.6 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34607.119 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileFormat.Cells", "FileFormat.Cells\FileFormat.Cells.csproj", "{347E8540-1317-4E99-BF8A-A16A04E753BB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileFormat.Cells", "FileFormat.Cells\FileFormat.Cells.csproj", "{347E8540-1317-4E99-BF8A-A16A04E753BB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileFormat.Cells_Tests", "FileFormat.Cells_Tests\FileFormat.Cells_Tests.csproj", "{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileFormat.Cells_Tests", "FileFormat.Cells_Tests\FileFormat.Cells_Tests.csproj", "{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + netcore3.1|Any CPU = netcore3.1|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {347E8540-1317-4E99-BF8A-A16A04E753BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {347E8540-1317-4E99-BF8A-A16A04E753BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {347E8540-1317-4E99-BF8A-A16A04E753BB}.netcore3.1|Any CPU.ActiveCfg = netcore3.1|Any CPU + {347E8540-1317-4E99-BF8A-A16A04E753BB}.netcore3.1|Any CPU.Build.0 = netcore3.1|Any CPU {347E8540-1317-4E99-BF8A-A16A04E753BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {347E8540-1317-4E99-BF8A-A16A04E753BB}.Release|Any CPU.Build.0 = Release|Any CPU {A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.netcore3.1|Any CPU.ActiveCfg = netcore3.1|Any CPU + {A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.netcore3.1|Any CPU.Build.0 = netcore3.1|Any CPU {A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.Release|Any CPU.ActiveCfg = Release|Any CPU {A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection diff --git a/FileFormat.Cells/Cell.cs b/FileFormat.Cells/Cell.cs index a4dd1b8..a365eef 100644 --- a/FileFormat.Cells/Cell.cs +++ b/FileFormat.Cells/Cell.cs @@ -2,12 +2,16 @@ using DocumentFormat.OpenXml; using System.Globalization; using DocumentFormat.OpenXml.Spreadsheet; +using DocumentFormat.OpenXml.Packaging; namespace FileFormat.Cells { public sealed class Cell { + private readonly DocumentFormat.OpenXml.Spreadsheet.Cell _cell; + private readonly WorkbookPart _workbookPart; + private readonly SheetData _sheetData; /// @@ -23,10 +27,11 @@ public sealed class Cell /// /// Thrown when or is null. /// - public Cell(DocumentFormat.OpenXml.Spreadsheet.Cell cell, SheetData sheetData) + public Cell(DocumentFormat.OpenXml.Spreadsheet.Cell cell, SheetData sheetData, WorkbookPart workbookPart) { _cell = cell ?? throw new ArgumentNullException(nameof(cell)); _sheetData = sheetData ?? throw new ArgumentNullException(nameof(sheetData)); + _workbookPart = workbookPart ?? throw new ArgumentNullException(nameof(workbookPart)); } /// @@ -82,9 +87,20 @@ public void PutFormula(string formula) /// Gets the value of the cell. /// /// The cell value as a string. - public string GetValue() - { - return _cell.CellValue?.Text; + public string GetValue() + { + if (_cell == null || _cell.CellValue == null) return ""; + + if (_cell.DataType != null && _cell.DataType.Value == CellValues.SharedString) + { + int index = int.Parse(_cell.CellValue.Text); + SharedStringTablePart sharedStrings = _workbookPart.SharedStringTablePart; + return sharedStrings.SharedStringTable.ElementAt(index).InnerText; + } + else + { + return _cell.CellValue.Text; + } } /// diff --git a/FileFormat.Cells/FileFormat.Cells.csproj b/FileFormat.Cells/FileFormat.Cells.csproj index dbf4e0d..2f6f421 100644 --- a/FileFormat.Cells/FileFormat.Cells.csproj +++ b/FileFormat.Cells/FileFormat.Cells.csproj @@ -1,14 +1,27 @@ - + Exe netcoreapp3.1 - 10.0 + enable enable + Debug;Release;netcore3.1 - + + + + + + AnyCPU + + + 10.0 + + + + - + \ No newline at end of file diff --git a/FileFormat.Cells/Image.cs b/FileFormat.Cells/Image.cs index 1fbf54f..4a27e02 100644 --- a/FileFormat.Cells/Image.cs +++ b/FileFormat.Cells/Image.cs @@ -6,7 +6,9 @@ using A14 = DocumentFormat.OpenXml.Office2010.Drawing; using DocumentFormat.OpenXml.Spreadsheet; using System.Linq; - +using System.IO; +using System; + namespace FileFormat.Cells { diff --git a/FileFormat.Cells/ImageHandler.cs b/FileFormat.Cells/ImageHandler.cs index 70d29ac..6ffd1f4 100644 --- a/FileFormat.Cells/ImageHandler.cs +++ b/FileFormat.Cells/ImageHandler.cs @@ -7,7 +7,9 @@ using DocumentFormat.OpenXml.Spreadsheet; using System.Linq; using DocumentFormat.OpenXml.Drawing.Spreadsheet; - +using System; +using System.IO; + namespace FileFormat.Cells { public class ImageHandler diff --git a/FileFormat.Cells/Properties/launchSettings.json b/FileFormat.Cells/Properties/launchSettings.json new file mode 100644 index 0000000..b91e10e --- /dev/null +++ b/FileFormat.Cells/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:13841", + "sslPort": 44390 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "http://localhost:5061", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true + }, + "https": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:7274;http://localhost:5061", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/FileFormat.Cells/Workbook.cs b/FileFormat.Cells/Workbook.cs index 7cf33d8..455dbd7 100644 --- a/FileFormat.Cells/Workbook.cs +++ b/FileFormat.Cells/Workbook.cs @@ -58,7 +58,7 @@ public Workbook() // Adding your Worksheet object to Worksheets list //var newWorksheet = new Worksheet(worksheetPart, worksheetPart.Worksheet); - var newWorksheet = Worksheet.WorksheetFactory.CreateInstance(worksheetPart, worksheetPart.Worksheet); + var newWorksheet = Worksheet.WorksheetFactory.CreateInstance(worksheetPart, worksheetPart.Worksheet, workbookpart); this.Worksheets.Add(newWorksheet); this.stylesPart = this.spreadsheetDocument.WorkbookPart.AddNewPart(); @@ -124,8 +124,9 @@ private void InitializeWorksheets() { var worksheetPart = (WorksheetPart)(this.workbookpart.GetPartById(sheet.Id)); var worksheet = worksheetPart.Worksheet; + var workbookPart = this.workbookpart; var sheetData = worksheet.Elements().FirstOrDefault() ?? new SheetData(); - this.Worksheets.Add(Worksheet.WorksheetFactory.CreateInstance(worksheetPart, worksheetPart.Worksheet)); + this.Worksheets.Add(Worksheet.WorksheetFactory.CreateInstance(worksheetPart, worksheetPart.Worksheet, workbookPart)); } } @@ -228,7 +229,7 @@ public Worksheet AddSheet(string sheetName) newWorksheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData); // Create a new Worksheet object and add it to Worksheets list - var newWorksheet = Worksheet.WorksheetFactory.CreateInstance(newWorksheetPart, newWorksheetPart.Worksheet); + var newWorksheet = Worksheet.WorksheetFactory.CreateInstance(newWorksheetPart, newWorksheetPart.Worksheet, this.workbookpart); this.Worksheets.Add(newWorksheet); // Append a new sheet and associate it with the workbook @@ -286,7 +287,7 @@ private void SyncWorksheets() var wp = (WorksheetPart)(this.workbookpart.GetPartById(sh.Id)); var ws = wp.Worksheet; var sd = ws.Elements().FirstOrDefault() ?? new SheetData(); - this.Worksheets.Add(Worksheet.WorksheetFactory.CreateInstance(wp, wp.Worksheet)); + this.Worksheets.Add(Worksheet.WorksheetFactory.CreateInstance(wp, wp.Worksheet, this.workbookpart)); } } diff --git a/FileFormat.Cells/Worksheet.cs b/FileFormat.Cells/Worksheet.cs index 8d3056f..a16f663 100644 --- a/FileFormat.Cells/Worksheet.cs +++ b/FileFormat.Cells/Worksheet.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Text; using System.Text.RegularExpressions; using DocumentFormat.OpenXml; @@ -16,11 +18,11 @@ public sealed class Worksheet { private WorksheetPart _worksheetPart; private SheetData _sheetData; - + private DocumentFormat.OpenXml.Spreadsheet.Cell sourceCell; public const double DefaultColumnWidth = 8.43; // Default width in character units public const double DefaultRowHeight = 15.0; // Default height in points - + private WorkbookPart _workbookPart; /// /// Gets the CellIndexer for the worksheet. This property provides indexed access to the cells of the worksheet. /// @@ -41,15 +43,17 @@ public sealed class Worksheet /// /// Thrown if SheetData is not found in the provided worksheet. /// - private Worksheet(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet) + private Worksheet(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet, WorkbookPart workbookPart) { _worksheetPart = worksheetPart ?? throw new ArgumentNullException(nameof(worksheetPart)); _sheetData = worksheet?.Elements().FirstOrDefault() ?? throw new InvalidOperationException("SheetData not found in the worksheet."); + _workbookPart = workbookPart ?? throw new ArgumentNullException(nameof(workbookPart)); // Initialize the Cells property this.Cells = new CellIndexer(this); + } /// @@ -61,9 +65,9 @@ private Worksheet(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadshee /// A new instance of the Worksheet class. public class WorksheetFactory { - public static Worksheet CreateInstance(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet) + public static Worksheet CreateInstance(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet, WorkbookPart workbookPart) { - return new Worksheet(worksheetPart, worksheet); + return new Worksheet(worksheetPart, worksheet, workbookPart); } } @@ -123,7 +127,7 @@ public string Name public Cell GetCell(string cellReference) { // This logic used to be in your indexer - return new Cell(GetOrCreateCell(cellReference), _sheetData); + return new Cell(GetOrCreateCell(cellReference), _sheetData, _workbookPart); } /// @@ -1604,8 +1608,36 @@ public void AddComment(string cellReference, Comment comment) _worksheetPart.Worksheet.Save(); } + public void CopyRange(Range sourceRange, string targetStartCellReference) + { + var (targetStartRow, targetStartColumn) = ParseCellReference(targetStartCellReference); + + uint rowOffset = targetStartRow - sourceRange.StartRowIndex; + uint columnOffset = targetStartColumn - sourceRange.StartColumnIndex; + + for (uint row = sourceRange.StartRowIndex; row <= sourceRange.EndRowIndex; row++) + { + for (uint column = sourceRange.StartColumnIndex - 1; column < sourceRange.EndColumnIndex; column++) + { + // Calculate target cell's row and column indices + uint targetRow = row + rowOffset; + uint targetColumn = column + columnOffset; + + // Construct source and target cell references + string sourceCellRef = $"{IndexToColumnLetter((int)column)}{row}"; + string targetCellRef = $"{IndexToColumnLetter((int)targetColumn)}{targetRow}"; + + this.Cells[targetCellRef].PutValue(this.Cells[sourceCellRef].GetValue()); + } + } + + // Save the worksheet to apply changes + _worksheetPart.Worksheet.Save(); + } + + } public class CellIndexer @@ -1635,6 +1667,7 @@ public Cell this[string cellReference] return _worksheet.GetCell(cellReference); } } + } } diff --git a/FileFormat.Cells_Tests/FileFormat.Cells_Tests.csproj b/FileFormat.Cells_Tests/FileFormat.Cells_Tests.csproj index c5dcee2..89db112 100644 --- a/FileFormat.Cells_Tests/FileFormat.Cells_Tests.csproj +++ b/FileFormat.Cells_Tests/FileFormat.Cells_Tests.csproj @@ -1,13 +1,14 @@  - netcoreapp3.1 + net70 10.0 enable enable false true + Debug;Release;netcore3.1