Skip to content

Commit 8ab9db8

Browse files
author
JanKallman
committed
Added TabColor property to Worksheet. Fixed copy of merged cells in Range.Copy. Some Documentation.
--HG-- extra : convert_revision : svn%3Ac031521d-7fdb-604e-9ef1-0138de3cd895/trunk%4084
1 parent 68dbba1 commit 8ab9db8

26 files changed

+503
-68
lines changed

Doc/EPPlusDoc.scproj

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,26 @@
1515
<Name>Documentation</Name>
1616
<!-- SHFB properties -->
1717
<OutputPath>.\Help\</OutputPath>
18-
<HtmlHelpName>EPPlus 2.8</HtmlHelpName>
19-
<FrameworkVersion>3.0</FrameworkVersion>
18+
<HtmlHelpName>EPPlus 2.9</HtmlHelpName>
19+
<FrameworkVersion>3.5</FrameworkVersion>
2020
<DocumentationSources>
21-
<DocumentationSource sourceFile="..\ExcelPackage\bin\Release\EPPlus.dll" xmlns="" />
22-
<DocumentationSource sourceFile="..\ExcelPackage\bin\Release\EPPlusXmlDocumentationFile.xml" xmlns="" />
23-
</DocumentationSources>
21+
<DocumentationSource sourceFile="..\ExcelPackage\bin\Release\EPPlus.dll" />
22+
<DocumentationSource sourceFile="..\ExcelPackage\bin\Release\EPPlus.XML" /></DocumentationSources>
2423
<ProjectSummary>EPPlus is a .net library that reads and writes Excel files using the Open Office Xml format.
2524
EPPlus supports ranges, cell styling, charts, picture, shapes, named ranges, comments,tables and a lot of other stuff.
2625
EPPlus started with the source from the ExcelPackage project hosted on CodePlex.</ProjectSummary>
2726
<NamespaceSummaries>
2827
<NamespaceSummaryItem name="OfficeOpenXml" isDocumented="True">This is the main namespace for EPPlus</NamespaceSummaryItem>
29-
<NamespaceSummaryItem name="OfficeOpenXml.Drawing" isDocumented="True">Contains all classes related to drawings. Drawing objects are Charts, Shapes and pictures</NamespaceSummaryItem>
28+
<NamespaceSummaryItem name="OfficeOpenXml.Drawing" isDocumented="True">Contains all classes related to drawings. Drawing objects are Charts, Shapes and Pictures</NamespaceSummaryItem>
3029
<NamespaceSummaryItem name="OfficeOpenXml.Drawing.Chart" isDocumented="True">Contains chart classes</NamespaceSummaryItem>
3130
<NamespaceSummaryItem name="OfficeOpenXml.Style" isDocumented="True">Contains classes for cell styling and named styles</NamespaceSummaryItem>
3231
<NamespaceSummaryItem name="OfficeOpenXml.Style.XmlAccess" isDocumented="True">Contains the classes that write the style xml</NamespaceSummaryItem>
3332
<NamespaceSummaryItem name="OfficeOpenXml.Drawing.Vml" isDocumented="True">Contains classes used for Vml drawings. Vml drawings are used for comments</NamespaceSummaryItem>
34-
<NamespaceSummaryItem name="OfficeOpenXml.Table" isDocumented="True">Contains the classes used for Excel tables</NamespaceSummaryItem></NamespaceSummaries>
35-
<HelpTitle>EPPlus 2.8</HelpTitle>
33+
<NamespaceSummaryItem name="OfficeOpenXml.Table" isDocumented="True">Contains the classes used for Excel tables</NamespaceSummaryItem>
34+
<NamespaceSummaryItem name="OfficeOpenXml.DataValidation" isDocumented="True">Contains classes for Datavalidation</NamespaceSummaryItem>
35+
<NamespaceSummaryItem name="OfficeOpenXml.Table.PivotTable" isDocumented="True">Contains classes for Excel Pivottables</NamespaceSummaryItem>
36+
<NamespaceSummaryItem name="OfficeOpenXml.Utils" isDocumented="True">Internal utility classes</NamespaceSummaryItem></NamespaceSummaries>
37+
<HelpTitle>EPPlus 2.9</HelpTitle>
3638
</PropertyGroup>
3739
<!-- There are no properties for these groups. AnyCPU needs to appear in
3840
order for Visual Studio to perform the build. The others are optional

ExcelPackage/EPPlus.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
<DefineConstants>TRACE</DefineConstants>
6262
<ErrorReport>prompt</ErrorReport>
6363
<WarningLevel>4</WarningLevel>
64-
<DocumentationFile>bin\Release\EPPlusXmlDocumentationFile.xml</DocumentationFile>
64+
<DocumentationFile>bin\Release\EPPlus.XML</DocumentationFile>
6565
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
6666
</PropertyGroup>
6767
<ItemGroup>

ExcelPackage/ExcelCell.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,11 @@ ulong IRangeID.RangeID
454454
#endregion
455455
internal ExcelCell Clone(ExcelWorksheet added)
456456
{
457-
ExcelCell newCell = new ExcelCell(added, _row, _col);
457+
return Clone(added, _row, _col);
458+
}
459+
internal ExcelCell Clone(ExcelWorksheet added, int row, int col)
460+
{
461+
ExcelCell newCell = new ExcelCell(added, row, col);
458462
if(_hyperlink!=null) newCell.Hyperlink = Hyperlink;
459463
newCell._formula = _formula;
460464
newCell._formulaR1C1 = _formulaR1C1;

ExcelPackage/ExcelCellBase.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ private static string AddToRowColumnTranslator(string Address, int row, int col,
254254
{
255255
if (rowIncr > 0) //Insert
256256
{
257-
Address = GetAddress(fromRow + rowIncr, fromCol);
257+
Address = GetAddress(fromRow + rowIncr, false, fromCol, Address.StartsWith("$"));
258258
}
259259
else //Delete
260260
{
@@ -264,13 +264,13 @@ private static string AddToRowColumnTranslator(string Address, int row, int col,
264264
}
265265
else
266266
{
267-
Address = GetAddress(fromRow + rowIncr, fromCol);
267+
Address = GetAddress(fromRow + rowIncr, false, fromCol, Address.StartsWith("$"));
268268
}
269269
}
270270
}
271271
else if (col != 0 && fromCol >= col && Address.StartsWith("$") == false)
272272
{
273-
Address = GetAddress(fromRow, fromCol + colIncr);
273+
Address = GetAddress(fromRow, Address.IndexOf('$', 1) > -1, fromCol + colIncr, false);
274274
}
275275
}
276276
return Address;

ExcelPackage/ExcelPrinterSettings.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,11 @@ internal ExcelPrinterSettings(XmlNamespaceManager ns, XmlNode topNode,ExcelWorks
342342
base(ns, topNode)
343343
{
344344
_ws = ws;
345+
SchemaNodeOrder = ws.SchemaNodeOrder;
345346
}
346347
const string _leftMarginPath = "d:pageMargins/@left";
347348
/// <summary>
348-
/// Left margin
349+
/// Left margin in inches
349350
/// </summary>
350351
public decimal LeftMargin
351352
{
@@ -361,7 +362,7 @@ public decimal LeftMargin
361362
}
362363
const string _rightMarginPath = "d:pageMargins/@right";
363364
/// <summary>
364-
/// Right margin
365+
/// Right margin in inches
365366
/// </summary>
366367
public decimal RightMargin
367368
{
@@ -377,7 +378,7 @@ public decimal RightMargin
377378
}
378379
const string _topMarginPath = "d:pageMargins/@top";
379380
/// <summary>
380-
/// Top margin
381+
/// Top margin in inches
381382
/// </summary>
382383
public decimal TopMargin
383384
{
@@ -393,7 +394,7 @@ public decimal TopMargin
393394
}
394395
const string _bottomMarginPath = "d:pageMargins/@bottom";
395396
/// <summary>
396-
/// Bottom margin
397+
/// Bottom margin in inches
397398
/// </summary>
398399
public decimal BottomMargin
399400
{
@@ -409,7 +410,7 @@ public decimal BottomMargin
409410
}
410411
const string _headerMarginPath = "d:pageMargins/@header";
411412
/// <summary>
412-
/// Header margin
413+
/// Header margin in inches
413414
/// </summary>
414415
public decimal HeaderMargin
415416
{
@@ -425,7 +426,7 @@ public decimal HeaderMargin
425426
}
426427
const string _footerMarginPath = "d:pageMargins/@footer";
427428
/// <summary>
428-
/// Footer margin
429+
/// Footer margin in inches
429430
/// </summary>
430431
public decimal FooterMargin
431432
{

ExcelPackage/ExcelRangeBase.cs

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
using OfficeOpenXml.DataValidation.Contracts;
4545
using System.Reflection;
4646
using OfficeOpenXml.Style.XmlAccess;
47+
using System.Security;
4748
namespace OfficeOpenXml
4849
{
4950
/// <summary>
@@ -875,9 +876,17 @@ public ExcelRichTextCollection RichText
875876
if (_rtc == null)
876877
{
877878
XmlDocument xml = new XmlDocument();
878-
if (_worksheet.Cell(_fromRow, _fromCol).Value != null)
879+
var cell = _worksheet.Cell(_fromRow, _fromCol);
880+
if (cell.Value != null)
879881
{
880-
xml.LoadXml("<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ><d:r><d:t>" + _worksheet.Cell(_fromRow, _fromCol).Value.ToString() + "</d:t></d:r></d:si>");
882+
if (cell.IsRichText)
883+
{
884+
xml.LoadXml("<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ><d:r><d:t>" + _worksheet.Cell(_fromRow, _fromCol).Value.ToString() + "</d:t></d:r></d:si>");
885+
}
886+
else
887+
{
888+
xml.LoadXml("<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ><d:r><d:t>" + SecurityElement.Escape(_worksheet.Cell(_fromRow, _fromCol).Value.ToString()) + "</d:t></d:r></d:si>");
889+
}
881890
}
882891
else
883892
{
@@ -1716,30 +1725,36 @@ public ExcelComment AddComment(string Text, string Author)
17161725
/// <param name="Destination">The start cell where the range will be copied.</param>
17171726
public void Copy(ExcelRangeBase Destination)
17181727
{
1719-
bool sameWorkbook=Destination._worksheet == _worksheet;
1728+
bool sameWorkbook = Destination._worksheet.Workbook == _worksheet.Workbook;
17201729
ExcelStyles sourceStyles=_worksheet.Workbook.Styles,
17211730
styles = Destination._worksheet.Workbook.Styles;
17221731
Dictionary<int,int> styleCashe=new Dictionary<int,int>();
17231732

17241733
//Delete all existing cells;
17251734
List<ExcelCell> newCells=new List<ExcelCell>();
1735+
Dictionary<ulong, ExcelCell> mergedCells = new Dictionary<ulong, ExcelCell>();
17261736
foreach (var cell in this)
17271737
{
17281738
//Clone the cell
1729-
var newCell=(_worksheet._cells[GetCellID(_worksheet.SheetID, cell._fromRow, cell._fromCol)] as ExcelCell).Clone(Destination._worksheet);
1739+
var copiedCell = (_worksheet._cells[GetCellID(_worksheet.SheetID, cell._fromRow, cell._fromCol)] as ExcelCell);
17301740

1731-
//Set the correct row/column
1732-
newCell.Row = Destination._fromRow + (newCell.Row - _fromRow);
1733-
newCell.Column = Destination._fromCol + (newCell.Column - _fromCol);
1741+
var newCell = copiedCell.Clone(Destination._worksheet,
1742+
Destination._fromRow + (copiedCell.Row - _fromRow),
1743+
Destination._fromCol + (copiedCell.Column - _fromCol));
17341744

17351745
//If the formula is shared, remove the shared ID and set the formula for the cell.
17361746
if (newCell._sharedFormulaID >= 0)
17371747
{
17381748
newCell._sharedFormulaID = int.MinValue;
17391749
newCell.Formula = cell.Formula;
17401750
}
1751+
1752+
if (!string.IsNullOrEmpty(newCell.Formula))
1753+
{
1754+
newCell.Formula = ExcelCell.UpdateFormulaReferences(newCell.Formula, newCell.Row - copiedCell.Row, (newCell.Column - copiedCell.Column), 1, 1);
1755+
}
17411756

1742-
//If its not the same workbook whe must copy the styles to the new workbook.
1757+
//If its not the same workbook we must copy the styles to the new workbook.
17431758
if (!sameWorkbook)
17441759
{
17451760
if (styleCashe.ContainsKey(cell.StyleID))
@@ -1753,17 +1768,67 @@ public void Copy(ExcelRangeBase Destination)
17531768
}
17541769
}
17551770
newCells.Add(newCell);
1771+
if (newCell.Merge) mergedCells.Add(newCell.CellID, newCell);
17561772
}
17571773

1758-
//Now clear the workbook.
1759-
Delete(Destination.Offset(0,0,(_toRow-_fromRow)+1, (_toCol-_fromCol)+1));
1774+
//Now clear the destination.
1775+
Destination.Offset(0, 0, (_toRow - _fromRow) + 1, (_toCol - _fromCol) + 1).Clear();
17601776

17611777
//And last add the new cells to the worksheet
17621778
foreach (var cell in newCells)
17631779
{
17641780
Destination.Worksheet._cells.Add(cell);
17651781
}
1782+
//Add merged cells
1783+
if(mergedCells.Count>0)
1784+
{
1785+
List<ExcelAddressBase> mergedAddresses = new List<ExcelAddressBase>();
1786+
foreach (var cell in mergedCells.Values)
1787+
{
1788+
if(!IsAdded(cell, mergedAddresses))
1789+
{
1790+
int startRow = cell.Row, startCol = cell.Column, endRow = cell.Row, endCol = cell.Column+1;
1791+
while(mergedCells.ContainsKey(ExcelCell.GetCellID(Destination.Worksheet.SheetID, endRow, endCol)))
1792+
{
1793+
endCol++;
1794+
}
1795+
1796+
while(IsMerged(mergedCells, Destination.Worksheet, endRow, startCol,endCol-1))
1797+
{
1798+
endRow++;
1799+
}
1800+
1801+
mergedAddresses.Add(new ExcelAddressBase(startRow, startCol, endRow-1, endCol-1));
1802+
}
1803+
}
1804+
Destination.Worksheet.MergedCells.List.AddRange((from r in mergedAddresses select r.Address));
1805+
}
1806+
}
1807+
1808+
private bool IsAdded(ExcelCell cell, List<ExcelAddressBase> mergedAddresses)
1809+
{
1810+
foreach(var address in mergedAddresses)
1811+
{
1812+
if(address.Collide(new ExcelAddressBase(cell.CellAddress))==eAddressCollition.Inside)
1813+
{
1814+
return true;
1815+
}
1816+
}
1817+
return false;
17661818
}
1819+
1820+
private bool IsMerged(Dictionary<ulong, ExcelCell> mergedCells,ExcelWorksheet worksheet, int row, int startCol, int endCol)
1821+
{
1822+
for(int col=startCol;col<=endCol;col++)
1823+
{
1824+
if(!mergedCells.ContainsKey(ExcelCell.GetCellID(worksheet.SheetID, row, col)))
1825+
{
1826+
return false;
1827+
}
1828+
}
1829+
return true;
1830+
}
1831+
17671832
/// <summary>
17681833
/// Clear all cells
17691834
/// </summary>

ExcelPackage/ExcelStyleCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public ExcelStyleCollection(bool SetNextIdManual)
4949
_setNextIdManual = SetNextIdManual;
5050
}
5151
public XmlNode TopNode { get; set; }
52-
List<T> _list = new List<T>();
52+
internal List<T> _list = new List<T>();
5353
Dictionary<string, int> _dic = new Dictionary<string, int>();
5454
internal int NextId=0;
5555
#region IEnumerable<T> Members

ExcelPackage/ExcelStyles.cs

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,18 @@ public ExcelNamedStyleXml CreateNamedStyle(string name, ExcelStyle Template)
379379
}
380380
else
381381
{
382-
style.Style = new ExcelStyle(this, NamedStylePropertyChange, -1, name, Template.Index);
383-
style.StyleXfId = Template.Index;
382+
if (Template.PositionID < 0 && Template.Styles==this)
383+
{
384+
style.Style = new ExcelStyle(this, NamedStylePropertyChange, Template.PositionID, name, Template.Index);
385+
style.StyleXfId = Template.Index;
386+
}
387+
else
388+
{
389+
int xfid=CloneStyle(Template.Styles, Template.XfId, true);
390+
style.Style = new ExcelStyle(this, NamedStylePropertyChange, -1, name, xfid);
391+
style.StyleXfId = xfid;
392+
393+
}
384394
}
385395
style.Name = name;
386396
int ix =_wb.Styles.NamedStyles.Add(style.Name, style);
@@ -607,10 +617,21 @@ private string GetXmlNode(XmlNode node)
607617
}
608618

609619
#endregion
610-
611620
internal int CloneStyle(ExcelStyles style, int styleID)
612621
{
613-
ExcelXfs xfs=style.CellXfs[styleID];
622+
return CloneStyle(style, styleID, false);
623+
}
624+
internal int CloneStyle(ExcelStyles style, int styleID, bool isNamedStyle)
625+
{
626+
ExcelXfs xfs;
627+
if (isNamedStyle)
628+
{
629+
xfs = style.CellStyleXfs[styleID];
630+
}
631+
else
632+
{
633+
xfs = style.CellXfs[styleID];
634+
}
614635
ExcelXfs newXfs=xfs.Copy(this);
615636
//Numberformat
616637
if (xfs.NumberFormatId > -1)
@@ -662,12 +683,23 @@ internal int CloneStyle(ExcelStyles style, int styleID)
662683
newXfs.FillId = ix;
663684
}
664685

665-
int id = CellXfs.FindIndexByID(newXfs.Id);
666-
if (id < 0)
686+
int id;
687+
if (isNamedStyle)
667688
{
668-
id = CellXfs.Add(newXfs.Id, newXfs);
689+
id = CellStyleXfs.FindIndexByID(newXfs.Id);
690+
if (id < 0)
691+
{
692+
id = CellStyleXfs.Add(newXfs.Id, newXfs);
693+
}
694+
}
695+
else
696+
{
697+
id = CellXfs.FindIndexByID(newXfs.Id);
698+
if (id < 0)
699+
{
700+
id = CellXfs.Add(newXfs.Id, newXfs);
701+
}
669702
}
670-
671703
return id;
672704
}
673705
}

0 commit comments

Comments
 (0)