Skip to content

Commit c15e783

Browse files
authored
Merge pull request #14 from fahadadeel/main
Implement Enhanced CopyRange Feature with Workbook and Worksheet Class Modifications
2 parents c4ea869 + e5ea08c commit c15e783

File tree

9 files changed

+135
-25
lines changed

9 files changed

+135
-25
lines changed

FileFormat.Cells.sln

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 25.0.1705.6
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.9.34607.119
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileFormat.Cells", "FileFormat.Cells\FileFormat.Cells.csproj", "{347E8540-1317-4E99-BF8A-A16A04E753BB}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileFormat.Cells", "FileFormat.Cells\FileFormat.Cells.csproj", "{347E8540-1317-4E99-BF8A-A16A04E753BB}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileFormat.Cells_Tests", "FileFormat.Cells_Tests\FileFormat.Cells_Tests.csproj", "{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}"
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileFormat.Cells_Tests", "FileFormat.Cells_Tests\FileFormat.Cells_Tests.csproj", "{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}"
99
EndProject
1010
Global
1111
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1212
Debug|Any CPU = Debug|Any CPU
13+
netcore3.1|Any CPU = netcore3.1|Any CPU
1314
Release|Any CPU = Release|Any CPU
1415
EndGlobalSection
1516
GlobalSection(ProjectConfigurationPlatforms) = postSolution
1617
{347E8540-1317-4E99-BF8A-A16A04E753BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1718
{347E8540-1317-4E99-BF8A-A16A04E753BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
19+
{347E8540-1317-4E99-BF8A-A16A04E753BB}.netcore3.1|Any CPU.ActiveCfg = netcore3.1|Any CPU
20+
{347E8540-1317-4E99-BF8A-A16A04E753BB}.netcore3.1|Any CPU.Build.0 = netcore3.1|Any CPU
1821
{347E8540-1317-4E99-BF8A-A16A04E753BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
1922
{347E8540-1317-4E99-BF8A-A16A04E753BB}.Release|Any CPU.Build.0 = Release|Any CPU
2023
{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2124
{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.Debug|Any CPU.Build.0 = Debug|Any CPU
25+
{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.netcore3.1|Any CPU.ActiveCfg = netcore3.1|Any CPU
26+
{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.netcore3.1|Any CPU.Build.0 = netcore3.1|Any CPU
2227
{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.Release|Any CPU.ActiveCfg = Release|Any CPU
2328
{A9BFD275-A6CD-4CD7-B039-8CB29CDE5C93}.Release|Any CPU.Build.0 = Release|Any CPU
2429
EndGlobalSection

FileFormat.Cells/Cell.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
using DocumentFormat.OpenXml;
33
using System.Globalization;
44
using DocumentFormat.OpenXml.Spreadsheet;
5+
using DocumentFormat.OpenXml.Packaging;
56

67
namespace FileFormat.Cells
78
{
89
public sealed class Cell
910
{
11+
1012
private readonly DocumentFormat.OpenXml.Spreadsheet.Cell _cell;
13+
private readonly WorkbookPart _workbookPart;
14+
1115
private readonly SheetData _sheetData;
1216

1317
/// <summary>
@@ -23,10 +27,11 @@ public sealed class Cell
2327
/// <exception cref="ArgumentNullException">
2428
/// Thrown when <paramref name="cell"/> or <paramref name="sheetData"/> is null.
2529
/// </exception>
26-
public Cell(DocumentFormat.OpenXml.Spreadsheet.Cell cell, SheetData sheetData)
30+
public Cell(DocumentFormat.OpenXml.Spreadsheet.Cell cell, SheetData sheetData, WorkbookPart workbookPart)
2731
{
2832
_cell = cell ?? throw new ArgumentNullException(nameof(cell));
2933
_sheetData = sheetData ?? throw new ArgumentNullException(nameof(sheetData));
34+
_workbookPart = workbookPart ?? throw new ArgumentNullException(nameof(workbookPart));
3035
}
3136

3237
/// <summary>
@@ -82,9 +87,20 @@ public void PutFormula(string formula)
8287
/// Gets the value of the cell.
8388
/// </summary>
8489
/// <returns>The cell value as a string.</returns>
85-
public string GetValue()
86-
{
87-
return _cell.CellValue?.Text;
90+
public string GetValue()
91+
{
92+
if (_cell == null || _cell.CellValue == null) return "";
93+
94+
if (_cell.DataType != null && _cell.DataType.Value == CellValues.SharedString)
95+
{
96+
int index = int.Parse(_cell.CellValue.Text);
97+
SharedStringTablePart sharedStrings = _workbookPart.SharedStringTablePart;
98+
return sharedStrings.SharedStringTable.ElementAt(index).InnerText;
99+
}
100+
else
101+
{
102+
return _cell.CellValue.Text;
103+
}
88104
}
89105

90106
/// <summary>
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
55
<TargetFramework>netcoreapp3.1</TargetFramework>
6-
<LangVersion>10.0</LangVersion>
6+
77
<ImplicitUsings>enable</ImplicitUsings>
88
<Nullable>enable</Nullable>
9+
<Configurations>Debug;Release;netcore3.1</Configurations>
910
</PropertyGroup>
1011

11-
<ItemGroup>
12+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
13+
14+
</PropertyGroup>
15+
16+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
17+
<PlatformTarget>AnyCPU</PlatformTarget>
18+
</PropertyGroup>
19+
<PropertyGroup>
20+
<LangVersion>10.0</LangVersion>
21+
</PropertyGroup>
22+
23+
24+
<ItemGroup>
1225
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
1326
</ItemGroup>
14-
</Project>
27+
</Project>

FileFormat.Cells/Image.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using A14 = DocumentFormat.OpenXml.Office2010.Drawing;
77
using DocumentFormat.OpenXml.Spreadsheet;
88
using System.Linq;
9-
9+
using System.IO;
10+
using System;
11+
1012
namespace FileFormat.Cells
1113
{
1214

FileFormat.Cells/ImageHandler.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
using DocumentFormat.OpenXml.Spreadsheet;
88
using System.Linq;
99
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
10-
10+
using System;
11+
using System.IO;
12+
1113
namespace FileFormat.Cells
1214
{
1315
public class ImageHandler
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:13841",
7+
"sslPort": 44390
8+
}
9+
},
10+
"profiles": {
11+
"http": {
12+
"commandName": "Project",
13+
"launchBrowser": true,
14+
"applicationUrl": "http://localhost:5061",
15+
"environmentVariables": {
16+
"ASPNETCORE_ENVIRONMENT": "Development"
17+
},
18+
"dotnetRunMessages": true
19+
},
20+
"https": {
21+
"commandName": "Project",
22+
"launchBrowser": true,
23+
"applicationUrl": "https://localhost:7274;http://localhost:5061",
24+
"environmentVariables": {
25+
"ASPNETCORE_ENVIRONMENT": "Development"
26+
},
27+
"dotnetRunMessages": true
28+
},
29+
"IIS Express": {
30+
"commandName": "IISExpress",
31+
"launchBrowser": true,
32+
"environmentVariables": {
33+
"ASPNETCORE_ENVIRONMENT": "Development"
34+
}
35+
}
36+
}
37+
}

FileFormat.Cells/Workbook.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public Workbook()
5858

5959
// Adding your Worksheet object to Worksheets list
6060
//var newWorksheet = new Worksheet(worksheetPart, worksheetPart.Worksheet);
61-
var newWorksheet = Worksheet.WorksheetFactory.CreateInstance(worksheetPart, worksheetPart.Worksheet);
61+
var newWorksheet = Worksheet.WorksheetFactory.CreateInstance(worksheetPart, worksheetPart.Worksheet, workbookpart);
6262
this.Worksheets.Add(newWorksheet);
6363

6464
this.stylesPart = this.spreadsheetDocument.WorkbookPart.AddNewPart<WorkbookStylesPart>();
@@ -124,8 +124,9 @@ private void InitializeWorksheets()
124124
{
125125
var worksheetPart = (WorksheetPart)(this.workbookpart.GetPartById(sheet.Id));
126126
var worksheet = worksheetPart.Worksheet;
127+
var workbookPart = this.workbookpart;
127128
var sheetData = worksheet.Elements<SheetData>().FirstOrDefault() ?? new SheetData();
128-
this.Worksheets.Add(Worksheet.WorksheetFactory.CreateInstance(worksheetPart, worksheetPart.Worksheet));
129+
this.Worksheets.Add(Worksheet.WorksheetFactory.CreateInstance(worksheetPart, worksheetPart.Worksheet, workbookPart));
129130
}
130131
}
131132

@@ -228,7 +229,7 @@ public Worksheet AddSheet(string sheetName)
228229
newWorksheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
229230

230231
// Create a new Worksheet object and add it to Worksheets list
231-
var newWorksheet = Worksheet.WorksheetFactory.CreateInstance(newWorksheetPart, newWorksheetPart.Worksheet);
232+
var newWorksheet = Worksheet.WorksheetFactory.CreateInstance(newWorksheetPart, newWorksheetPart.Worksheet, this.workbookpart);
232233
this.Worksheets.Add(newWorksheet);
233234

234235
// Append a new sheet and associate it with the workbook
@@ -286,7 +287,7 @@ private void SyncWorksheets()
286287
var wp = (WorksheetPart)(this.workbookpart.GetPartById(sh.Id));
287288
var ws = wp.Worksheet;
288289
var sd = ws.Elements<SheetData>().FirstOrDefault() ?? new SheetData();
289-
this.Worksheets.Add(Worksheet.WorksheetFactory.CreateInstance(wp, wp.Worksheet));
290+
this.Worksheets.Add(Worksheet.WorksheetFactory.CreateInstance(wp, wp.Worksheet, this.workbookpart));
290291
}
291292
}
292293

FileFormat.Cells/Worksheet.cs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using System.Text;
35
using System.Text.RegularExpressions;
46
using DocumentFormat.OpenXml;
@@ -16,11 +18,11 @@ public sealed class Worksheet
1618
{
1719
private WorksheetPart _worksheetPart;
1820
private SheetData _sheetData;
19-
21+
private DocumentFormat.OpenXml.Spreadsheet.Cell sourceCell;
2022
public const double DefaultColumnWidth = 8.43; // Default width in character units
2123
public const double DefaultRowHeight = 15.0; // Default height in points
2224

23-
25+
private WorkbookPart _workbookPart;
2426
/// <summary>
2527
/// Gets the CellIndexer for the worksheet. This property provides indexed access to the cells of the worksheet.
2628
/// </summary>
@@ -41,15 +43,17 @@ public sealed class Worksheet
4143
/// <exception cref="InvalidOperationException">
4244
/// Thrown if SheetData is not found in the provided worksheet.
4345
/// </exception>
44-
private Worksheet(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet)
46+
private Worksheet(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet, WorkbookPart workbookPart)
4547
{
4648
_worksheetPart = worksheetPart ?? throw new ArgumentNullException(nameof(worksheetPart));
4749

4850
_sheetData = worksheet?.Elements<SheetData>().FirstOrDefault()
4951
?? throw new InvalidOperationException("SheetData not found in the worksheet.");
52+
_workbookPart = workbookPart ?? throw new ArgumentNullException(nameof(workbookPart));
5053

5154
// Initialize the Cells property
5255
this.Cells = new CellIndexer(this);
56+
5357
}
5458

5559
/// <summary>
@@ -61,9 +65,9 @@ private Worksheet(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadshee
6165
/// <returns>A new instance of the Worksheet class.</returns>
6266
public class WorksheetFactory
6367
{
64-
public static Worksheet CreateInstance(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet)
68+
public static Worksheet CreateInstance(WorksheetPart worksheetPart, DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet, WorkbookPart workbookPart)
6569
{
66-
return new Worksheet(worksheetPart, worksheet);
70+
return new Worksheet(worksheetPart, worksheet, workbookPart);
6771
}
6872
}
6973

@@ -123,7 +127,7 @@ public string Name
123127
public Cell GetCell(string cellReference)
124128
{
125129
// This logic used to be in your indexer
126-
return new Cell(GetOrCreateCell(cellReference), _sheetData);
130+
return new Cell(GetOrCreateCell(cellReference), _sheetData, _workbookPart);
127131
}
128132

129133
/// <summary>
@@ -1604,8 +1608,36 @@ public void AddComment(string cellReference, Comment comment)
16041608
_worksheetPart.Worksheet.Save();
16051609
}
16061610

1611+
public void CopyRange(Range sourceRange, string targetStartCellReference)
1612+
{
1613+
var (targetStartRow, targetStartColumn) = ParseCellReference(targetStartCellReference);
1614+
1615+
uint rowOffset = targetStartRow - sourceRange.StartRowIndex;
1616+
uint columnOffset = targetStartColumn - sourceRange.StartColumnIndex;
1617+
1618+
for (uint row = sourceRange.StartRowIndex; row <= sourceRange.EndRowIndex; row++)
1619+
{
1620+
for (uint column = sourceRange.StartColumnIndex - 1; column < sourceRange.EndColumnIndex; column++)
1621+
{
1622+
// Calculate target cell's row and column indices
1623+
uint targetRow = row + rowOffset;
1624+
uint targetColumn = column + columnOffset;
1625+
1626+
// Construct source and target cell references
1627+
string sourceCellRef = $"{IndexToColumnLetter((int)column)}{row}";
1628+
string targetCellRef = $"{IndexToColumnLetter((int)targetColumn)}{targetRow}";
1629+
1630+
this.Cells[targetCellRef].PutValue(this.Cells[sourceCellRef].GetValue());
1631+
}
1632+
}
1633+
1634+
// Save the worksheet to apply changes
1635+
_worksheetPart.Worksheet.Save();
1636+
}
1637+
16071638

16081639

1640+
16091641
}
16101642

16111643
public class CellIndexer
@@ -1635,6 +1667,7 @@ public Cell this[string cellReference]
16351667
return _worksheet.GetCell(cellReference);
16361668
}
16371669
}
1670+
16381671
}
16391672
}
16401673

FileFormat.Cells_Tests/FileFormat.Cells_Tests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp3.1</TargetFramework>
4+
<TargetFramework>net70</TargetFramework>
55
<LangVersion>10.0</LangVersion>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88

99
<IsPackable>false</IsPackable>
1010
<IsTestProject>true</IsTestProject>
11+
<Configurations>Debug;Release;netcore3.1</Configurations>
1112
</PropertyGroup>
1213

1314
<ItemGroup>

0 commit comments

Comments
 (0)