diff --git a/ClosedXML.sln b/ClosedXML.sln
index b58a074..cd1cd87 100644
--- a/ClosedXML.sln
+++ b/ClosedXML.sln
@@ -1,9 +1,9 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.3
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Sandbox", "ClosedXML_Sandbox\ClosedXML_Sandbox.csproj", "{38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClosedXML_Sandbox", "ClosedXML_Sandbox\ClosedXML_Sandbox.csproj", "{38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5C94E22C-85AA-48FD-B082-CF929FFC6C31}"
ProjectSection(SolutionItems) = preProject
@@ -11,11 +11,11 @@
ClosedXML.vsmdi = ClosedXML.vsmdi
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Examples", "ClosedXML_Examples\ClosedXML_Examples.csproj", "{03A518D0-1CB7-488E-861C-C4E782B27A46}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClosedXML_Examples", "ClosedXML_Examples\ClosedXML_Examples.csproj", "{03A518D0-1CB7-488E-861C-C4E782B27A46}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML", "ClosedXML\ClosedXML.csproj", "{BD5E6BFE-E837-4A35-BCA9-39667D873A20}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClosedXML", "ClosedXML\ClosedXML.csproj", "{BD5E6BFE-E837-4A35-BCA9-39667D873A20}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Tests", "ClosedXML_Tests\ClosedXML_Tests.csproj", "{09B066ED-E4A7-4545-A1A4-FF03DD524BDF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClosedXML_Tests", "ClosedXML_Tests\ClosedXML_Tests.csproj", "{09B066ED-E4A7-4545-A1A4-FF03DD524BDF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{073CFB1C-43DC-4ADC-9D12-BB8D7B10C099}"
ProjectSection(SolutionItems) = preProject
@@ -49,6 +49,9 @@
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {2E35B7D8-9690-408F-B52A-F4FC485A6B09}
+ EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = ClosedXML.vsmdi
EndGlobalSection
diff --git a/ClosedXML/Attributes/XLColumnAttribute.cs b/ClosedXML/Attributes/XLColumnAttribute.cs
index 526dcb0..67ab26f 100644
--- a/ClosedXML/Attributes/XLColumnAttribute.cs
+++ b/ClosedXML/Attributes/XLColumnAttribute.cs
@@ -1,8 +1,7 @@
+using ClosedXML.Excel;
using System;
using System.Linq;
using System.Reflection;
-using ClosedXML;
-using ClosedXML.Excel;
namespace ClosedXML.Attributes
{
diff --git a/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML.csproj
index a7bc0e1..8ec60a4 100644
--- a/ClosedXML/ClosedXML.csproj
+++ b/ClosedXML/ClosedXML.csproj
@@ -1,414 +1,53 @@
-
-
+
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {BD5E6BFE-E837-4A35-BCA9-39667D873A20}
- Library
- Properties
- ClosedXML
- ClosedXML
- v4.0
- 512
- ..\
- true
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- 1591
- false
- 6
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- bin\Release\ClosedXML.xml
- 1591
- false
- 6
-
-
+ netstandard2.0;net40;net46
+ 0.93.0
+ Manuel de Leon, Amir Ghezelbash, Francois Botha
+
+
+ ClosedXML makes it easier for developers to create Excel 2007+ (.xlsx, .xlsm, etc) files. It provides a nice object oriented way to manipulate the files (similar to VBA) without dealing with the hassles of XML Documents. It can be used by any .NET language like C# and VisualBasic.NET.
+ MIT
+ https://github.com/ClosedXML/ClosedXML/blob/master/LICENSE
+ https://github.com/ClosedXML/ClosedXML
+ https://github.com/ClosedXML/ClosedXML
true
-
-
ClosedXML.snk
+ $(NoWarn);NU1605;CS1591
+ true
-
-
- ..\packages\DocumentFormat.OpenXml.2.7.2\lib\net40\DocumentFormat.OpenXml.dll
- True
-
-
- ..\packages\ExcelNumberFormat.1.0.3\lib\net20\ExcelNumberFormat.dll
- True
-
-
- ..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll
- True
-
+
+
+ $(DefineConstants);_NETSTANDARD_;_NETSTANDARD2_0_
+
+
+
+ $(DefineConstants);_NETFRAMEWORK_;_NET40_
+
+
+
+ $(DefineConstants);_NETFRAMEWORK_;_NET46_
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
- .editorconfig
-
-
-
- Designer
-
+
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
diff --git a/ClosedXML/Excel/Cells/XLCell.cs b/ClosedXML/Excel/Cells/XLCell.cs
index 8a4a708..45bddd5 100644
--- a/ClosedXML/Excel/Cells/XLCell.cs
+++ b/ClosedXML/Excel/Cells/XLCell.cs
@@ -1579,7 +1579,6 @@
get { yield break; }
}
-
public override IXLRanges RangesUsed
{
get
@@ -1694,6 +1693,7 @@
}
#region Styles
+
private XLStyleValue GetStyleForRead()
{
return StyleValue;
diff --git a/ClosedXML/Excel/Columns/XLColumn.cs b/ClosedXML/Excel/Columns/XLColumn.cs
index 9521d1d..607f181 100644
--- a/ClosedXML/Excel/Columns/XLColumn.cs
+++ b/ClosedXML/Excel/Columns/XLColumn.cs
@@ -254,6 +254,7 @@
public IXLColumn AdjustToContents(Int32 startRow, Int32 endRow, Double minWidth, Double maxWidth)
{
var fontCache = new Dictionary();
+
Double colMaxWidth = minWidth;
List autoFilterRows = new List();
diff --git a/ClosedXML/Excel/ConditionalFormats/Save/XLCFColorScaleConverter.cs b/ClosedXML/Excel/ConditionalFormats/Save/XLCFColorScaleConverter.cs
index 5fc548c..bddd195 100644
--- a/ClosedXML/Excel/ConditionalFormats/Save/XLCFColorScaleConverter.cs
+++ b/ClosedXML/Excel/ConditionalFormats/Save/XLCFColorScaleConverter.cs
@@ -1,5 +1,5 @@
-using System;
using DocumentFormat.OpenXml.Spreadsheet;
+using System;
namespace ClosedXML.Excel
{
diff --git a/ClosedXML/Excel/ConditionalFormats/Save/XLCFDataBarConverter.cs b/ClosedXML/Excel/ConditionalFormats/Save/XLCFDataBarConverter.cs
index 29300fa..67b19a0 100644
--- a/ClosedXML/Excel/ConditionalFormats/Save/XLCFDataBarConverter.cs
+++ b/ClosedXML/Excel/ConditionalFormats/Save/XLCFDataBarConverter.cs
@@ -1,7 +1,7 @@
-using System;
-using System.Linq;
using ClosedXML.Extensions;
using DocumentFormat.OpenXml.Spreadsheet;
+using System;
+using System.Linq;
namespace ClosedXML.Excel
{
@@ -25,9 +25,11 @@
case XLColorType.Color:
color.Rgb = cf.Colors[1].Color.ToHex();
break;
+
case XLColorType.Theme:
color.Theme = System.Convert.ToUInt32(cf.Colors[1].ThemeColor);
break;
+
case XLColorType.Indexed:
color.Indexed = System.Convert.ToUInt32(cf.Colors[1].Indexed);
break;
@@ -37,7 +39,6 @@
dataBar.Append(conditionalFormatValueObject2);
dataBar.Append(color);
-
conditionalFormattingRule.Append(dataBar);
if (cf.Colors.Count > 1)
diff --git a/ClosedXML/Excel/Drawings/PictureEnums.cs b/ClosedXML/Excel/Drawings/PictureEnums.cs
index 3d76e73..f00f85b 100644
--- a/ClosedXML/Excel/Drawings/PictureEnums.cs
+++ b/ClosedXML/Excel/Drawings/PictureEnums.cs
@@ -14,9 +14,9 @@
Tiff = 3,
Icon = 4,
Pcx = 5,
- Jpeg = 6,
- Emf = 7,
- Wmf = 8
+ Jpeg = 6
+ //Emf = 7,
+ //Wmf = 8
}
public enum XLPicturePlacement
diff --git a/ClosedXML/Excel/Drawings/XLPictures.cs b/ClosedXML/Excel/Drawings/XLPictures.cs
index c539d0e..705ccb1 100644
--- a/ClosedXML/Excel/Drawings/XLPictures.cs
+++ b/ClosedXML/Excel/Drawings/XLPictures.cs
@@ -73,9 +73,9 @@
public IXLPicture Add(string imageFile)
{
- using (var bitmap = Image.FromFile(imageFile) as Bitmap)
+ using (var fs = File.Open(imageFile, FileMode.Open))
{
- var picture = new XLPicture(_worksheet, bitmap);
+ var picture = new XLPicture(_worksheet, fs);
_pictures.Add(picture);
picture.Name = GetNextPictureName();
return picture;
diff --git a/ClosedXML/Excel/IXLTheme.cs b/ClosedXML/Excel/IXLTheme.cs
index 17e4e57..b506e22 100644
--- a/ClosedXML/Excel/IXLTheme.cs
+++ b/ClosedXML/Excel/IXLTheme.cs
@@ -1,6 +1,3 @@
-using ClosedXML.Excel;
-using System.Drawing;
-
namespace ClosedXML.Excel
{
public interface IXLTheme
diff --git a/ClosedXML/Excel/IXLWorksheets.cs b/ClosedXML/Excel/IXLWorksheets.cs
index f811507..180c304 100644
--- a/ClosedXML/Excel/IXLWorksheets.cs
+++ b/ClosedXML/Excel/IXLWorksheets.cs
@@ -4,21 +4,28 @@
namespace ClosedXML.Excel
{
- public interface IXLWorksheets: IEnumerable
+ public interface IXLWorksheets : IEnumerable
{
int Count { get; }
- bool TryGetWorksheet(string sheetName,out IXLWorksheet worksheet);
+
+ bool TryGetWorksheet(string sheetName, out IXLWorksheet worksheet);
IXLWorksheet Worksheet(String sheetName);
- IXLWorksheet Worksheet(Int32 position);
- IXLWorksheet Add(String sheetName);
- IXLWorksheet Add(String sheetName, Int32 position);
- IXLWorksheet Add(DataTable dataTable);
- IXLWorksheet Add(DataTable dataTable, String sheetName);
- void Add(DataSet dataSet);
- void Delete(String sheetName);
- void Delete(Int32 position);
-
+ IXLWorksheet Worksheet(Int32 position);
+
+ IXLWorksheet Add(String sheetName);
+
+ IXLWorksheet Add(String sheetName, Int32 position);
+
+ IXLWorksheet Add(DataTable dataTable);
+
+ IXLWorksheet Add(DataTable dataTable, String sheetName);
+
+ void Add(DataSet dataSet);
+
+ void Delete(String sheetName);
+
+ void Delete(Int32 position);
}
}
diff --git a/ClosedXML/Excel/PageSetup/XLHFText.cs b/ClosedXML/Excel/PageSetup/XLHFText.cs
index f9530a3..6659cd6 100644
--- a/ClosedXML/Excel/PageSetup/XLHFText.cs
+++ b/ClosedXML/Excel/PageSetup/XLHFText.cs
@@ -6,11 +6,13 @@
internal class XLHFText
{
private readonly XLHFItem _hfItem;
+
public XLHFText(XLRichString richText, XLHFItem hfItem)
{
RichText = richText;
_hfItem = hfItem;
}
+
public XLRichString RichText { get; private set; }
public String GetHFText(String prevText)
@@ -98,6 +100,5 @@
return sb.ToString();
}
-
}
}
diff --git a/ClosedXML/Excel/Ranges/IXLRanges.cs b/ClosedXML/Excel/Ranges/IXLRanges.cs
index cc6cdab..815f6f0 100644
--- a/ClosedXML/Excel/Ranges/IXLRanges.cs
+++ b/ClosedXML/Excel/Ranges/IXLRanges.cs
@@ -19,6 +19,15 @@
/// The range to remove from this group.
void Remove(IXLRange range);
+ ///
+ /// Removes ranges matching the criteria from the collection, optionally releasing their event handlers.
+ ///
+ /// Criteria to filter ranges. Only those ranges that satisfy the criteria will be removed.
+ /// Null means the entire collection should be cleared.
+ /// Specify whether or not should removed ranges be unsubscribed from
+ /// row/column shifting events. Until ranges are unsubscribed they cannot be collected by GC.
+ void RemoveAll(Predicate match = null, bool releaseEventHandlers = true);
+
Int32 Count { get; }
Boolean Contains(IXLRange range);
diff --git a/ClosedXML/Excel/Ranges/XLRanges.cs b/ClosedXML/Excel/Ranges/XLRanges.cs
index 1acc4a7..a57186c 100644
--- a/ClosedXML/Excel/Ranges/XLRanges.cs
+++ b/ClosedXML/Excel/Ranges/XLRanges.cs
@@ -45,6 +45,27 @@
_ranges.RemoveAll(r => r.ToString() == range.ToString());
}
+ ///
+ /// Removes ranges matching the criteria from the collection, optionally releasing their event handlers.
+ ///
+ /// Criteria to filter ranges. Only those ranges that satisfy the criteria will be removed.
+ /// Null means the entire collection should be cleared.
+ /// Specify whether or not should removed ranges be unsubscribed from
+ /// row/column shifting events. Until ranges are unsubscribed they cannot be collected by GC.
+ public void RemoveAll(Predicate match = null, bool releaseEventHandlers = true)
+ {
+ match = match ?? (_ => true);
+
+ if (releaseEventHandlers)
+ {
+ _ranges
+ .Where(r => match(r))
+ .ForEach(r => r.Dispose());
+ }
+
+ Count -= _ranges.RemoveAll(match);
+ }
+
public int Count { get; private set; }
public IEnumerator GetEnumerator()
diff --git a/ClosedXML/Excel/Rows/XLRow.cs b/ClosedXML/Excel/Rows/XLRow.cs
index 53e4008..9e263b7 100644
--- a/ClosedXML/Excel/Rows/XLRow.cs
+++ b/ClosedXML/Excel/Rows/XLRow.cs
@@ -71,7 +71,7 @@
yield return cell.Style;
}
}
-
+
protected override IEnumerable Children
{
get
@@ -280,6 +280,7 @@
public IXLRow AdjustToContents(Int32 startColumn, Int32 endColumn, Double minHeight, Double maxHeight)
{
var fontCache = new Dictionary();
+
Double rowMaxHeight = minHeight;
foreach (XLCell c in from XLCell c in Row(startColumn, endColumn).CellsUsed() where !c.IsMerged() select c)
{
diff --git a/ClosedXML/Excel/SaveOptions.cs b/ClosedXML/Excel/SaveOptions.cs
index 7dcd9a1..62edb53 100644
--- a/ClosedXML/Excel/SaveOptions.cs
+++ b/ClosedXML/Excel/SaveOptions.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace ClosedXML.Excel
{
@@ -19,6 +15,7 @@
this.EvaluateFormulasBeforeSaving = false;
this.GenerateCalculationChain = true;
}
+
public Boolean ValidatePackage;
public Boolean EvaluateFormulasBeforeSaving;
public Boolean GenerateCalculationChain;
diff --git a/ClosedXML/Excel/Style/Colors/XLColor_Static.cs b/ClosedXML/Excel/Style/Colors/XLColor_Static.cs
index 1f1f65f..c4628bc 100644
--- a/ClosedXML/Excel/Style/Colors/XLColor_Static.cs
+++ b/ClosedXML/Excel/Style/Colors/XLColor_Static.cs
@@ -42,10 +42,12 @@
return FromColor(Color.FromArgb(a, r, g, b));
}
+#if _NETFRAMEWORK_
public static XLColor FromKnownColor(KnownColor color)
{
return FromColor(Color.FromKnownColor(color));
}
+#endif
public static XLColor FromName(String name)
{
diff --git a/ClosedXML/Excel/Tables/XLTable.cs b/ClosedXML/Excel/Tables/XLTable.cs
index 97f5c5f..528eb6d 100644
--- a/ClosedXML/Excel/Tables/XLTable.cs
+++ b/ClosedXML/Excel/Tables/XLTable.cs
@@ -219,13 +219,39 @@
get { return _name; }
set
{
- if (Worksheet.Tables.Any(t => t.Name == value))
- {
- throw new ArgumentException(String.Format("This worksheet already contains a table named '{0}'",
- value));
- }
+ if (_name == value) return;
+
+ // Validation rules for table names
+ var oldname = _name ?? string.Empty;
+
+ if (String.IsNullOrWhiteSpace(value))
+ throw new ArgumentException($"The table name '{value}' is invalid");
+
+ // Table names are case insensitive
+ if (!oldname.Equals(value, StringComparison.OrdinalIgnoreCase)
+ && Worksheet.Tables.Any(t => t.Name.Equals(value, StringComparison.OrdinalIgnoreCase)))
+ throw new ArgumentException($"This worksheet already contains a table named '{value}'");
+
+ if (value[0] != '_' && !char.IsLetter(value[0]))
+ throw new ArgumentException($"The table name '{value}' does not begin with a letter or an underscore");
+
+ if (value.Length > 255)
+ throw new ArgumentException("The table name is more than 255 characters");
+
+ if (new[] { 'C', 'R' }.Any(c => value.ToUpper().Equals(c.ToString())))
+ throw new ArgumentException($"The table name '{value}' is invalid");
_name = value;
+
+ // Some totals row formula depend on the table name. Update them.
+ if (_fieldNames?.Any() ?? false)
+ this.Fields.ForEach(f => (f as XLTableField).UpdateTableFieldTotalsRowFormula());
+
+ if (!String.IsNullOrWhiteSpace(oldname))
+ {
+ Worksheet.Tables.Add(this);
+ Worksheet.Tables.Remove(oldname);
+ }
}
}
@@ -337,6 +363,8 @@
var existingHeaders = this.FieldNames.Keys;
var newHeaders = new HashSet();
+
+ // Force evaluation of f.Column field
var tempArray = this.Fields.Select(f => f.Column).ToArray();
var firstRow = range.Row(1);
@@ -391,7 +419,7 @@
{
foreach (var f in this._fieldNames.Values.Cast())
{
- f.UpdateUnderlyingCellFormula();
+ f.UpdateTableFieldTotalsRowFormula();
var c = this.TotalsRow().Cell(f.Index + 1);
if (!String.IsNullOrWhiteSpace(f.TotalsRowLabel))
{
diff --git a/ClosedXML/Excel/Tables/XLTableField.cs b/ClosedXML/Excel/Tables/XLTableField.cs
index 893d3ff..dabb701 100644
--- a/ClosedXML/Excel/Tables/XLTableField.cs
+++ b/ClosedXML/Excel/Tables/XLTableField.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@@ -89,7 +90,7 @@
set
{
totalsRowFunction = value;
- UpdateUnderlyingCellFormula();
+ UpdateTableFieldTotalsRowFormula();
}
}
@@ -173,25 +174,37 @@
return distinctStyles.Count() == 1;
}
- internal void UpdateUnderlyingCellFormula()
+ private static IEnumerable QuotedTableFieldCharacters = new[] { "'", "#" };
+
+ internal void UpdateTableFieldTotalsRowFormula()
{
if (TotalsRowFunction != XLTotalsRowFunction.None && TotalsRowFunction != XLTotalsRowFunction.Custom)
{
var cell = table.TotalsRow().Cell(Index + 1);
- String formula = String.Empty;
+ var formulaCode = String.Empty;
switch (TotalsRowFunction)
{
- case XLTotalsRowFunction.Sum: formula = "109"; break;
- case XLTotalsRowFunction.Minimum: formula = "105"; break;
- case XLTotalsRowFunction.Maximum: formula = "104"; break;
- case XLTotalsRowFunction.Average: formula = "101"; break;
- case XLTotalsRowFunction.Count: formula = "103"; break;
- case XLTotalsRowFunction.CountNumbers: formula = "102"; break;
- case XLTotalsRowFunction.StandardDeviation: formula = "107"; break;
- case XLTotalsRowFunction.Variance: formula = "110"; break;
+ case XLTotalsRowFunction.Sum: formulaCode = "109"; break;
+ case XLTotalsRowFunction.Minimum: formulaCode = "105"; break;
+ case XLTotalsRowFunction.Maximum: formulaCode = "104"; break;
+ case XLTotalsRowFunction.Average: formulaCode = "101"; break;
+ case XLTotalsRowFunction.Count: formulaCode = "103"; break;
+ case XLTotalsRowFunction.CountNumbers: formulaCode = "102"; break;
+ case XLTotalsRowFunction.StandardDeviation: formulaCode = "107"; break;
+ case XLTotalsRowFunction.Variance: formulaCode = "110"; break;
}
- cell.FormulaA1 = "SUBTOTAL(" + formula + ",[" + Name + "])";
+ var modifiedName = Name;
+ QuotedTableFieldCharacters.ForEach(c => modifiedName = modifiedName.Replace(c, "'" + c));
+
+ if (modifiedName.StartsWith(" ") || modifiedName.EndsWith(" "))
+ {
+ modifiedName = "[" + modifiedName + "]";
+ }
+
+ var prependTableName = modifiedName.Contains(" ");
+
+ cell.FormulaA1 = $"SUBTOTAL({formulaCode},{(prependTableName ? table.Name : string.Empty)}[{modifiedName}])";
var lastCell = table.LastRow().Cell(Index + 1);
if (lastCell.DataType != XLDataType.Text)
{
diff --git a/ClosedXML/Excel/XLWorkbook.cs b/ClosedXML/Excel/XLWorkbook.cs
index 59059b1..f64c655 100644
--- a/ClosedXML/Excel/XLWorkbook.cs
+++ b/ClosedXML/Excel/XLWorkbook.cs
@@ -434,7 +434,6 @@
{
CopyStream(_originalStream, fileStream);
CreatePackage(fileStream, false, _spreadsheetDocumentType, options);
- fileStream.Close();
}
}
@@ -527,7 +526,6 @@
using (var fileStream = new FileStream(_originalFile, FileMode.Open, FileAccess.Read))
{
CopyStream(fileStream, stream);
- fileStream.Close();
}
CreatePackage(stream, false, _spreadsheetDocumentType, options);
}
diff --git a/ClosedXML/Excel/XLWorkbook_ImageHandling.cs b/ClosedXML/Excel/XLWorkbook_ImageHandling.cs
index 9dbaf3e..8ea8d29 100644
--- a/ClosedXML/Excel/XLWorkbook_ImageHandling.cs
+++ b/ClosedXML/Excel/XLWorkbook_ImageHandling.cs
@@ -43,13 +43,13 @@
if (!IsAllowedAnchor(anchor))
return null;
- var picture = anchor
- .Descendants()
- .FirstOrDefault();
+ // Maybe we should not restrict here, and just search for all NonVisualDrawingProperties in an anchor?
+ var shape = anchor.Descendants().Cast().FirstOrDefault()
+ ?? anchor.Descendants().Cast().FirstOrDefault();
- if (picture == null) return null;
+ if (shape == null) return null;
- return picture
+ return shape
.Descendants()
.FirstOrDefault();
}
diff --git a/ClosedXML/Excel/XLWorkbook_Load.cs b/ClosedXML/Excel/XLWorkbook_Load.cs
index 5e311d9..7ca1145 100644
--- a/ClosedXML/Excel/XLWorkbook_Load.cs
+++ b/ClosedXML/Excel/XLWorkbook_Load.cs
@@ -1,5 +1,3 @@
-#region
-
using ClosedXML.Extensions;
using ClosedXML.Utils;
using DocumentFormat.OpenXml;
@@ -17,19 +15,13 @@
using Op = DocumentFormat.OpenXml.CustomProperties;
using Xdr = DocumentFormat.OpenXml.Drawing.Spreadsheet;
-#endregion
-
namespace ClosedXML.Excel
{
- #region
-
using Ap;
using Drawings;
using Op;
using System.Drawing;
- #endregion
-
public partial class XLWorkbook
{
private readonly Dictionary _colorList = new Dictionary();
@@ -362,7 +354,7 @@
xlTable.AutoFilter.Range = xlTable.Worksheet.Range(xlTable.RangeAddress);
}
- #endregion
+ #endregion LoadTables
LoadDrawings(worksheetPart, ws);
@@ -418,7 +410,7 @@
}
}
- #endregion
+ #endregion LoadComments
}
var workbook = dSpreadsheet.WorkbookPart.Workbook;
@@ -760,7 +752,7 @@
}
}
- #endregion
+ #endregion Pivot tables
}
private static void LoadFieldOptions(PivotField pf, IXLPivotField pivotField)
@@ -825,10 +817,12 @@
var imagePart = drawingsPart.GetPartById(imgId);
using (var stream = imagePart.GetStream())
+ using (var ms = new MemoryStream())
{
+ stream.CopyTo(ms);
var vsdp = GetPropertiesFromAnchor(anchor);
- var picture = (ws as XLWorksheet).AddPicture(stream, vsdp.Name, Convert.ToInt32(vsdp.Id.Value)) as XLPicture;
+ var picture = (ws as XLWorksheet).AddPicture(ms, vsdp.Name, Convert.ToInt32(vsdp.Id.Value)) as XLPicture;
picture.RelId = imgId;
Xdr.ShapeProperties spPr = anchor.Descendants().First();
@@ -940,7 +934,7 @@
return shape;
}
- #endregion
+ #endregion Comment Helpers
private String GetTableColumnName(string name)
{
@@ -1544,7 +1538,7 @@
LoadFont(pp, xlCell.RichText.Phonetics);
}
- #endregion
+ #endregion Load PhoneticProperties
#region Load Phonetic Runs
@@ -1554,7 +1548,7 @@
(Int32)pr.EndingBaseIndex.Value);
}
- #endregion
+ #endregion Load Phonetic Runs
}
private void LoadNumberFormat(NumberingFormat nfSource, IXLNumberFormat nf)
@@ -1875,7 +1869,7 @@
{
case XLFilterOperator.Equal:
if (isText)
- condition = o => o.ToString().Equals(xlFilter.Value.ToString(), StringComparison.InvariantCultureIgnoreCase);
+ condition = o => o.ToString().Equals(xlFilter.Value.ToString(), StringComparison.OrdinalIgnoreCase);
else
condition = o => (o as IComparable).CompareTo(xlFilter.Value) == 0;
break;
@@ -1886,7 +1880,7 @@
case XLFilterOperator.LessThan: condition = o => (o as IComparable).CompareTo(xlFilter.Value) < 0; break;
case XLFilterOperator.NotEqual:
if (isText)
- condition = o => !o.ToString().Equals(xlFilter.Value.ToString(), StringComparison.InvariantCultureIgnoreCase);
+ condition = o => !o.ToString().Equals(xlFilter.Value.ToString(), StringComparison.OrdinalIgnoreCase);
else
condition = o => (o as IComparable).CompareTo(xlFilter.Value) != 0;
break;
@@ -1929,7 +1923,7 @@
if (isText)
{
xlFilter.Value = filter.Val.Value;
- condition = o => o.ToString().Equals(xlFilter.Value.ToString(), StringComparison.InvariantCultureIgnoreCase);
+ condition = o => o.ToString().Equals(xlFilter.Value.ToString(), StringComparison.OrdinalIgnoreCase);
}
else
{
@@ -2185,7 +2179,7 @@
var id = fr.Descendants().FirstOrDefault();
if (id != null && id.Text != null && !String.IsNullOrWhiteSpace(id.Text))
- conditionalFormat.Id = Guid.Parse(id.Text.Substring(1, id.Text.Length - 2));
+ conditionalFormat.Id = new Guid(id.Text.Substring(1, id.Text.Length - 2));
ExtractConditionalFormatValueObjects(conditionalFormat, dataBar);
}
diff --git a/ClosedXML/Excel/XLWorkbook_Save.cs b/ClosedXML/Excel/XLWorkbook_Save.cs
index 1c68c90..fa3e568 100644
--- a/ClosedXML/Excel/XLWorkbook_Save.cs
+++ b/ClosedXML/Excel/XLWorkbook_Save.cs
@@ -104,7 +104,7 @@
if (errors.Any())
{
- var message = string.Join("\r\n", errors.Select(e => string.Format("{0} in {1}", e.Description, e.Path.XPath)).ToArray());
+ var message = string.Join("\r\n", errors.Select(e => string.Format("Part {0}, Path {1}: {2}", e.Part.Uri, e.Path.XPath, e.Description)).ToArray());
throw new ApplicationException(message);
}
return true;
@@ -358,7 +358,8 @@
// Only delete the VmlDrawingParts for comments.
if (vmlDrawingPart != null)
{
- var xdoc = XDocumentExtensions.Load(vmlDrawingPart.GetStream(FileMode.Open));
+ var vmlStream = vmlDrawingPart.GetStream(FileMode.Open);
+ var xdoc = XDocumentExtensions.Load(vmlStream);
//xdoc.Root.Elements().Where(e => e.Name.LocalName == "shapelayout").Remove();
xdoc.Root.Elements().Where(
e => e.Name.LocalName == "shapetype" && (string)e.Attribute("id") == @"_x0000_t202").Remove();
@@ -388,6 +389,7 @@
legacyParts.ForEach(p => vmlDrawingPartNew.AddPart(p, vmlDrawingPart.GetIdOfPart(p)));
}
+ vmlStream.Close();
worksheetPart.DeletePart(vmlDrawingPart);
if (hasNewPart && rId != worksheetPart.GetIdOfPart(vmlDrawingPartNew))
@@ -1800,6 +1802,20 @@
var modified = Properties.Modified == DateTime.MinValue ? DateTime.Now : Properties.Modified;
document.PackageProperties.Created = created;
document.PackageProperties.Modified = modified;
+
+#if true // Workaround: https://github.com/OfficeDev/Open-XML-SDK/issues/235
+
+ if (Properties.LastModifiedBy == null) document.PackageProperties.LastModifiedBy = "";
+ if (Properties.Author == null) document.PackageProperties.Creator = "";
+ if (Properties.Title == null) document.PackageProperties.Title = "";
+ if (Properties.Subject == null) document.PackageProperties.Subject = "";
+ if (Properties.Category == null) document.PackageProperties.Category = "";
+ if (Properties.Keywords == null) document.PackageProperties.Keywords = "";
+ if (Properties.Comments == null) document.PackageProperties.Description = "";
+ if (Properties.Status == null) document.PackageProperties.ContentStatus = "";
+
+#endif
+
document.PackageProperties.LastModifiedBy = Properties.LastModifiedBy;
document.PackageProperties.Creator = Properties.Author;
@@ -2190,7 +2206,7 @@
var pivotCacheRecords = new PivotCacheRecords();
pivotCacheRecords.AddNamespaceDeclaration("r",
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
pivotTableCacheRecordsPart.PivotCacheRecords = pivotCacheRecords;
context.PivotTables.Add(pti.Guid, pti);
@@ -2772,9 +2788,10 @@
SaveContext context)
{
var ms = new MemoryStream();
- CopyStream(vmlDrawingPart.GetStream(FileMode.OpenOrCreate), ms);
+ var stream = vmlDrawingPart.GetStream(FileMode.OpenOrCreate);
+ CopyStream(stream, ms);
ms.Position = 0;
- var writer = new XmlTextWriter(vmlDrawingPart.GetStream(FileMode.Create), Encoding.UTF8);
+ var writer = new XmlTextWriter(stream, Encoding.UTF8);
writer.WriteStartElement("xml");
@@ -2964,8 +2981,8 @@
},
new Xdr.Picture(
new Xdr.NonVisualPictureProperties(
- new Xdr.NonVisualDrawingProperties { Id = nvpId, Name = pic.Name },
- new Xdr.NonVisualPictureDrawingProperties(new PictureLocks { NoChangeAspect = true })
+ new Xdr.NonVisualDrawingProperties { Id = nvpId, Name = pic.Name },
+ new Xdr.NonVisualPictureDrawingProperties(new PictureLocks { NoChangeAspect = true })
),
new Xdr.BlipFill(
new Blip { Embed = drawingsPart.GetIdOfPart(imagePart), CompressionState = BlipCompressionValues.Print },
@@ -2987,6 +3004,7 @@
case Drawings.XLPicturePlacement.MoveAndSize:
var moveAndSizeFromMarker = pic.Markers[Drawings.XLMarkerPosition.TopLeft];
+ if (moveAndSizeFromMarker == null) moveAndSizeFromMarker = new Drawings.XLMarker(picture.Worksheet.Cell("A1").Address);
fMark = new Xdr.FromMarker
{
ColumnId = new Xdr.ColumnId((moveAndSizeFromMarker.Address.ColumnNumber - 1).ToString()),
@@ -2996,6 +3014,7 @@
};
var moveAndSizeToMarker = pic.Markers[Drawings.XLMarkerPosition.BottomRight];
+ if (moveAndSizeToMarker == null) moveAndSizeToMarker = new Drawings.XLMarker(picture.Worksheet.Cell("A1").Address, new System.Drawing.Point(picture.Width, picture.Height));
tMark = new Xdr.ToMarker
{
ColumnId = new Xdr.ColumnId((moveAndSizeToMarker.Address.ColumnNumber - 1).ToString()),
@@ -3032,6 +3051,7 @@
case Drawings.XLPicturePlacement.Move:
var moveFromMarker = pic.Markers[Drawings.XLMarkerPosition.TopLeft];
+ if (moveFromMarker == null) moveFromMarker = new Drawings.XLMarker(picture.Worksheet.Cell("A1").Address);
fMark = new Xdr.FromMarker
{
ColumnId = new Xdr.ColumnId((moveFromMarker.Address.ColumnNumber - 1).ToString()),
@@ -3072,14 +3092,22 @@
}
}
- private static void RebasePictureIds(WorksheetPart worksheetPart)
+ // Still not fully implemented for all shapes
+ private static void RebaseShapeIds(WorksheetPart worksheetPart)
{
- for (var i = 0; i < worksheetPart.DrawingsPart.WorksheetDrawing.ChildElements.Count; i++)
+ var worksheetDrawing = worksheetPart.DrawingsPart.WorksheetDrawing;
+ for (var i = 0; i < worksheetDrawing.ChildElements.Count; i++)
{
- var anchor = worksheetPart.DrawingsPart.WorksheetDrawing.ElementAt(i);
+ var anchor = worksheetDrawing.ElementAt(i);
var props = GetPropertiesFromAnchor(anchor);
if (props != null)
- props.Id = Convert.ToUInt32(i + 1);
+ {
+ var offset = 1;
+ while (worksheetDrawing.Descendants().Any(p => p.Id == Convert.ToUInt32(i + offset)))
+ offset++;
+
+ props.Id = Convert.ToUInt32(i + offset);
+ }
}
}
@@ -3242,7 +3270,7 @@
{
xlStyles.Add(s);
}
-
+
foreach (var s in worksheet.Internals.CellsCollection.GetCells().Select(c => c.StyleValue))
{
xlStyles.Add(s);
@@ -3252,13 +3280,12 @@
pivotTableNumberFormats.Add(ptnf);
}
- var alignments = xlStyles.Select(s => s.Alignment).Distinct().ToList();
- var borders = xlStyles.Select(s => s.Border).Distinct().ToList();
- var fonts = xlStyles.Select(s => s.Font).Distinct().ToList();
- var fills = xlStyles.Select(s => s.Fill).Distinct().ToList();
+ var alignments = xlStyles.Select(s => s.Alignment).Distinct().ToList();
+ var borders = xlStyles.Select(s => s.Border).Distinct().ToList();
+ var fonts = xlStyles.Select(s => s.Font).Distinct().ToList();
+ var fills = xlStyles.Select(s => s.Fill).Distinct().ToList();
var numberFormats = xlStyles.Select(s => s.NumberFormat).Distinct().ToList();
- var protections = xlStyles.Select(s => s.Protection).Distinct().ToList();
-
+ var protections = xlStyles.Select(s => s.Protection).Distinct().ToList();
for (int i = 0; i < fonts.Count; i++)
{
@@ -3378,8 +3405,6 @@
{
foreach (var cf in ws.ConditionalFormats)
{
- //var ie = context.DifferentialFormats.Keys.First().Equals(cf.Style);
-
if (!cf.Style.Value.Equals(DefaultStyle.Value) && !context.DifferentialFormats.ContainsKey(cf.Style.Value.Key))
AddConditionalDifferentialFormat(workbookStylesPart.Stylesheet.DifferentialFormats, cf, context);
}
@@ -3419,7 +3444,7 @@
LoadBorder(df.Border, emptyContainer.Style.Border);
LoadNumberFormat(df.NumberingFormat, emptyContainer.Style.NumberFormat);
LoadFill(df.Fill, emptyContainer.Style.Fill, differentialFillFormat: true);
-
+
if (!dictionary.ContainsKey(emptyContainer.StyleValue.Key))
dictionary.Add(emptyContainer.StyleValue.Key, id++);
}
@@ -3490,11 +3515,11 @@
differentialFormat.Append(numberFormat);
}
- var diffFill = GetNewFill(new FillInfo {Fill = style.Fill}, differentialFillFormat: true, ignoreMod: false);
+ var diffFill = GetNewFill(new FillInfo { Fill = style.Fill }, differentialFillFormat: true, ignoreMod: false);
if (diffFill?.HasChildren ?? false)
differentialFormat.Append(diffFill);
- var diffBorder = GetNewBorder(new BorderInfo {Border = style.Border}, false);
+ var diffBorder = GetNewBorder(new BorderInfo { Border = style.Border }, false);
if (diffBorder?.HasChildren ?? false)
differentialFormat.Append(diffBorder);
@@ -3619,7 +3644,7 @@
&& f.FillId != null && styleInfo.FillId == f.FillId
&& f.FontId != null && styleInfo.FontId == f.FontId
&& f.NumberFormatId != null && styleInfo.NumberFormatId == f.NumberFormatId
- && (f.ApplyFill == null && styleInfo.Style.Fill == XLFillValue.Default ||
+ && (f.ApplyFill == null && styleInfo.Style.Fill == XLFillValue.Default ||
f.ApplyFill != null && f.ApplyFill == ApplyFill(styleInfo))
&& (f.ApplyBorder == null && styleInfo.Style.Border == XLBorderValue.Default ||
f.ApplyBorder != null && f.ApplyBorder == ApplyBorder(styleInfo))
@@ -3764,10 +3789,10 @@
var DiagonalBorder = new DiagonalBorder { Style = borderInfo.Border.DiagonalBorder.ToOpenXml() };
if (borderInfo.Border.DiagonalBorderColor != XLBorderValue.Default.DiagonalBorderColor || ignoreMod)
if (borderInfo.Border.DiagonalBorderColor != null)
- {
- var DiagonalBorderColor = GetNewColor(borderInfo.Border.DiagonalBorderColor);
- DiagonalBorder.AppendChild(DiagonalBorderColor);
- }
+ {
+ var DiagonalBorderColor = GetNewColor(borderInfo.Border.DiagonalBorderColor);
+ DiagonalBorder.AppendChild(DiagonalBorderColor);
+ }
border.AppendChild(DiagonalBorder);
}
@@ -4062,7 +4087,7 @@
var verticalAlignment = fontInfo.Font.VerticalAlignment != XLFontValue.Default.VerticalAlignment || ignoreMod
? new VerticalTextAlignment { Val = fontInfo.Font.VerticalAlignment.ToOpenXml() }
: null;
-
+
var shadow = (fontInfo.Font.Shadow != XLFontValue.Default.Shadow || ignoreMod) && fontInfo.Font.Shadow ? new Shadow() : null;
var fontSize = fontInfo.Font.FontSize != XLFontValue.Default.FontSize || ignoreMod
? new FontSize { Val = fontInfo.Font.FontSize }
@@ -4425,7 +4450,8 @@
return range.RangeAddress.FirstAddress.ToStringRelative(false);
else
return range.RangeAddress.ToStringRelative(false);
- }));
+ })
+ );
selection.SequenceOfReferences = new ListValue { InnerText = String.Join(" ", seqRef.Distinct().ToArray()) };
@@ -5426,7 +5452,7 @@
}
if (xlWorksheet.Pictures.Any())
- RebasePictureIds(worksheetPart);
+ RebaseShapeIds(worksheetPart);
var tableParts = worksheetPart.Worksheet.Elements().First();
if (xlWorksheet.Pictures.Any() && !worksheetPart.Worksheet.OfType().Any())
diff --git a/ClosedXML/Excel/XLWorksheet.cs b/ClosedXML/Excel/XLWorksheet.cs
index b0648cd..5775416 100644
--- a/ClosedXML/Excel/XLWorksheet.cs
+++ b/ClosedXML/Excel/XLWorksheet.cs
@@ -184,7 +184,7 @@
set
{
if (value > Workbook.WorksheetsInternal.Count + Workbook.UnsupportedSheets.Count + 1)
- throw new IndexOutOfRangeException("Index must be equal or less than the number of worksheets + 1.");
+ throw new ArgumentOutOfRangeException(nameof(value), "Index must be equal or less than the number of worksheets + 1.");
if (value < _position)
{
diff --git a/ClosedXML/Extensions.cs b/ClosedXML/Extensions.cs
index 8836f26..5d14a91 100644
--- a/ClosedXML/Extensions.cs
+++ b/ClosedXML/Extensions.cs
@@ -213,47 +213,25 @@
public static class FontBaseExtensions
{
- private static Font GetCachedFont(IXLFontBase fontBase, Dictionary fontCache)
- {
- Font font;
- if (!fontCache.TryGetValue(fontBase, out font))
- {
- font = new Font(fontBase.FontName, (float)fontBase.FontSize, GetFontStyle(fontBase));
- fontCache.Add(fontBase, font);
- }
- return font;
- }
-
public static Double GetWidth(this IXLFontBase fontBase, String text, Dictionary fontCache)
{
if (String.IsNullOrWhiteSpace(text))
return 0;
var font = GetCachedFont(fontBase, fontCache);
+ var textWidth = GraphicsUtils.MeasureString(text, font).Width;
- var textSize = GraphicsUtils.MeasureString(text, font);
-
- double width = (((textSize.Width / (double)7) * 256) - (128 / 7)) / 256;
+ double width = (textWidth / 7d * 256 - 128 / 7) / 256;
width = Math.Round(width + 0.2, 2);
return width;
}
- private static FontStyle GetFontStyle(IXLFontBase font)
- {
- FontStyle fontStyle = FontStyle.Regular;
- if (font.Bold) fontStyle |= FontStyle.Bold;
- if (font.Italic) fontStyle |= FontStyle.Italic;
- if (font.Strikethrough) fontStyle |= FontStyle.Strikeout;
- if (font.Underline != XLFontUnderlineValues.None) fontStyle |= FontStyle.Underline;
- return fontStyle;
- }
-
public static Double GetHeight(this IXLFontBase fontBase, Dictionary fontCache)
{
var font = GetCachedFont(fontBase, fontCache);
- var textSize = GraphicsUtils.MeasureString("X", font);
- return (double)textSize.Height * 0.85;
+ var textHeight = GraphicsUtils.MeasureString("X", font).Height;
+ return (double)textHeight * 0.85;
}
public static void CopyFont(this IXLFontBase font, IXLFontBase sourceFont)
@@ -270,6 +248,27 @@
font.FontFamilyNumbering = sourceFont.FontFamilyNumbering;
font.FontCharSet = sourceFont.FontCharSet;
}
+
+ private static Font GetCachedFont(IXLFontBase fontBase, Dictionary fontCache)
+ {
+ Font font;
+ if (!fontCache.TryGetValue(fontBase, out font))
+ {
+ font = new Font(fontBase.FontName, (float)fontBase.FontSize, GetFontStyle(fontBase));
+ fontCache.Add(fontBase, font);
+ }
+ return font;
+ }
+
+ private static FontStyle GetFontStyle(IXLFontBase font)
+ {
+ FontStyle fontStyle = FontStyle.Regular;
+ if (font.Bold) fontStyle |= FontStyle.Bold;
+ if (font.Italic) fontStyle |= FontStyle.Italic;
+ if (font.Strikethrough) fontStyle |= FontStyle.Strikeout;
+ if (font.Underline != XLFontUnderlineValues.None) fontStyle |= FontStyle.Underline;
+ return fontStyle;
+ }
}
public static class XDocumentExtensions
diff --git a/ClosedXML/Properties/AssemblyInfo.cs b/ClosedXML/Properties/AssemblyInfo.cs
index 92b76d7..ddf1df5 100644
--- a/ClosedXML/Properties/AssemblyInfo.cs
+++ b/ClosedXML/Properties/AssemblyInfo.cs
@@ -1,24 +1 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ClosedXML")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ClosedXML")]
-[assembly: AssemblyCopyright("Copyright © Manuel De Leon 2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("8747331d-de58-4621-8c7f-a7d57ca3467a")]
-
-[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("ClosedXML_Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a1fb8ba59167fe734d64128ca73d32c45cb8a117246d09c95c8769db88fe332b0a3396bedd0ea48ee42b0e5796fec0798ca5cb628a9a6de80d35d6c67b936ca1670347b3d4f2b769c8ce2ddcf959dbac6bcd88e6c08751ea1fffa0522de3507193e7035305a8aa008d6c88cca1341b3120fa9c347ab3f97e2d772e2709277da5")]
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("ClosedXML_Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a1fb8ba59167fe734d64128ca73d32c45cb8a117246d09c95c8769db88fe332b0a3396bedd0ea48ee42b0e5796fec0798ca5cb628a9a6de80d35d6c67b936ca1670347b3d4f2b769c8ce2ddcf959dbac6bcd88e6c08751ea1fffa0522de3507193e7035305a8aa008d6c88cca1341b3120fa9c347ab3f97e2d772e2709277da5")]
diff --git a/ClosedXML/Properties/AssemblyVersionInfo.cs b/ClosedXML/Properties/AssemblyVersionInfo.cs
deleted file mode 100644
index da0403f..0000000
--- a/ClosedXML/Properties/AssemblyVersionInfo.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Reflection;
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-[assembly: AssemblyVersion("0.92.0.0")]
-[assembly: AssemblyFileVersion("0.92.0.0")]
-[assembly: AssemblyInformationalVersion("0.92.0")]
diff --git a/ClosedXML/Utils/GraphicsUtils.cs b/ClosedXML/Utils/GraphicsUtils.cs
index be2472f..f0f7644 100644
--- a/ClosedXML/Utils/GraphicsUtils.cs
+++ b/ClosedXML/Utils/GraphicsUtils.cs
@@ -7,6 +7,7 @@
{
[ThreadStatic]
private static Graphics threadLocalGraphics;
+
internal static Graphics Graphics
{
get
@@ -20,9 +21,10 @@
}
}
+ private static StringFormat defaultStringFormat = StringFormat.GenericTypographic;
public static SizeF MeasureString(string s, Font font)
{
- SizeF result = Graphics.MeasureString(s, font, Int32.MaxValue, StringFormat.GenericTypographic);
+ SizeF result = Graphics.MeasureString(s, font, Int32.MaxValue, defaultStringFormat);
return result;
}
}
diff --git a/ClosedXML/XLHelper.cs b/ClosedXML/XLHelper.cs
index 1c1081d..5bb1bd5 100644
--- a/ClosedXML/XLHelper.cs
+++ b/ClosedXML/XLHelper.cs
@@ -1,12 +1,11 @@
using System;
+using System.Drawing;
using System.Globalization;
+using System.Linq;
+using System.Text.RegularExpressions;
namespace ClosedXML.Excel
{
- using System.Drawing;
- using System.Linq;
- using System.Text.RegularExpressions;
-
///
/// Common methods
///
@@ -19,7 +18,8 @@
public const String MaxColumnLetter = "XFD";
public const Double Epsilon = 1e-10;
- private const Int32 TwoT26 = 26 * 26;
+ private const Int32 TwoT26 = 26*26;
+
internal static readonly Graphics Graphic = Graphics.FromImage(new Bitmap(200, 200));
internal static readonly Double DpiX = Graphic.DpiX;
internal static readonly NumberStyles NumberStyle = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowExponent;
@@ -226,6 +226,19 @@
return rows;
}
+#if false
+// Not using this anymore, but keeping it around for in case we bring back .NET3.5 support.
+ public static bool IsNullOrWhiteSpace(string value)
+ {
+#if _NET35_
+ if (value == null) return true;
+ return value.All(c => char.IsWhiteSpace(c));
+#else
+ return String.IsNullOrWhiteSpace(value);
+#endif
+ }
+#endif
+
private static readonly Regex A1RegexRelative = new Regex(
@"(?<=\W)(?\$?[a-zA-Z]{1,3}\$?\d{1,7})(?=\W)" // A1
+ @"|(?<=\W)(?\$?\d{1,7}:\$?\d{1,7})(?=\W)" // 1:1
diff --git a/ClosedXML/packages.config b/ClosedXML/packages.config
deleted file mode 100644
index 3f21e14..0000000
--- a/ClosedXML/packages.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/ClosedXML_Examples/ClosedXML_Examples.csproj b/ClosedXML_Examples/ClosedXML_Examples.csproj
index dca9ada..bcbad93 100644
--- a/ClosedXML_Examples/ClosedXML_Examples.csproj
+++ b/ClosedXML_Examples/ClosedXML_Examples.csproj
@@ -1,208 +1,38 @@
-
-
+
+
- Debug
- x86
- 8.0.30703
- 2.0
- {03A518D0-1CB7-488E-861C-C4E782B27A46}
+ netcoreapp2.0;net40;net46
Exe
- Properties
- ClosedXML_Examples
- ClosedXML_Examples
- v4.0
-
-
- 512
- ..\
- true
-
-
- true
- bin\Debug\
- DEBUG;TRACE
- full
- AnyCPU
- prompt
- false
- 6
-
-
- bin\Release\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- false
- 6
-
-
- ClosedXML_Examples.Program
-
-
+ 0.93.0
true
-
-
ClosedXML.snk
+ $(NoWarn);NU1605
-
- true
+
+
+ $(DefineConstants);_NETSTANDARD_;_NETSTANDARD2_0_
+
+
+ $(DefineConstants);_NETFRAMEWORK_;_NET40_
+
+
+
+ $(DefineConstants);_NETFRAMEWORK_;_NET46_
+
+
-
- ..\packages\DocumentFormat.OpenXml.2.7.2\lib\net40\DocumentFormat.OpenXml.dll
- True
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
- Properties\AssemblyVersionInfo.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
- .editorconfig
-
-
-
-
+
+
-
-
- {BD5E6BFE-E837-4A35-BCA9-39667D873A20}
- ClosedXML
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
diff --git a/ClosedXML_Examples/Properties/AssemblyInfo.cs b/ClosedXML_Examples/Properties/AssemblyInfo.cs
deleted file mode 100644
index c7e7b8b..0000000
--- a/ClosedXML_Examples/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ClosedXML_Examples")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("ClosedXML_Examples")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("603cd89c-23f2-415e-8afc-2e9ab7a4c372")]
diff --git a/ClosedXML_Examples/Styles/UsingColors.cs b/ClosedXML_Examples/Styles/UsingColors.cs
index 9364c15..54fea8f 100644
--- a/ClosedXML_Examples/Styles/UsingColors.cs
+++ b/ClosedXML_Examples/Styles/UsingColors.cs
@@ -61,12 +61,6 @@
ro++;
- // FromKnownColor(KnownColor knownColor)
- ws.Cell(++ro, 1).Style.Fill.BackgroundColor = XLColor.FromKnownColor(KnownColor.Plum);
- ws.Cell(ro, 2).Value = "XLColor.FromKnownColor(KnownColor.Plum)";
-
- ro++;
-
// FromName(String colorName)
ws.Cell(++ro, 1).Style.Fill.BackgroundColor = XLColor.FromName("PowderBlue");
ws.Cell(ro, 2).Value = "XLColor.FromName(\"PowderBlue\")";
@@ -87,4 +81,4 @@
wb.SaveAs(filePath);
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Examples/app.config b/ClosedXML_Examples/app.config
index 86fcc8b..21ac8f3 100644
--- a/ClosedXML_Examples/app.config
+++ b/ClosedXML_Examples/app.config
@@ -1,6 +1,6 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/ClosedXML_Examples/packages.config b/ClosedXML_Examples/packages.config
deleted file mode 100644
index becf24f..0000000
--- a/ClosedXML_Examples/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/ClosedXML_Sandbox/ClosedXML_Sandbox.csproj b/ClosedXML_Sandbox/ClosedXML_Sandbox.csproj
index 7931620..d8ea4f6 100644
--- a/ClosedXML_Sandbox/ClosedXML_Sandbox.csproj
+++ b/ClosedXML_Sandbox/ClosedXML_Sandbox.csproj
@@ -1,92 +1,44 @@
-
-
+
+
- Debug
- x86
- 8.0.30703
- 2.0
- {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}
Exe
- Properties
- ClosedXML_Sandbox
- ClosedXML_Sandbox
- v4.0
- 512
- ..\
- true
-
+ netcoreapp2.0;net40;net46
+ 0.93.0
+ $(NoWarn);NU1605
-
- true
- bin\Debug\
- DEBUG;TRACE
- full
- AnyCPU
- prompt
- false
- 6
+
+
+ $(DefineConstants);_NETSTANDARD_;_NETSTANDARD2_0_
-
- bin\Release\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- false
- 6
+
+
+ $(DefineConstants);_NETFRAMEWORK_;_NET40_
-
-
- ..\packages\DocumentFormat.OpenXml.2.7.2\lib\net40\DocumentFormat.OpenXml.dll
- True
-
-
+
+
+ $(DefineConstants);_NETFRAMEWORK_;_NET46_
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
- Properties\AssemblyVersionInfo.cs
-
-
-
-
-
+
+
+
+
-
- .editorconfig
-
-
-
-
+
+
PreserveNewest
+
-
- {bd5e6bfe-e837-4a35-bca9-39667d873a20}
- ClosedXML
-
-
- {03A518D0-1CB7-488E-861C-C4E782B27A46}
- ClosedXML_Examples
-
+
-
-
-
\ No newline at end of file
+
+
diff --git a/ClosedXML_Sandbox/Properties/AssemblyInfo.cs b/ClosedXML_Sandbox/Properties/AssemblyInfo.cs
deleted file mode 100644
index a2c5998..0000000
--- a/ClosedXML_Sandbox/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ClosedXML_Sandbox")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("ClosedXML_Sandbox")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("7a3783fd-4e1b-4c17-a745-e6bbb593bd45")]
diff --git a/ClosedXML_Sandbox/ReflectionExtensions.cs b/ClosedXML_Sandbox/ReflectionExtensions.cs
new file mode 100644
index 0000000..7229a8c
--- /dev/null
+++ b/ClosedXML_Sandbox/ReflectionExtensions.cs
@@ -0,0 +1,17 @@
+#if _NET40_
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+namespace ClosedXML_Sandbox
+{
+ internal static class ReflectionExtensions
+ {
+ public static void SetValue(this PropertyInfo info, object obj, object value)
+ {
+ info.SetValue(obj, value, null);
+ }
+ }
+}
+#endif
diff --git a/ClosedXML_Sandbox/app.config b/ClosedXML_Sandbox/app.config
index 86fcc8b..21ac8f3 100644
--- a/ClosedXML_Sandbox/app.config
+++ b/ClosedXML_Sandbox/app.config
@@ -1,6 +1,6 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/ClosedXML_Sandbox/packages.config b/ClosedXML_Sandbox/packages.config
deleted file mode 100644
index becf24f..0000000
--- a/ClosedXML_Sandbox/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/ClosedXML_Tests/ClosedXML_Tests.csproj b/ClosedXML_Tests/ClosedXML_Tests.csproj
index 43cb231..5656bfe 100644
--- a/ClosedXML_Tests/ClosedXML_Tests.csproj
+++ b/ClosedXML_Tests/ClosedXML_Tests.csproj
@@ -1,332 +1,67 @@
-
-
+
+
- Debug
- AnyCPU
-
-
- 2.0
- {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}
- Library
- Properties
- ClosedXML_Tests
- ClosedXML_Tests
- v4.5.2
- 512
- {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- ..\
- true
+ netcoreapp2.0;net40;net46
+ 0.93.0
+ false
+ $(NoWarn);NU1605
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE;$(AppVeyor)
- prompt
- 4
- false
- 6
-
-
- pdbonly
- true
- bin\Release\
- TRACE;$(AppVeyor)
- prompt
- 4
- false
- 6
-
+
+ $(AppVeyor)
true
-
-
ClosedXML.snk
+
+
+ $(DefineConstants);_NETSTANDARD_;_NETSTANDARD2_0_
+
+
+
+ $(DefineConstants);_NETFRAMEWORK_;_NET40_
+
+
+
+ $(DefineConstants);_NETFRAMEWORK_;_NET46_
+
+
-
- ..\packages\DocumentFormat.OpenXml.2.7.2\lib\net40\DocumentFormat.OpenXml.dll
- True
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- ..\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll
- True
-
-
-
-
- 3.5
-
-
-
-
-
-
-
-
- Properties\AssemblyVersionInfo.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
- {BD5E6BFE-E837-4A35-BCA9-39667D873A20}
- ClosedXML
-
-
- {03A518D0-1CB7-488E-861C-C4E782B27A46}
- ClosedXML_Examples
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- .editorconfig
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
diff --git a/ClosedXML_Tests/Excel/CalcEngine/DateAndTimeTests.cs b/ClosedXML_Tests/Excel/CalcEngine/DateAndTimeTests.cs
index 1d4c5d4..32e6af1 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/DateAndTimeTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/DateAndTimeTests.cs
@@ -12,7 +12,7 @@
[TestFixture]
public class DateAndTimeTests
{
- [OneTimeSetUp]
+ [SetUp]
public void SetCultureInfo()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
diff --git a/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs b/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs
index a4435ef..781a945 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs
@@ -8,7 +8,7 @@
[TestFixture]
public class FunctionsTests
{
- [OneTimeSetUp]
+ [SetUp]
public void Init()
{
// Make sure tests run on a deterministic culture
diff --git a/ClosedXML_Tests/Excel/CalcEngine/InformationTests.cs b/ClosedXML_Tests/Excel/CalcEngine/InformationTests.cs
index 19de6ca..07b0027 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/InformationTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/InformationTests.cs
@@ -9,7 +9,7 @@
[TestFixture]
public class InformationTests
{
- [OneTimeSetUp]
+ [SetUp]
public void SetCultureInfo()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
diff --git a/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs b/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs
index b7b7151..ce521c9 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs
@@ -10,7 +10,7 @@
{
private XLWorkbook workbook;
- [OneTimeSetUp]
+ [SetUp]
public void Init()
{
// Make sure tests run on a deterministic culture
diff --git a/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs b/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs
index 3f451f1..34516fe 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs
@@ -217,7 +217,7 @@
workbook.Dispose();
}
- [OneTimeSetUp]
+ [SetUp]
public void Init()
{
// Make sure tests run on a deterministic culture
diff --git a/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs b/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs
index b4cf9b6..3644161 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs
@@ -11,7 +11,7 @@
[TestFixture]
public class TextTests
{
- [OneTimeSetUp]
+ [SetUp]
public void Init()
{
// Make sure tests run on a deterministic culture
diff --git a/ClosedXML_Tests/Excel/Columns/ColumnTests.cs b/ClosedXML_Tests/Excel/Columns/ColumnTests.cs
index a0571cd..35dc053 100644
--- a/ClosedXML_Tests/Excel/Columns/ColumnTests.cs
+++ b/ClosedXML_Tests/Excel/Columns/ColumnTests.cs
@@ -3,6 +3,7 @@
using System.Linq;
using ClosedXML.Excel;
using NUnit.Framework;
+using ClosedXML_Tests.Utils;
namespace ClosedXML_Tests.Excel
{
@@ -107,8 +108,6 @@
IXLColumn column3 = ws.Column(3);
IXLColumn columnIns = ws.Column(2).InsertColumnsBefore(1).First();
- string outputPath = Path.Combine(TestHelper.TestsOutputDirectory, "ForTesting", "Sandbox.xlsx");
- wb.SaveAs(outputPath, true);
Assert.AreEqual(XLColor.Red, ws.Column(1).Cell(1).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.Red, ws.Column(1).Cell(2).Style.Fill.BackgroundColor);
diff --git a/ClosedXML_Tests/Excel/Comments/CommentsTests.cs b/ClosedXML_Tests/Excel/Comments/CommentsTests.cs
index 1ba4e76..34b8382 100644
--- a/ClosedXML_Tests/Excel/Comments/CommentsTests.cs
+++ b/ClosedXML_Tests/Excel/Comments/CommentsTests.cs
@@ -1,10 +1,6 @@
using ClosedXML.Excel;
using NUnit.Framework;
-using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace ClosedXML_Tests.Excel.Comments
{
@@ -23,11 +19,9 @@
Assert.AreEqual(XLColorType.Indexed, xlColor.ColorType);
Assert.AreEqual(81, xlColor.Indexed);
-
var color = xlColor.Color.ToHex();
Assert.AreEqual("FF000000", color);
}
-
}
}
}
diff --git a/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs b/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
index 1da6ecb..a52cef1 100644
--- a/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
+++ b/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
@@ -35,6 +35,27 @@
}
[Test]
+ public void CanAddPictureFromStream()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet1");
+
+ using (var resourceStream = Assembly.GetAssembly(typeof(ClosedXML_Examples.BasicTable)).GetManifestResourceStream("ClosedXML_Examples.Resources.SampleImage.jpg"))
+ {
+ var picture = ws.AddPicture(resourceStream, "MyPicture")
+ .WithPlacement(XLPicturePlacement.FreeFloating)
+ .MoveTo(50, 50)
+ .WithSize(200, 200);
+
+ Assert.AreEqual(XLPictureFormat.Jpeg, picture.Format);
+ Assert.AreEqual(200, picture.Width);
+ Assert.AreEqual(200, picture.Height);
+ }
+ }
+ }
+
+ [Test]
public void CanAddPictureFromFile()
{
using (var wb = new XLWorkbook())
@@ -77,9 +98,8 @@
var ws = wb.AddWorksheet("Sheet1");
using (var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClosedXML_Tests.Resource.Images.ImageHandling.png"))
- using (var bitmap = Bitmap.FromStream(resourceStream) as Bitmap)
{
- var pic = ws.AddPicture(bitmap, "MyPicture")
+ var pic = ws.AddPicture(resourceStream, "MyPicture")
.WithPlacement(XLPicturePlacement.FreeFloating)
.MoveTo(50, 50);
@@ -251,7 +271,6 @@
Assert.AreEqual(originalCount - 2, ws.Pictures.Count);
}
}
-
}
[Test]
diff --git a/ClosedXML_Tests/Excel/Ranges/CopyingRangesTests.cs b/ClosedXML_Tests/Excel/Ranges/CopyingRangesTests.cs
index f2b8058..45eb96c 100644
--- a/ClosedXML_Tests/Excel/Ranges/CopyingRangesTests.cs
+++ b/ClosedXML_Tests/Excel/Ranges/CopyingRangesTests.cs
@@ -19,7 +19,7 @@
column1.Cell(2).Style.Fill.SetBackgroundColor(XLColor.FromArgb(1, 1, 1));
column1.Cell(3).Style.Fill.SetBackgroundColor(XLColor.FromHtml("#CCCCCC"));
column1.Cell(4).Style.Fill.SetBackgroundColor(XLColor.FromIndex(26));
- column1.Cell(5).Style.Fill.SetBackgroundColor(XLColor.FromKnownColor(KnownColor.MediumSeaGreen));
+ column1.Cell(5).Style.Fill.SetBackgroundColor(XLColor.FromColor(Color.MediumSeaGreen));
column1.Cell(6).Style.Fill.SetBackgroundColor(XLColor.FromName("Blue"));
column1.Cell(7).Style.Fill.SetBackgroundColor(XLColor.FromTheme(XLThemeColor.Accent3));
@@ -31,7 +31,7 @@
Assert.AreEqual(XLColor.FromArgb(1, 1, 1), column2.Cell(2).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromHtml("#CCCCCC"), column2.Cell(3).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromIndex(26), column2.Cell(4).Style.Fill.BackgroundColor);
- Assert.AreEqual(XLColor.FromKnownColor(KnownColor.MediumSeaGreen),
+ Assert.AreEqual(XLColor.FromColor(Color.MediumSeaGreen),
column2.Cell(5).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromName("Blue"), column2.Cell(6).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromTheme(XLThemeColor.Accent3), column2.Cell(7).Style.Fill.BackgroundColor);
@@ -41,7 +41,7 @@
Assert.AreEqual(XLColor.FromArgb(1, 1, 1), column3.Cell(2).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromHtml("#CCCCCC"), column3.Cell(3).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromIndex(26), column3.Cell(4).Style.Fill.BackgroundColor);
- Assert.AreEqual(XLColor.FromKnownColor(KnownColor.MediumSeaGreen),
+ Assert.AreEqual(XLColor.FromColor(Color.MediumSeaGreen),
column3.Cell(5).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromName("Blue"), column3.Cell(6).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromTheme(XLThemeColor.Accent3), column3.Cell(7).Style.Fill.BackgroundColor);
@@ -64,7 +64,7 @@
Assert.AreEqual(XLColor.FromArgb(1, 1, 1), row2.Cell(2).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromHtml("#CCCCCC"), row2.Cell(3).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromIndex(26), row2.Cell(4).Style.Fill.BackgroundColor);
- Assert.AreEqual(XLColor.FromKnownColor(KnownColor.MediumSeaGreen), row2.Cell(5).Style.Fill.BackgroundColor);
+ Assert.AreEqual(XLColor.FromColor(Color.MediumSeaGreen), row2.Cell(5).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromName("Blue"), row2.Cell(6).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromTheme(XLThemeColor.Accent3), row2.Cell(7).Style.Fill.BackgroundColor);
@@ -73,7 +73,7 @@
Assert.AreEqual(XLColor.FromArgb(1, 1, 1), row3.Cell(2).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromHtml("#CCCCCC"), row3.Cell(3).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromIndex(26), row3.Cell(4).Style.Fill.BackgroundColor);
- Assert.AreEqual(XLColor.FromKnownColor(KnownColor.MediumSeaGreen), row3.Cell(5).Style.Fill.BackgroundColor);
+ Assert.AreEqual(XLColor.FromColor(Color.MediumSeaGreen), row3.Cell(5).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromName("Blue"), row3.Cell(6).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.FromTheme(XLThemeColor.Accent3), row3.Cell(7).Style.Fill.BackgroundColor);
@@ -100,7 +100,7 @@
Assert.AreEqual(2, ws.ConditionalFormats.Count());
Assert.IsTrue(ws.ConditionalFormats.Single(x => x.Range.RangeAddress.ToStringRelative() == "B1:B3").Values.Any(v => v.Value.Value == "G1" && v.Value.IsFormula));
Assert.IsTrue(ws.ConditionalFormats.Single(x => x.Range.RangeAddress.ToStringRelative() == "C5:C5").Values.Any(v => v.Value.Value == "H5" && v.Value.IsFormula));
- }
+ }
private static void FillRow(IXLRow row1)
{
@@ -108,7 +108,7 @@
row1.Cell(2).Style.Fill.SetBackgroundColor(XLColor.FromArgb(1, 1, 1));
row1.Cell(3).Style.Fill.SetBackgroundColor(XLColor.FromHtml("#CCCCCC"));
row1.Cell(4).Style.Fill.SetBackgroundColor(XLColor.FromIndex(26));
- row1.Cell(5).Style.Fill.SetBackgroundColor(XLColor.FromKnownColor(KnownColor.MediumSeaGreen));
+ row1.Cell(5).Style.Fill.SetBackgroundColor(XLColor.FromColor(Color.MediumSeaGreen));
row1.Cell(6).Style.Fill.SetBackgroundColor(XLColor.FromName("Blue"));
row1.Cell(7).Style.Fill.SetBackgroundColor(XLColor.FromTheme(XLThemeColor.Accent3));
diff --git a/ClosedXML_Tests/Excel/Ranges/UsedAndUnusedCellsTests.cs b/ClosedXML_Tests/Excel/Ranges/UsedAndUnusedCellsTests.cs
index a4442c6..fab9b91 100644
--- a/ClosedXML_Tests/Excel/Ranges/UsedAndUnusedCellsTests.cs
+++ b/ClosedXML_Tests/Excel/Ranges/UsedAndUnusedCellsTests.cs
@@ -12,7 +12,7 @@
{
private XLWorkbook workbook;
- [OneTimeSetUp]
+ [SetUp]
public void SetupWorkbook()
{
workbook = new XLWorkbook();
diff --git a/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs b/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
index eff6f11..5668d01 100644
--- a/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
+++ b/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
@@ -387,5 +387,58 @@
Assert.AreEqual(1, ws.ConditionalFormats.Count());
Assert.AreEqual("C3:G4", ws.ConditionalFormats.Single().Range.RangeAddress.ToStringRelative());
}
+
+ [Test]
+ public void RangesRemoveAllWithDispose()
+ {
+ var ws = new XLWorkbook().Worksheets.Add("Sheet1");
+ var ranges = new XLRanges();
+ ranges.Add(ws.Range("A1:A2"));
+ ranges.Add(ws.Range("B1:B2"));
+ var rangesCopy = ranges.ToList();
+
+ ranges.RemoveAll();
+ ws.FirstColumn().InsertColumnsBefore(1);
+
+ Assert.AreEqual(0, ranges.Count);
+ // if ranges were disposed they addresses didn't change
+ Assert.AreEqual("A1:A2", rangesCopy.First().RangeAddress.ToString());
+ Assert.AreEqual("B1:B2", rangesCopy.Last().RangeAddress.ToString());
+ }
+
+ [Test]
+ public void RangesRemoveAllWithoutDispose()
+ {
+ var ws = new XLWorkbook().Worksheets.Add("Sheet1");
+ var ranges = new XLRanges();
+ ranges.Add(ws.Range("A1:A2"));
+ ranges.Add(ws.Range("B1:B2"));
+ var rangesCopy = ranges.ToList();
+
+ ranges.RemoveAll(null, false);
+ ws.FirstColumn().InsertColumnsBefore(1);
+
+ Assert.AreEqual(0, ranges.Count);
+ // if ranges were not disposed they addresses should change
+ Assert.AreEqual("B1:B2", rangesCopy.First().RangeAddress.ToString());
+ Assert.AreEqual("C1:C2", rangesCopy.Last().RangeAddress.ToString());
+ }
+
+
+ [Test]
+ public void RangesRemoveAllByCriteria()
+ {
+ var ws = new XLWorkbook().Worksheets.Add("Sheet1");
+ var ranges = new XLRanges();
+ ranges.Add(ws.Range("A1:A2"));
+ ranges.Add(ws.Range("B1:B3"));
+ ranges.Add(ws.Range("C1:C4"));
+ var otherRange = ws.Range("A3:D3");
+
+ ranges.RemoveAll(r => r.Intersects(otherRange));
+
+ Assert.AreEqual(1, ranges.Count);
+ Assert.AreEqual("A1:A2", ranges.Single().RangeAddress.ToString());
+ }
}
}
diff --git a/ClosedXML_Tests/Excel/Saving/SavingTests.cs b/ClosedXML_Tests/Excel/Saving/SavingTests.cs
index 7f94697..4b19a6b 100644
--- a/ClosedXML_Tests/Excel/Saving/SavingTests.cs
+++ b/ClosedXML_Tests/Excel/Saving/SavingTests.cs
@@ -16,6 +16,17 @@
public class SavingTests
{
[Test]
+ public void CanSaveEmptyFile()
+ {
+ using (var ms = new MemoryStream())
+ using (var wb = new XLWorkbook())
+ {
+ wb.AddWorksheet("Sheet1");
+ wb.SaveAs(ms);
+ }
+ }
+
+ [Test]
public void CanSuccessfullySaveFileMultipleTimes()
{
using (var wb = new XLWorkbook())
diff --git a/ClosedXML_Tests/Excel/Styles/NumberFormatTests.cs b/ClosedXML_Tests/Excel/Styles/NumberFormatTests.cs
index ed012b3..76bf394 100644
--- a/ClosedXML_Tests/Excel/Styles/NumberFormatTests.cs
+++ b/ClosedXML_Tests/Excel/Styles/NumberFormatTests.cs
@@ -27,7 +27,7 @@
Assert.AreEqual("yy-MM-dd", ws.Cell("A5").Style.DateFormat.Format);
ws.Row(1).Style.NumberFormat.Format = "yy-MM-dd";
- ws.Cell("A1").InsertData(table.AsEnumerable(), true);
+ ws.Cell("A1").InsertData(table.Rows, true);
Assert.AreEqual("yy-MM-dd", ws.Cell("E1").Style.DateFormat.Format);
}
}
diff --git a/ClosedXML_Tests/Excel/Tables/TablesTests.cs b/ClosedXML_Tests/Excel/Tables/TablesTests.cs
index ca50c3f..e5868fa 100644
--- a/ClosedXML_Tests/Excel/Tables/TablesTests.cs
+++ b/ClosedXML_Tests/Excel/Tables/TablesTests.cs
@@ -555,6 +555,41 @@
}
[Test]
+ public void TableRenameTests()
+ {
+ var l = new List()
+ {
+ new TestObjectWithAttributes() { Column1 = "a", Column2 = "b", MyField = 4, UnOrderedColumn = 999 },
+ new TestObjectWithAttributes() { Column1 = "c", Column2 = "d", MyField = 5, UnOrderedColumn = 777 }
+ };
+
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ var table1 = ws.FirstCell().InsertTable(l);
+ var table2 = ws.Cell("A10").InsertTable(l);
+
+ Assert.AreEqual("Table1", table1.Name);
+ Assert.AreEqual("Table2", table2.Name);
+
+ table1.Name = "table1";
+ Assert.AreEqual("table1", table1.Name);
+
+ Assert.Throws(() => table1.Name = "");
+ Assert.Throws(() => table1.Name = "R");
+ Assert.Throws(() => table1.Name = "C");
+ Assert.Throws(() => table1.Name = "r");
+ Assert.Throws(() => table1.Name = "c");
+
+ Assert.Throws(() => table1.Name = "123");
+ Assert.Throws(() => table1.Name = new String('A', 256));
+
+ Assert.Throws(() => table1.Name = "Table2");
+ Assert.Throws(() => table1.Name = "TABLE2");
+ }
+ }
+
+ [Test]
public void CanResizeTable()
{
using (var wb = new XLWorkbook())
@@ -692,6 +727,42 @@
}
}
+ [Test]
+ public void TotalsFunctionsOfHeadersWithWeirdCharacters()
+ {
+ var l = new List()
+ {
+ new TestObjectWithAttributes() { Column1 = "a", Column2 = "b", MyField = 4, UnOrderedColumn = 999 },
+ new TestObjectWithAttributes() { Column1 = "c", Column2 = "d", MyField = 5, UnOrderedColumn = 777 }
+ };
+
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().InsertTable(l, false);
+
+ // Give the headings weird names (i.e. spaces, hashes, single quotes
+ ws.Cell("A1").Value = "ABCD ";
+ ws.Cell("B1").Value = " #BCD";
+ ws.Cell("C1").Value = " as'df ";
+ ws.Cell("D1").Value = "Normal";
+
+ var table = ws.RangeUsed().CreateTable();
+ Assert.IsNotNull(table);
+
+ table.ShowTotalsRow = true;
+ table.Field(0).TotalsRowFunction = XLTotalsRowFunction.Count;
+ table.Field(1).TotalsRowFunction = XLTotalsRowFunction.Count;
+ table.Field(2).TotalsRowFunction = XLTotalsRowFunction.Sum;
+ table.Field(3).TotalsRowFunction = XLTotalsRowFunction.Sum;
+
+ Assert.AreEqual("SUBTOTAL(103,Table1[[ABCD ]])", table.Field(0).TotalsRowFormulaA1);
+ Assert.AreEqual("SUBTOTAL(103,Table1[[ '#BCD]])", table.Field(1).TotalsRowFormulaA1);
+ Assert.AreEqual("SUBTOTAL(109,Table1[[ as''df ]])", table.Field(2).TotalsRowFormulaA1);
+ Assert.AreEqual("SUBTOTAL(109,[Normal])", table.Field(3).TotalsRowFormulaA1);
+ }
+ }
+
//TODO: Delete table (not underlying range)
}
}
diff --git a/ClosedXML_Tests/ExcelDocsComparerTests.cs b/ClosedXML_Tests/ExcelDocsComparerTests.cs
index ac2fa36..42677eb 100644
--- a/ClosedXML_Tests/ExcelDocsComparerTests.cs
+++ b/ClosedXML_Tests/ExcelDocsComparerTests.cs
@@ -1,6 +1,6 @@
-using System.IO;
using ClosedXML_Examples;
using NUnit.Framework;
+using System.IO;
namespace ClosedXML_Tests
{
@@ -17,7 +17,7 @@
new BasicTable().Create(left);
new BasicTable().Create(right);
string message;
- Assert.IsTrue(ExcelDocsComparer.Compare(left, right, TestHelper.IsRunningOnUnix, out message));
+ Assert.IsTrue(ExcelDocsComparer.Compare(left, right, out message));
}
finally
{
@@ -43,7 +43,7 @@
new HelloWorld().Create(right);
string message;
- Assert.IsFalse(ExcelDocsComparer.Compare(left, right, TestHelper.IsRunningOnUnix, out message));
+ Assert.IsFalse(ExcelDocsComparer.Compare(left, right, out message));
}
finally
{
@@ -58,4 +58,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/OleDb/OleDbTests.cs b/ClosedXML_Tests/OleDb/OleDbTests.cs
index 2aa897c..b7cd054 100644
--- a/ClosedXML_Tests/OleDb/OleDbTests.cs
+++ b/ClosedXML_Tests/OleDb/OleDbTests.cs
@@ -1,4 +1,5 @@
-using ClosedXML.Excel;
+#if !APPVEYOR && _NETFRAMEWORK_
+using ClosedXML.Excel;
using ClosedXML_Tests.Utils;
using NUnit.Framework;
using System;
@@ -13,7 +14,6 @@
[TestFixture]
public class OleDbTests
{
-#if !APPVEYOR
[Test]
public void TestOleDbValues()
{
@@ -78,7 +78,6 @@
}
}
}
-#endif
private string CreateTestFile()
{
@@ -118,3 +117,4 @@
}
}
}
+#endif
diff --git a/ClosedXML_Tests/OpenXMLTests.cs b/ClosedXML_Tests/OpenXMLTests.cs
new file mode 100644
index 0000000..c0d0ddf
--- /dev/null
+++ b/ClosedXML_Tests/OpenXMLTests.cs
@@ -0,0 +1,30 @@
+using DocumentFormat.OpenXml.Packaging;
+using NUnit.Framework;
+using System.IO;
+
+namespace ClosedXML_Tests
+{
+ [TestFixture]
+ public class OpenXMLTests
+ {
+ [Test]
+ [Ignore("Workaround has been included in ClosedXML")]
+ public static void SetPackagePropertiesEntryToNullWithOpenXml()
+ {
+ // Fixed in .NET Standard 2.1
+ // See:
+ // https://github.com/OfficeDev/Open-XML-SDK/issues/235
+ // https://github.com/dotnet/corefx/issues/23795
+ using (var stream = TestHelper.GetStreamFromResource(TestHelper.GetResourcePath(@"Examples\PivotTables\PivotTables.xlsx")))
+ using (var ms = new MemoryStream())
+ {
+ stream.CopyTo(ms);
+
+ using (var document = SpreadsheetDocument.Open(ms, true))
+ {
+ document.PackageProperties.Creator = null;
+ }
+ }
+ }
+ }
+}
diff --git a/ClosedXML_Tests/Properties/AssemblyInfo.cs b/ClosedXML_Tests/Properties/AssemblyInfo.cs
deleted file mode 100644
index bfb414e..0000000
--- a/ClosedXML_Tests/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-
-[assembly: AssemblyTitle("ClosedXML_Tests")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("ClosedXML_Tests")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-
-[assembly: Guid("a16b867e-6b00-4ccc-a368-c9f9b14e0e6a")]
-
diff --git a/ClosedXML_Tests/Resource/Examples/Styles/UsingColors.xlsx b/ClosedXML_Tests/Resource/Examples/Styles/UsingColors.xlsx
index 2ada7d9..2d49b85 100644
--- a/ClosedXML_Tests/Resource/Examples/Styles/UsingColors.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Styles/UsingColors.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/TestHelper.cs b/ClosedXML_Tests/TestHelper.cs
index 5c1acf8..1887cd5 100644
--- a/ClosedXML_Tests/TestHelper.cs
+++ b/ClosedXML_Tests/TestHelper.cs
@@ -43,6 +43,8 @@
// the columns widths after AdjustToContents() will
// cause the tests to fail.
// Therefore we ignore the width attribute when running on Unix
+ public static bool StripColumnWidths { get { return IsRunningOnUnix; } }
+
public static bool IsRunningOnUnix
{
get
@@ -83,7 +85,7 @@
using (var streamActual = File.OpenRead(filePath2))
{
string message;
- var success = ExcelDocsComparer.Compare(streamActual, streamExpected, TestHelper.IsRunningOnUnix, out message);
+ var success = ExcelDocsComparer.Compare(streamActual, streamExpected, out message);
var formattedMessage =
String.Format(
"Actual file '{0}' is different than the expected file '{1}'. The difference is: '{2}'",
@@ -108,7 +110,6 @@
fileName += ActualTestResultPostFix;
fileName = Path.ChangeExtension(fileName, extension);
- filePath1 = Path.Combine(directory, "z" + fileName);
var filePath2 = Path.Combine(directory, fileName);
using (var wb = workbookGenerator.Invoke())
@@ -121,7 +122,7 @@
using (var streamActual = File.OpenRead(filePath2))
{
string message;
- var success = ExcelDocsComparer.Compare(streamActual, streamExpected, TestHelper.IsRunningOnUnix, out message);
+ var success = ExcelDocsComparer.Compare(streamActual, streamExpected, out message);
var formattedMessage =
String.Format(
"Actual file '{0}' is different than the expected file '{1}'. The difference is: '{2}'",
diff --git a/ClosedXML_Tests/Utils/ExcelDocsComparer.cs b/ClosedXML_Tests/Utils/ExcelDocsComparer.cs
index 2ad4ab2..9c35602 100644
--- a/ClosedXML_Tests/Utils/ExcelDocsComparer.cs
+++ b/ClosedXML_Tests/Utils/ExcelDocsComparer.cs
@@ -6,25 +6,21 @@
{
internal static class ExcelDocsComparer
{
- public static bool Compare(string left, string right, bool stripColumnWidths, out string message)
+ public static bool Compare(string left, string right, out string message)
{
using (FileStream leftStream = File.OpenRead(left))
+ using (FileStream rightStream = File.OpenRead(right))
{
- using (FileStream rightStream = File.OpenRead(right))
- {
- return Compare(leftStream, rightStream, stripColumnWidths, out message);
- }
+ return Compare(leftStream, rightStream, out message);
}
}
- public static bool Compare(Stream left, Stream right, bool stripColumnWidths, out string message)
+ public static bool Compare(Stream left, Stream right, out string message)
{
- using (Package leftPackage = Package.Open(left))
+ using (Package leftPackage = Package.Open(left, FileMode.Open, FileAccess.Read))
+ using (Package rightPackage = Package.Open(right, FileMode.Open, FileAccess.Read))
{
- using (Package rightPackage = Package.Open(right))
- {
- return PackageHelper.Compare(leftPackage, rightPackage, false, ExcludeMethod, stripColumnWidths, out message);
- }
+ return PackageHelper.Compare(leftPackage, rightPackage, false, ExcludeMethod, out message);
}
}
@@ -39,4 +35,4 @@
return false;
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Utils/PackageHelper.cs b/ClosedXML_Tests/Utils/PackageHelper.cs
index 60bc482..f4f43cd 100644
--- a/ClosedXML_Tests/Utils/PackageHelper.cs
+++ b/ClosedXML_Tests/Utils/PackageHelper.cs
@@ -273,9 +273,9 @@
///
///
///
- public static bool Compare(Package left, Package right, bool compareToFirstDifference, bool stripColumnWidths, out string message)
+ public static bool Compare(Package left, Package right, bool compareToFirstDifference, out string message)
{
- return Compare(left, right, compareToFirstDifference, null, stripColumnWidths, out message);
+ return Compare(left, right, compareToFirstDifference, null, out message);
}
///
@@ -288,7 +288,7 @@
///
///
public static bool Compare(Package left, Package right, bool compareToFirstDifference,
- Func excludeMethod, bool stripColumnWidths, out string message)
+ Func excludeMethod, out string message)
{
#region Check
@@ -346,15 +346,23 @@
}
var leftPart = left.GetPart(pair.Uri);
var rightPart = right.GetPart(pair.Uri);
- using (Stream oneStream = leftPart.GetStream(FileMode.Open, FileAccess.Read))
- using (Stream otherStream = rightPart.GetStream(FileMode.Open, FileAccess.Read))
+ using (Stream leftPackagePartStream = leftPart.GetStream(FileMode.Open, FileAccess.Read))
+ using (Stream rightPackagePartStream = rightPart.GetStream(FileMode.Open, FileAccess.Read))
+ using (var leftMemoryStream = new MemoryStream())
+ using (var rightMemoryStream = new MemoryStream())
{
- bool stripColumnWidthsFromSheet = stripColumnWidths &&
+ leftPackagePartStream.CopyTo(leftMemoryStream);
+ rightPackagePartStream.CopyTo(rightMemoryStream);
+
+ leftMemoryStream.Seek(0, SeekOrigin.Begin);
+ rightMemoryStream.Seek(0, SeekOrigin.Begin);
+
+ bool stripColumnWidthsFromSheet = TestHelper.StripColumnWidths &&
leftPart.ContentType == @"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" &&
rightPart.ContentType == @"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml";
- var tuple1 = new Tuple(pair.Uri, oneStream);
- var tuple2 = new Tuple(pair.Uri, otherStream);
+ var tuple1 = new Tuple(pair.Uri, leftMemoryStream);
+ var tuple2 = new Tuple(pair.Uri, rightMemoryStream);
if (!StreamHelper.Compare(tuple1, tuple2, stripColumnWidthsFromSheet))
{
diff --git a/ClosedXML_Tests/Utils/StreamHelper.cs b/ClosedXML_Tests/Utils/StreamHelper.cs
index bf89911..59ef12c 100644
--- a/ClosedXML_Tests/Utils/StreamHelper.cs
+++ b/ClosedXML_Tests/Utils/StreamHelper.cs
@@ -147,6 +147,9 @@
foreach (var pair in uriSpecificIgnores.Where(p => p.Key.Equals(uri.OriginalString)))
s = pair.Value.Replace(s, "");
+ // Collapse empty xml elements
+ s = emptyXmlElementRegex.Replace(s, "<$1 />");
+
if (ignoreColumnWidths)
s = RemoveColumnWidths(s);
@@ -162,6 +165,7 @@
new KeyValuePair("/docProps/core.xml", new Regex(@"", RegexOptions.Compiled))
};
+ private static Regex emptyXmlElementRegex = new Regex(@"<([\w:]+)><\/\1>", RegexOptions.Compiled);
private static Regex columnRegex = new Regex("", RegexOptions.Compiled);
private static Regex widthRegex = new Regex("width=\"\\d+(\\.\\d+)?\"\\s+", RegexOptions.Compiled);
diff --git a/ClosedXML_Tests/packages.config b/ClosedXML_Tests/packages.config
deleted file mode 100644
index 5e0ab7c..0000000
--- a/ClosedXML_Tests/packages.config
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/appveyor.yml b/appveyor.yml
index db11140..42a2dd4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,43 +1,47 @@
-version: 0.92.{build}
-branches:
- # whitelist
- only:
- - develop
+version: 0.93.0.{build}
- # blacklist
- except:
- - gh-pages
-# Build worker image (VM template)
-image: Visual Studio 2015
+os: Visual Studio 2017
+image: Visual Studio 2017
+
environment:
AppVeyor: APPVEYOR
-# enable patching of AssemblyInfo.* files
-assembly_info:
+branches:
+ only:
+ - develop
+ except:
+ - gh-pages
+
+dotnet_csproj:
patch: true
- file: AssemblyInfo.*
- assembly_version: "{version}"
- assembly_file_version: "{version}"
- assembly_informational_version: "{version}"
+ file: '**\*.csproj'
+ version: '{version}'
+ package_version: '{version}'
+ assembly_version: '{version}'
+ file_version: '{version}'
+ informational_version: '{version}'
-#---------------------------------#
-# build configuration #
-#---------------------------------#
-
-# build platform, i.e. x86, x64, Any CPU. This setting is optional.
-platform: Any CPU
-
-build:
- parallel: true # enable MSBuild parallel builds
- project: ClosedXML.sln # path to Visual Studio solution or project
- verbosity: minimal
-
+# platform: Any CPU
configuration : Release
-#Restore
+build:
+ parallel: true
+ project: ClosedXML.sln
+ verbosity: minimal
+
before_build:
+ - ps: if (Test-Path 'C:\Tools\NuGet43') { $nugetDir = 'C:\Tools\NuGet43' } else { $nugetDir = 'C:\Tools\NuGet' }
+ - ps: (New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/v4.3.0/nuget.exe', "$nugetDir\NuGet.exe")
+ - cmd: nuget update -self
- nuget restore
artifacts:
- - path: ClosedXML/bin/Release/ClosedXML.dll
- - path: ClosedXML/bin/Release/ClosedXML.xml
+ - path: ClosedXML/bin/Release/netstandard2.0/ClosedXML.dll
+ - path: ClosedXML/bin/Release/net40/ClosedXML.dll
+ - path: ClosedXML/bin/Release/net46/ClosedXML.dll
+
+test:
+ assemblies:
+ - ClosedXML_Tests/bin/Release/netcoreapp2.0/ClosedXML_Tests.dll
+ - ClosedXML_Tests/bin/Release/net40/ClosedXML_Tests.dll
+ - ClosedXML_Tests/bin/Release/net46/ClosedXML_Tests.dll