diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 984600d..5b1b779 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,3 +1,5 @@
+## Read and complete the full issue template
+
**Do you want to request a *feature* or report a *bug*?**
- [x] Bug
- [ ] Feature
@@ -8,20 +10,26 @@
**What is the current behavior?**
-**If the current behavior is a bug, please provide the steps to reproduce and
-if possible a minimal demo of the problem with a sample spreadsheet.**
+Complete this.
**What is the expected behavior or new feature?**
+Complete this.
+
**Did this work in previous versions of our tool? Which versions?**
-- [ ] I attached a sample spreadsheet. (You can drag files on to this issue)
+Yes/No/v0.XX
+
+## Reproducibility
+**This is an important section. Read it carefully. Failure to do so will cause a 'RTFM' comment.**
+
+Without a code sample, it is unlikely that your issue will get attention. Don't be lazy. Do the effort and assist the developers to reproduce your problem. Code samples should be [minimal complete and verifiable](https://stackoverflow.com/help/mcve). Sample spreadsheets should be attached whenever applicable. Remove sensitive information.
**Code to reproduce problem:**
```c#
public void Main()
{
- // Where possible, post full code to reproduce your issue that adheres to:
+ // Code standards:
// - Fully runnable. I should be able to copy and paste this code into a
// console application and run it without having to edit it much.
// - Declare all your variables (this follows from the previous point)
@@ -30,3 +38,4 @@
// post your full application.
}
```
+- [ ] I attached a sample spreadsheet. (You can drag files on to this issue)
diff --git a/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML.csproj
index 893e0dd..4d4338c 100644
--- a/ClosedXML/ClosedXML.csproj
+++ b/ClosedXML/ClosedXML.csproj
@@ -65,9 +65,18 @@
+
+
+
+
+
+
+
+
+
@@ -81,6 +90,7 @@
+
diff --git a/ClosedXML/Excel/CalcEngine/CalcEngine.cs b/ClosedXML/Excel/CalcEngine/CalcEngine.cs
index 71e3d72..c1a1aa1 100644
--- a/ClosedXML/Excel/CalcEngine/CalcEngine.cs
+++ b/ClosedXML/Excel/CalcEngine/CalcEngine.cs
@@ -77,18 +77,20 @@
// skip leading equals sign
if (_len > 0 && _expr[0] == '=')
- {
_ptr++;
- }
+
+ // skip leading +'s
+ while (_len > _ptr && _expr[_ptr] == '+')
+ _ptr++;
// parse the expression
var expr = ParseExpression();
// check for errors
- if (_token.ID != TKID.END)
- {
- Throw();
- }
+ if (_token.ID == TKID.OPEN)
+ Throw("Unknown function: " + expr.LastParseItem);
+ else if (_token.ID != TKID.END)
+ Throw("Expected end of expression");
// optimize expression
if (_optimize)
@@ -113,10 +115,9 @@
///
public object Evaluate(string expression)
{
- var x = //Parse(expression);
- _cache != null
- ? _cache[expression]
- : Parse(expression);
+ var x = _cache != null
+ ? _cache[expression]
+ : Parse(expression);
return x.Evaluate();
}
@@ -252,6 +253,18 @@
#region ** token/keyword tables
+ private static readonly IDictionary ErrorMap = new Dictionary()
+ {
+ ["#REF!"] = ErrorExpression.ExpressionErrorType.CellReference,
+ ["#VALUE!"] = ErrorExpression.ExpressionErrorType.CellValue,
+ ["#DIV/0!"] = ErrorExpression.ExpressionErrorType.DivisionByZero,
+ ["#NAME?"] = ErrorExpression.ExpressionErrorType.NameNotRecognized,
+ ["#N/A"] = ErrorExpression.ExpressionErrorType.NoValueAvailable,
+ ["#NULL!"] = ErrorExpression.ExpressionErrorType.NullValue,
+ ["#NUM!"] = ErrorExpression.ExpressionErrorType.NumberInvalid
+ };
+
+
// build/get static token table
private Dictionary
diff --git a/ClosedXML_Examples/Creating/CreateFiles.cs b/ClosedXML_Examples/Creating/CreateFiles.cs
index 1e639dd..8f1978f 100644
--- a/ClosedXML_Examples/Creating/CreateFiles.cs
+++ b/ClosedXML_Examples/Creating/CreateFiles.cs
@@ -4,6 +4,7 @@
using ClosedXML_Examples.Ranges;
using ClosedXML_Examples.Rows;
using ClosedXML_Examples.Styles;
+using ClosedXML_Examples.Tables;
using System.IO;
namespace ClosedXML_Examples
@@ -67,6 +68,7 @@
new RowCells().Create(Path.Combine(path, "RowCells.xlsx"));
new FreezePanes().Create(Path.Combine(path, "FreezePanes.xlsx"));
new UsingTables().Create(Path.Combine(path, "UsingTables.xlsx"));
+ new ResizingTables().Create(Path.Combine(path, "ResizingTables.xlsx"));
new AddingRowToTables().Create(Path.Combine(path, "AddingRowToTables.xlsx"));
new RightToLeft().Create(Path.Combine(path, "RightToLeft.xlsx"));
new ShowCase().Create(Path.Combine(path, "ShowCase.xlsx"));
diff --git a/ClosedXML_Examples/Misc/CopyingWorksheets.cs b/ClosedXML_Examples/Misc/CopyingWorksheets.cs
index b0843eb..e06cd66 100644
--- a/ClosedXML_Examples/Misc/CopyingWorksheets.cs
+++ b/ClosedXML_Examples/Misc/CopyingWorksheets.cs
@@ -1,6 +1,6 @@
-using System.IO;
using ClosedXML.Excel;
-using ClosedXML_Examples.Ranges;
+using ClosedXML_Examples.Tables;
+using System.IO;
namespace ClosedXML_Examples.Misc
{
@@ -18,7 +18,7 @@
var wsSource = wb.Worksheet(1);
// Copy the worksheet to a new sheet in this workbook
wsSource.CopyTo("Copy");
-
+
// We're going to open another workbook to show that you can
// copy a sheet from one workbook to another:
new BasicTable().Create(tempFile2);
@@ -40,6 +40,5 @@
}
}
}
-
}
}
diff --git a/ClosedXML_Examples/Misc/Formulas.cs b/ClosedXML_Examples/Misc/Formulas.cs
index 729cb9e..8066a81 100644
--- a/ClosedXML_Examples/Misc/Formulas.cs
+++ b/ClosedXML_Examples/Misc/Formulas.cs
@@ -54,6 +54,7 @@
// Just put the formula between curly braces
ws.Cell("A6").Value = "Array Formula: ";
ws.Cell("B6").FormulaA1 = "{A2+A3}";
+ ws.Range("C6:D6").FormulaA1 = "{TRANSPOSE(A2:A3)}";
ws.Range(1, 1, 1, 7).Style.Fill.BackgroundColor = XLColor.Cyan;
ws.Range(1, 1, 1, 7).Style.Font.Bold = true;
diff --git a/ClosedXML_Examples/Misc/InsertingData.cs b/ClosedXML_Examples/Misc/InsertingData.cs
index 69c11a8..626a9ec 100644
--- a/ClosedXML_Examples/Misc/InsertingData.cs
+++ b/ClosedXML_Examples/Misc/InsertingData.cs
@@ -1,8 +1,8 @@
+using ClosedXML.Excel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
-using ClosedXML.Excel;
namespace ClosedXML_Examples.Misc
{
@@ -13,72 +13,82 @@
// Public
public void Create(String filePath)
{
- var wb = new XLWorkbook();
- var ws = wb.Worksheets.Add("Inserting Data");
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.Worksheets.Add("Inserting Data");
- // From a list of strings
- var listOfStrings = new List();
- listOfStrings.Add("House");
- listOfStrings.Add("001");
- ws.Cell(1, 1).Value = "From Strings";
- ws.Cell(1, 1).AsRange().AddToNamed("Titles");
- ws.Cell(2, 1).InsertData(listOfStrings);
+ // From a list of strings
+ var listOfStrings = new List();
+ listOfStrings.Add("House");
+ listOfStrings.Add("001");
+ ws.Cell(1, 1).Value = "From Strings";
+ ws.Cell(1, 1).AsRange().AddToNamed("Titles");
+ ws.Cell(2, 1).InsertData(listOfStrings);
- // From a list of arrays
- var listOfArr = new List();
- listOfArr.Add(new Int32[] { 1, 2, 3 });
- listOfArr.Add(new Int32[] { 1 });
- listOfArr.Add(new Int32[] { 1, 2, 3, 4, 5, 6 });
- ws.Cell(1, 3).Value = "From Arrays";
- ws.Range(1, 3, 1, 8).Merge().AddToNamed("Titles");
- ws.Cell(2, 3).InsertData(listOfArr);
+ // From a list of arrays
+ var listOfArr = new List();
+ listOfArr.Add(new Int32[] { 1, 2, 3 });
+ listOfArr.Add(new Int32[] { 1 });
+ listOfArr.Add(new Int32[] { 1, 2, 3, 4, 5, 6 });
+ ws.Cell(1, 3).Value = "From Arrays";
+ ws.Range(1, 3, 1, 8).Merge().AddToNamed("Titles");
+ ws.Cell(2, 3).InsertData(listOfArr);
- // From a DataTable
- var dataTable = GetTable();
- ws.Cell(6, 1).Value = "From DataTable";
- ws.Range(6, 1, 6, 4).Merge().AddToNamed("Titles");
- ws.Cell(7, 1).InsertData(dataTable);
+ // From a DataTable
+ var dataTable = GetTable();
+ ws.Cell(6, 1).Value = "From DataTable";
+ ws.Range(6, 1, 6, 4).Merge().AddToNamed("Titles");
+ ws.Cell(7, 1).InsertData(dataTable);
- // From a query
- var list = new List();
- list.Add(new Person() { Name = "John", Age = 30, House = "On Elm St." });
- list.Add(new Person() { Name = "Mary", Age = 15, House = "On Main St." });
- list.Add(new Person() { Name = "Luis", Age = 21, House = "On 23rd St." });
- list.Add(new Person() { Name = "Henry", Age = 45, House = "On 5th Ave." });
+ // From a query
+ var list = new List();
+ list.Add(new Person() { Name = "John", Age = 30, House = "On Elm St." });
+ list.Add(new Person() { Name = "Mary", Age = 15, House = "On Main St." });
+ list.Add(new Person() { Name = "Luis", Age = 21, House = "On 23rd St." });
+ list.Add(new Person() { Name = "Henry", Age = 45, House = "On 5th Ave." });
- var people = from p in list
- where p.Age >= 21
- select new { p.Name, p.House, p.Age };
+ var people = from p in list
+ where p.Age >= 21
+ select new { p.Name, p.House, p.Age };
- ws.Cell(6, 6).Value = "From Query";
- ws.Range(6, 6, 6, 8).Merge().AddToNamed("Titles");
- ws.Cell(7, 6).InsertData(people);
+ ws.Cell(6, 6).Value = "From Query";
+ ws.Range(6, 6, 6, 8).Merge().AddToNamed("Titles");
+ ws.Cell(7, 6).InsertData(people);
- // Prepare the style for the titles
- var titlesStyle = wb.Style;
- titlesStyle.Font.Bold = true;
- titlesStyle.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
- titlesStyle.Fill.BackgroundColor = XLColor.Cyan;
+ ws.Cell(11, 6).Value = "From List";
+ ws.Range(11, 6, 11, 9).Merge().AddToNamed("Titles");
+ ws.Cell(12, 6).InsertData(list);
- // Format all titles in one shot
- wb.NamedRanges.NamedRange("Titles").Ranges.Style = titlesStyle;
+ ws.Cell("A13").Value = "Transposed";
+ ws.Range(13, 1, 13, 3).Merge().AddToNamed("Titles");
+ ws.Cell("A14").InsertData(people.AsEnumerable(), true);
- ws.Columns().AdjustToContents();
+ // Prepare the style for the titles
+ var titlesStyle = wb.Style;
+ titlesStyle.Font.Bold = true;
+ titlesStyle.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
+ titlesStyle.Fill.BackgroundColor = XLColor.Cyan;
- wb.SaveAs(filePath);
+ // Format all titles in one shot
+ wb.NamedRanges.NamedRange("Titles").Ranges.Style = titlesStyle;
+
+ ws.Columns().AdjustToContents();
+
+ wb.SaveAs(filePath);
+ }
}
- class Person
+ private class Person
{
public String House { get; set; }
public String Name { get; set; }
public Int32 Age { get; set; }
+ public static String ClassType { get { return nameof(Person); } }
}
// Private
private DataTable GetTable()
{
-
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
@@ -92,9 +102,9 @@
table.Rows.Add(100, "Dilantin", "Melanie", new DateTime(2000, 1, 5));
return table;
}
+
// Override
-
- #endregion
+ #endregion Methods
}
}
diff --git a/ClosedXML_Examples/Misc/InsertingTables.cs b/ClosedXML_Examples/Misc/InsertingTables.cs
deleted file mode 100644
index fb6a3a0..0000000
--- a/ClosedXML_Examples/Misc/InsertingTables.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using ClosedXML.Attributes;
-using ClosedXML.Excel;
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Linq;
-
-namespace ClosedXML_Examples.Misc
-{
- public class InsertingTables : IXLExample
- {
- #region Methods
-
- // Public
- public void Create(String filePath)
- {
- var wb = new XLWorkbook();
- var ws = wb.Worksheets.Add("Inserting Tables");
-
- // From a list of strings
- var listOfStrings = new List();
- listOfStrings.Add("House");
- listOfStrings.Add("Car");
- ws.Cell(1, 1).Value = "From Strings";
- ws.Cell(1, 1).AsRange().AddToNamed("Titles");
- ws.Cell(2, 1).InsertTable(listOfStrings);
-
- // From a list of arrays
- var listOfArr = new List();
- listOfArr.Add(new Int32[] { 1, 2, 3 });
- listOfArr.Add(new Int32[] { 1 });
- listOfArr.Add(new Int32[] { 1, 2, 3, 4, 5, 6 });
- ws.Cell(1, 3).Value = "From Arrays";
- ws.Range(1, 3, 1, 8).Merge().AddToNamed("Titles");
- ws.Cell(2, 3).InsertTable(listOfArr);
-
- // From a DataTable
- var dataTable = GetTable();
- ws.Cell(7, 1).Value = "From DataTable";
- ws.Range(7, 1, 7, 4).Merge().AddToNamed("Titles");
- ws.Cell(8, 1).InsertTable(dataTable);
-
- // From a query
- var list = new List();
- list.Add(new Person() { Name = "John", Age = 30, House = "On Elm St." });
- list.Add(new Person() { Name = "Mary", Age = 15, House = "On Main St." });
- list.Add(new Person() { Name = "Luis", Age = 21, House = "On 23rd St." });
- list.Add(new Person() { Name = "Henry", Age = 45, House = "On 5th Ave." });
-
- var people = from p in list
- where p.Age >= 21
- select p;
-
- ws.Cell(7, 6).Value = "From Query";
- ws.Range(7, 6, 7, 8).Merge().AddToNamed("Titles");
- ws.Cell(8, 6).InsertTable(people);
-
- // Prepare the style for the titles
- var titlesStyle = wb.Style;
- titlesStyle.Font.Bold = true;
- titlesStyle.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
- titlesStyle.Fill.BackgroundColor = XLColor.Cyan;
-
- // Format all titles in one shot
- wb.NamedRanges.NamedRange("Titles").Ranges.Style = titlesStyle;
-
- ws.Columns().AdjustToContents();
-
- wb.SaveAs(filePath);
- }
-
- private class Person
- {
- [XLColumn(Header = "House Street")]
- public String House { get; set; }
-
- public String Name { get; set; }
- public Int32 Age { get; set; }
- }
-
- // Private
- private DataTable GetTable()
- {
- DataTable table = new DataTable();
- table.Columns.Add("Dosage", typeof(int));
- table.Columns.Add("Drug", typeof(string));
- table.Columns.Add("Patient", typeof(string));
- table.Columns.Add("Date", typeof(DateTime));
-
- table.Rows.Add(25, "Indocin", "David", new DateTime(2000, 1, 1));
- table.Rows.Add(50, "Enebrel", "Sam", new DateTime(2000, 1, 2));
- table.Rows.Add(10, "Hydralazine", "Christoff", new DateTime(2000, 1, 3));
- table.Rows.Add(21, "Combivent", "Janet", new DateTime(2000, 1, 4));
- table.Rows.Add(100, "Dilantin", "Melanie", new DateTime(2000, 1, 5));
- return table;
- }
-
- // Override
-
- #endregion Methods
- }
-}
diff --git a/ClosedXML_Examples/PivotTables/PivotTables.cs b/ClosedXML_Examples/PivotTables/PivotTables.cs
index 9eb24ea..fa479da 100644
--- a/ClosedXML_Examples/PivotTables/PivotTables.cs
+++ b/ClosedXML_Examples/PivotTables/PivotTables.cs
@@ -60,6 +60,8 @@
IXLWorksheet ptSheet;
IXLPivotTable pt;
+ #region Pivots
+
for (int i = 1; i <= 3; i++)
{
// Add a new sheet for our pivot table
@@ -95,7 +97,10 @@
ptSheet.Columns().AdjustToContents();
}
- // Different kind of pivot
+ #endregion Pivots
+
+ #region Different kind of pivot
+
ptSheet = wb.Worksheets.Add("pvtNoColumnLabels");
pt = ptSheet.PivotTables.AddNew("pvtNoColumnLabels", ptSheet.Cell(1, 1), dataRange);
@@ -105,8 +110,10 @@
pt.Values.Add("NumberOfOrders").SetSummaryFormula(XLPivotSummary.Sum);
pt.Values.Add("Quality").SetSummaryFormula(XLPivotSummary.Sum);
+ #endregion Different kind of pivot
- // Pivot table with collapsed fields
+ #region Pivot table with collapsed fields
+
ptSheet = wb.Worksheets.Add("pvtCollapsedFields");
pt = ptSheet.PivotTables.AddNew("pvtCollapsedFields", ptSheet.Cell(1, 1), dataRange);
@@ -116,8 +123,10 @@
pt.Values.Add("NumberOfOrders").SetSummaryFormula(XLPivotSummary.Sum);
pt.Values.Add("Quality").SetSummaryFormula(XLPivotSummary.Sum);
+ #endregion Pivot table with collapsed fields
- // Pivot table with a field both as a value and as a row/column/filter label
+ #region Pivot table with a field both as a value and as a row/column/filter label
+
ptSheet = wb.Worksheets.Add("pvtFieldAsValueAndLabel");
pt = ptSheet.PivotTables.AddNew("pvtFieldAsValueAndLabel", ptSheet.Cell(1, 1), dataRange);
@@ -126,6 +135,37 @@
pt.Values.Add("Name").SetSummaryFormula(XLPivotSummary.Count);//.NumberFormat.Format = "#0.00";
+ #endregion Pivot table with a field both as a value and as a row/column/filter label
+
+ #region Pivot table with subtotals disabled
+
+ ptSheet = wb.Worksheets.Add("pvtHideSubTotals");
+
+ // Create the pivot table, using the data from the "PastrySalesData" table
+ pt = ptSheet.PivotTables.AddNew("pvtHidesubTotals", ptSheet.Cell(1, 1), dataRange);
+
+ // The rows in our pivot table will be the names of the pastries
+ pt.RowLabels.Add(XLConstants.PivotTableValuesSentinalLabel);
+
+ // The columns will be the months
+ pt.ColumnLabels.Add("Month");
+ pt.ColumnLabels.Add("Name");
+
+ // The values in our table will come from the "NumberOfOrders" field
+ // The default calculation setting is a total of each row/column
+ pt.Values.Add("NumberOfOrders", "NumberOfOrdersPercentageOfBearclaw")
+ .ShowAsPercentageFrom("Name").And("Bearclaw")
+ .NumberFormat.Format = "0%";
+
+ pt.Values.Add("Quality", "Sum of Quality")
+ .NumberFormat.SetFormat("#,##0.00");
+
+ pt.Subtotals = XLPivotSubtotals.DoNotShow;
+
+ ptSheet.Columns().AdjustToContents();
+
+ #endregion Pivot table with subtotals disabled
+
wb.SaveAs(filePath);
}
}
diff --git a/ClosedXML_Examples/Ranges/UsingTables.cs b/ClosedXML_Examples/Ranges/UsingTables.cs
deleted file mode 100644
index e5c24b2..0000000
--- a/ClosedXML_Examples/Ranges/UsingTables.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System;
-using System.IO;
-using ClosedXML.Excel;
-using System.Linq;
-
-
-namespace ClosedXML_Examples.Ranges
-{
- public class UsingTables : IXLExample
- {
- #region Methods
-
- // Public
- public void Create(String filePath)
- {
- string tempFile = ExampleHelper.GetTempFilePath(filePath);
- try
- {
- new BasicTable().Create(tempFile);
- var wb = new XLWorkbook(tempFile);
- var ws = wb.Worksheet(1);
- ws.Name = "Contacts Table";
- var firstCell = ws.FirstCellUsed();
- var lastCell = ws.LastCellUsed();
- var range = ws.Range(firstCell.Address, lastCell.Address);
- range.FirstRow().Delete(); // Deleting the "Contacts" header (we don't need it for our purposes)
-
- // We want to use a theme for table, not the hard coded format of the BasicTable
- range.Clear(XLClearOptions.Formats);
- // Put back the date and number formats
- range.Column(4).Style.NumberFormat.NumberFormatId = 15;
- range.Column(5).Style.NumberFormat.Format = "$ #,##0";
-
- var table = range.CreateTable(); // You can also use range.AsTable() if you want to
- // manipulate the range as a table but don't want
- // to create the table in the worksheet.
-
- // Let's activate the Totals row and add the sum of Income
- table.ShowTotalsRow = true;
- table.Field("Income").TotalsRowFunction = XLTotalsRowFunction.Sum;
- // Just for fun let's add the text "Sum Of Income" to the totals row
- table.Field(0).TotalsRowLabel = "Sum Of Income";
-
- // Copy all the headers
- Int32 columnWithHeaders = lastCell.Address.ColumnNumber + 2;
- Int32 currentRow = table.RangeAddress.FirstAddress.RowNumber;
- ws.Cell(currentRow, columnWithHeaders).Value = "Table Headers";
- foreach (var cell in table.HeadersRow().Cells())
- {
- currentRow++;
- ws.Cell(currentRow, columnWithHeaders).Value = cell.Value;
- }
-
- // Format the headers as a table with a different style and no autofilters
- var htFirstCell = ws.Cell(table.RangeAddress.FirstAddress.RowNumber, columnWithHeaders);
- var htLastCell = ws.Cell(currentRow, columnWithHeaders);
- var headersTable = ws.Range(htFirstCell, htLastCell).CreateTable("Headers");
- headersTable.Theme = XLTableTheme.TableStyleLight10;
- headersTable.ShowAutoFilter = false;
-
- // Add a custom formula to the headersTable
- headersTable.ShowTotalsRow = true;
- headersTable.Field(0).TotalsRowFormulaA1 = "CONCATENATE(\"Count: \", CountA(Headers[Table Headers]))";
-
- // Copy the names
- Int32 columnWithNames = columnWithHeaders + 2;
- currentRow = table.RangeAddress.FirstAddress.RowNumber; // reset the currentRow
- ws.Cell(currentRow, columnWithNames).Value = "Names";
- foreach (var row in table.DataRange.Rows())
- {
- currentRow++;
- var fName = row.Field("FName").GetString(); // Notice how we're calling the cell by field name
- var lName = row.Field("LName").GetString(); // Notice how we're calling the cell by field name
- var name = String.Format("{0} {1}", fName, lName);
- ws.Cell(currentRow, columnWithNames).Value = name;
- }
-
- // Format the names as a table with a different style and no autofilters
- var ntFirstCell = ws.Cell(table.RangeAddress.FirstAddress.RowNumber, columnWithNames);
- var ntLastCell = ws.Cell(currentRow, columnWithNames);
- var namesTable = ws.Range(ntFirstCell, ntLastCell).CreateTable();
- namesTable.Theme = XLTableTheme.TableStyleLight12;
- namesTable.ShowAutoFilter = false;
-
- ws.Columns().AdjustToContents();
- ws.Columns("A,G,I").Width = 3;
-
- wb.SaveAs(filePath);
- }
- finally
- {
- if (File.Exists(tempFile))
- {
- File.Delete(tempFile);
- }
- }
- }
-
- // Private
-
- // Override
-
-
- #endregion
- }
-}
diff --git a/ClosedXML_Examples/Styles/UsingPhonetics.cs b/ClosedXML_Examples/Styles/UsingPhonetics.cs
index eaf2e32..f6c6483 100644
--- a/ClosedXML_Examples/Styles/UsingPhonetics.cs
+++ b/ClosedXML_Examples/Styles/UsingPhonetics.cs
@@ -23,8 +23,10 @@
// And then we add the phonetics
cell.RichText.Phonetics.SetFontSize(8);
- cell.RichText.Phonetics.Add("げん", 7, 1);
- cell.RichText.Phonetics.Add("き", 8, 1);
+ cell.RichText.Phonetics.Add("げん", 7, 8);
+ cell.RichText.Phonetics.Add("き", 8, 9);
+
+ //TODO: I'm looking for someone who understands Japanese to confirm the validity of the above code.
wb.SaveAs(filePath);
}
diff --git a/ClosedXML_Examples/Tables/InsertingTables.cs b/ClosedXML_Examples/Tables/InsertingTables.cs
new file mode 100644
index 0000000..176eed1
--- /dev/null
+++ b/ClosedXML_Examples/Tables/InsertingTables.cs
@@ -0,0 +1,111 @@
+using ClosedXML.Attributes;
+using ClosedXML.Excel;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+
+namespace ClosedXML_Examples.Tables
+{
+ public class InsertingTables : IXLExample
+ {
+ #region Methods
+
+ // Public
+ public void Create(String filePath)
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.Worksheets.Add("Inserting Tables");
+
+ // From a list of strings
+ var listOfStrings = new List();
+ listOfStrings.Add("House");
+ listOfStrings.Add("Car");
+ ws.Cell(1, 1).Value = "From Strings";
+ ws.Cell(1, 1).AsRange().AddToNamed("Titles");
+ ws.Cell(2, 1).InsertTable(listOfStrings);
+
+ // From a list of arrays
+ var listOfArr = new List();
+ listOfArr.Add(new Int32[] { 1, 2, 3 });
+ listOfArr.Add(new Int32[] { 1 });
+ listOfArr.Add(new Int32[] { 1, 2, 3, 4, 5, 6 });
+ ws.Cell(1, 3).Value = "From Arrays";
+ ws.Range(1, 3, 1, 8).Merge().AddToNamed("Titles");
+ ws.Cell(2, 3).InsertTable(listOfArr);
+
+ // From a DataTable
+ var dataTable = GetTable();
+ ws.Cell(7, 1).Value = "From DataTable";
+ ws.Range(7, 1, 7, 4).Merge().AddToNamed("Titles");
+ ws.Cell(8, 1).InsertTable(dataTable);
+
+ // From a query
+ var list = new List();
+ list.Add(new Person() { Name = "John", Age = 30, House = "On Elm St." });
+ list.Add(new Person() { Name = "Mary", Age = 15, House = "On Main St." });
+ list.Add(new Person() { Name = "Luis", Age = 21, House = "On 23rd St." });
+ list.Add(new Person() { Name = "Henry", Age = 45, House = "On 5th Ave." });
+
+ var people = from p in list
+ where p.Age >= 21
+ select p;
+
+ ws.Cell(7, 6).Value = "From Query";
+ ws.Range(7, 6, 7, 9).Merge().AddToNamed("Titles");
+ ws.Cell(8, 6).InsertTable(people);
+
+ ws.Cell(15, 6).Value = "From List";
+ ws.Range(15, 6, 15, 9).Merge().AddToNamed("Titles");
+ ws.Cell(16, 6).InsertTable(people);
+
+ // Prepare the style for the titles
+ var titlesStyle = wb.Style;
+ titlesStyle.Font.Bold = true;
+ titlesStyle.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
+ titlesStyle.Fill.BackgroundColor = XLColor.Cyan;
+
+ // Format all titles in one shot
+ wb.NamedRanges.NamedRange("Titles").Ranges.Style = titlesStyle;
+
+ ws.Columns().AdjustToContents();
+
+ wb.SaveAs(filePath);
+ }
+ }
+
+ private class Person
+ {
+ [XLColumn(Header = "House Street")]
+ public String House { get; set; }
+
+ public String Name { get; set; }
+ public Int32 Age { get; set; }
+
+ [XLColumn(Header = "Class Type")]
+ public static String ClassType { get { return nameof(Person); } }
+ }
+
+ // Private
+ private DataTable GetTable()
+ {
+ DataTable table = new DataTable();
+ table.Columns.Add("Dosage", typeof(int));
+ table.Columns.Add("Drug", typeof(string));
+ table.Columns.Add("Patient", typeof(string));
+ table.Columns.Add("Date", typeof(DateTime));
+
+ table.Rows.Add(25, "Indocin", "David", new DateTime(2000, 1, 1));
+ table.Rows.Add(50, "Enebrel", "Sam", new DateTime(2000, 1, 2));
+ table.Rows.Add(10, "Hydralazine", "Christoff", new DateTime(2000, 1, 3));
+ table.Rows.Add(21, "Combivent", "Janet", new DateTime(2000, 1, 4));
+ table.Rows.Add(100, "Dilantin", "Melanie", new DateTime(2000, 1, 5));
+ return table;
+ }
+
+ // Override
+
+ #endregion Methods
+ }
+}
diff --git a/ClosedXML_Examples/Tables/ResizingTables.cs b/ClosedXML_Examples/Tables/ResizingTables.cs
new file mode 100644
index 0000000..64ad34e
--- /dev/null
+++ b/ClosedXML_Examples/Tables/ResizingTables.cs
@@ -0,0 +1,47 @@
+using ClosedXML.Excel;
+using System;
+using System.Linq;
+
+// TODO: Add example to Wiki
+
+namespace ClosedXML_Examples.Tables
+{
+ public class ResizingTables : IXLExample
+ {
+ public void Create(string filePath)
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws1 = wb.AddWorksheet("Sheet1");
+
+ var data1 = Enumerable.Range(1, 10)
+ .Select(i =>
+ new
+ {
+ Index = i,
+ Character = Convert.ToChar(64 + i),
+ String = new String('a', i),
+ Integer = 64 + i
+ });
+
+ var table1 = ws1.Cell("B2").InsertTable(data1, true)
+ .SetShowHeaderRow()
+ .SetShowTotalsRow();
+
+ table1.Fields.First().TotalsRowLabel = "Sum of Integer";
+ table1.Fields.Last().TotalsRowFunction = XLTotalsRowFunction.Sum;
+
+ var ws2 = ws1.CopyTo("Sheet2");
+ var table2 = ws2.Tables.First();
+ table2.Resize(table2.FirstCell(), table2.LastCell().CellLeft().CellAbove(3));
+
+ var ws3 = ws2.CopyTo("Sheet3");
+ var table3 = ws3.Tables.First();
+ table3.Resize(table3.FirstCell().CellLeft(), table3.LastCell().CellRight().CellBelow(1));
+
+ wb.Worksheets.ForEach(ws => ws.Columns().AdjustToContents());
+ wb.SaveAs(filePath);
+ }
+ }
+ }
+}
diff --git a/ClosedXML_Examples/Tables/UsingTables.cs b/ClosedXML_Examples/Tables/UsingTables.cs
new file mode 100644
index 0000000..639a0a0
--- /dev/null
+++ b/ClosedXML_Examples/Tables/UsingTables.cs
@@ -0,0 +1,105 @@
+using ClosedXML.Excel;
+using System;
+using System.IO;
+
+namespace ClosedXML_Examples.Tables
+{
+ public class UsingTables : IXLExample
+ {
+ #region Methods
+
+ // Public
+ public void Create(String filePath)
+ {
+ string tempFile = ExampleHelper.GetTempFilePath(filePath);
+ try
+ {
+ new BasicTable().Create(tempFile);
+ using (var wb = new XLWorkbook(tempFile))
+ {
+ var ws = wb.Worksheet(1);
+ ws.Name = "Contacts Table";
+ var firstCell = ws.FirstCellUsed();
+ var lastCell = ws.LastCellUsed();
+ var range = ws.Range(firstCell.Address, lastCell.Address);
+ range.FirstRow().Delete(); // Deleting the "Contacts" header (we don't need it for our purposes)
+
+ // We want to use a theme for table, not the hard coded format of the BasicTable
+ range.Clear(XLClearOptions.Formats);
+ // Put back the date and number formats
+ range.Column(4).Style.NumberFormat.NumberFormatId = 15;
+ range.Column(5).Style.NumberFormat.Format = "$ #,##0";
+
+ var table = range.CreateTable(); // You can also use range.AsTable() if you want to
+ // manipulate the range as a table but don't want
+ // to create the table in the worksheet.
+
+ // Let's activate the Totals row and add the sum of Income
+ table.ShowTotalsRow = true;
+ table.Field("Income").TotalsRowFunction = XLTotalsRowFunction.Sum;
+ // Just for fun let's add the text "Sum Of Income" to the totals row
+ table.Field(0).TotalsRowLabel = "Sum Of Income";
+
+ // Copy all the headers
+ Int32 columnWithHeaders = lastCell.Address.ColumnNumber + 2;
+ Int32 currentRow = table.RangeAddress.FirstAddress.RowNumber;
+ ws.Cell(currentRow, columnWithHeaders).Value = "Table Headers";
+ foreach (var cell in table.HeadersRow().Cells())
+ {
+ currentRow++;
+ ws.Cell(currentRow, columnWithHeaders).Value = cell.Value;
+ }
+
+ // Format the headers as a table with a different style and no autofilters
+ var htFirstCell = ws.Cell(table.RangeAddress.FirstAddress.RowNumber, columnWithHeaders);
+ var htLastCell = ws.Cell(currentRow, columnWithHeaders);
+ var headersTable = ws.Range(htFirstCell, htLastCell).CreateTable("Headers");
+ headersTable.Theme = XLTableTheme.TableStyleLight10;
+ headersTable.ShowAutoFilter = false;
+
+ // Add a custom formula to the headersTable
+ headersTable.ShowTotalsRow = true;
+ headersTable.Field(0).TotalsRowFormulaA1 = "CONCATENATE(\"Count: \", CountA(Headers[Table Headers]))";
+
+ // Copy the names
+ Int32 columnWithNames = columnWithHeaders + 2;
+ currentRow = table.RangeAddress.FirstAddress.RowNumber; // reset the currentRow
+ ws.Cell(currentRow, columnWithNames).Value = "Names";
+ foreach (var row in table.DataRange.Rows())
+ {
+ currentRow++;
+ var fName = row.Field("FName").GetString(); // Notice how we're calling the cell by field name
+ var lName = row.Field("LName").GetString(); // Notice how we're calling the cell by field name
+ var name = String.Format("{0} {1}", fName, lName);
+ ws.Cell(currentRow, columnWithNames).Value = name;
+ }
+
+ // Format the names as a table with a different style and no autofilters
+ var ntFirstCell = ws.Cell(table.RangeAddress.FirstAddress.RowNumber, columnWithNames);
+ var ntLastCell = ws.Cell(currentRow, columnWithNames);
+ var namesTable = ws.Range(ntFirstCell, ntLastCell).CreateTable();
+ namesTable.Theme = XLTableTheme.TableStyleLight12;
+ namesTable.ShowAutoFilter = false;
+
+ ws.Columns().AdjustToContents();
+ ws.Columns("A,G,I").Width = 3;
+
+ wb.SaveAs(filePath);
+ }
+ }
+ finally
+ {
+ if (File.Exists(tempFile))
+ {
+ File.Delete(tempFile);
+ }
+ }
+ }
+
+ // Private
+
+ // Override
+
+ #endregion Methods
+ }
+}
diff --git a/ClosedXML_Tests/ClosedXML_Tests.csproj b/ClosedXML_Tests/ClosedXML_Tests.csproj
index 487ea3a..28a64f7 100644
--- a/ClosedXML_Tests/ClosedXML_Tests.csproj
+++ b/ClosedXML_Tests/ClosedXML_Tests.csproj
@@ -76,14 +76,19 @@
+
+
+
+
+
@@ -91,6 +96,7 @@
+
@@ -169,7 +175,6 @@
-
@@ -219,7 +224,6 @@
-
@@ -285,6 +289,13 @@
+
+
+
+
+
+
+
diff --git a/ClosedXML_Tests/Examples/MiscTests.cs b/ClosedXML_Tests/Examples/MiscTests.cs
index 4f14453..d74a9fc 100644
--- a/ClosedXML_Tests/Examples/MiscTests.cs
+++ b/ClosedXML_Tests/Examples/MiscTests.cs
@@ -133,11 +133,6 @@
TestHelper.RunTestExample(@"Misc\InsertingData.xlsx");
}
- [Test]
- public void InsertingTables()
- {
- TestHelper.RunTestExample(@"Misc\InsertingTables.xlsx");
- }
[Test]
public void LambdaExpressions()
@@ -204,11 +199,11 @@
{
TestHelper.RunTestExample(@"Misc\WorkbookProperties.xlsx");
}
-
+
[Test]
public void WorkbookProtection()
{
TestHelper.RunTestExample(@"Misc\WorkbookProtection.xlsx");
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Examples/RangesTests.cs b/ClosedXML_Tests/Examples/RangesTests.cs
index fe3e1e2..59cd62b 100644
--- a/ClosedXML_Tests/Examples/RangesTests.cs
+++ b/ClosedXML_Tests/Examples/RangesTests.cs
@@ -99,12 +99,6 @@
}
[Test]
- public void UsingTables()
- {
- TestHelper.RunTestExample(@"Ranges\UsingTables.xlsx");
- }
-
- [Test]
public void AddingRowToTables()
{
TestHelper.RunTestExample(@"Ranges\AddingRowToTables.xlsx");
@@ -116,4 +110,4 @@
TestHelper.RunTestExample(@"Ranges\WalkingRanges.xlsx");
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Examples/StylesTests.cs b/ClosedXML_Tests/Examples/StylesTests.cs
index 4ecfb15..c400a81 100644
--- a/ClosedXML_Tests/Examples/StylesTests.cs
+++ b/ClosedXML_Tests/Examples/StylesTests.cs
@@ -67,9 +67,15 @@
}
[Test]
+ public void UsingPhonetics()
+ {
+ TestHelper.RunTestExample(@"Styles\UsingPhonetics.xlsx");
+ }
+
+ [Test]
public void UsingRichText()
{
TestHelper.RunTestExample(@"Styles\UsingRichText.xlsx");
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Examples/TablesTests.cs b/ClosedXML_Tests/Examples/TablesTests.cs
new file mode 100644
index 0000000..934bf65
--- /dev/null
+++ b/ClosedXML_Tests/Examples/TablesTests.cs
@@ -0,0 +1,27 @@
+using ClosedXML_Examples.Tables;
+using NUnit.Framework;
+
+namespace ClosedXML_Tests.Examples
+{
+ [TestFixture]
+ public class TablesTests
+ {
+ [Test]
+ public void InsertingTables()
+ {
+ TestHelper.RunTestExample(@"Tables\InsertingTables.xlsx");
+ }
+
+ [Test]
+ public void ResizingTables()
+ {
+ TestHelper.RunTestExample(@"Tables\ResizingTables.xlsx");
+ }
+
+ [Test]
+ public void UsingTables()
+ {
+ TestHelper.RunTestExample(@"Tables\UsingTables.xlsx");
+ }
+ }
+}
diff --git a/ClosedXML_Tests/Excel/CalcEngine/CalcEngineExceptionTests.cs b/ClosedXML_Tests/Excel/CalcEngine/CalcEngineExceptionTests.cs
new file mode 100644
index 0000000..b1be35f
--- /dev/null
+++ b/ClosedXML_Tests/Excel/CalcEngine/CalcEngineExceptionTests.cs
@@ -0,0 +1,29 @@
+using ClosedXML.Excel;
+using ClosedXML.Excel.CalcEngine.Exceptions;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace ClosedXML_Tests.Excel.CalcEngine
+{
+ [TestFixture]
+ public class CalcEngineExceptionTests
+ {
+ [OneTimeSetUp]
+ public void SetCultureInfo()
+ {
+ Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
+ }
+
+ [Test]
+ public void InvalidCharNumber()
+ {
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("CHAR(-2)"));
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("CHAR(270)"));
+ }
+ }
+}
diff --git a/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs b/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs
index 3fca48e..3ad7f8e 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs
@@ -620,7 +620,7 @@
Assert.AreEqual(0, cell.Value);
cell = wb.Worksheet(1).Cell(3, 1).SetFormulaA1("=SUM(D1,D2)");
Assert.AreEqual(0, cell.Value);
- Assert.That(() => wb.Worksheet(1).Cell(3, 1).SetFormulaA1("=AVERAGE(D1,D2)").Value, Throws.Exception);
+ Assert.That(() => wb.Worksheet(1).Cell(3, 1).SetFormulaA1("=AVERAGE(D1,D2)").Value, Throws.TypeOf());
}
[Test]
diff --git a/ClosedXML_Tests/Excel/CalcEngine/InformationTests.cs b/ClosedXML_Tests/Excel/CalcEngine/InformationTests.cs
index 93ad203..19de6ca 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/InformationTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/InformationTests.cs
@@ -158,6 +158,17 @@
}
#endregion IsLogical Tests
+ [Test]
+ public void IsNA()
+ {
+ object actual;
+ actual = XLWorkbook.EvaluateExpr("ISNA(#N/A)");
+ Assert.AreEqual(true, actual);
+
+ actual = XLWorkbook.EvaluateExpr("ISNA(#REF!)");
+ Assert.AreEqual(false, actual);
+ }
+
#region IsNotText Tests
[Test]
@@ -288,6 +299,30 @@
}
#endregion IsOdd Test
+ [Test]
+ public void IsRef()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet");
+ ws.Cell("A1").Value = "123";
+
+ ws.Cell("B1").FormulaA1 = "ISREF(A1)";
+ ws.Cell("B2").FormulaA1 = "ISREF(5)";
+ ws.Cell("B3").FormulaA1 = "ISREF(YEAR(TODAY()))";
+
+ bool actual;
+ actual = ws.Cell("B1").GetValue();
+ Assert.AreEqual(true, actual);
+
+ actual = ws.Cell("B2").GetValue();
+ Assert.AreEqual(false, actual);
+
+ actual = ws.Cell("B3").GetValue();
+ Assert.AreEqual(false, actual);
+ }
+ }
+
#region IsText Tests
[Test]
diff --git a/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs b/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs
index a112f3d..a18e509 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs
@@ -1,4 +1,5 @@
using ClosedXML.Excel;
+using ClosedXML.Excel.CalcEngine.Exceptions;
using NUnit.Framework;
using System;
@@ -106,6 +107,12 @@
value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8,TRUE)");
Assert.AreEqual(179.64, value);
+ value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8)");
+ Assert.AreEqual(179.64, value);
+
+ value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8,)");
+ Assert.AreEqual(179.64, value);
+
value = workbook.Evaluate("=VLOOKUP(14.5,Data!$B$2:$I$71,8,TRUE)");
Assert.AreEqual(174.65, value);
@@ -116,11 +123,11 @@
[Test]
public void Vlookup_Exceptions()
{
- Assert.That(() => workbook.Evaluate(@"=VLOOKUP("""",Data!$B$2:$I$71,3,FALSE)"), Throws.Exception);
- Assert.That(() => workbook.Evaluate(@"=VLOOKUP(50,Data!$B$2:$I$71,3,FALSE)"), Throws.Exception);
- Assert.That(() => workbook.Evaluate(@"=VLOOKUP(20,Data!$B$2:$I$71,9,FALSE)"), Throws.Exception);
+ Assert.Throws(() => workbook.Evaluate(@"=VLOOKUP("""",Data!$B$2:$I$71,3,FALSE)"));
+ Assert.Throws(() => workbook.Evaluate(@"=VLOOKUP(50,Data!$B$2:$I$71,3,FALSE)"));
+ Assert.Throws(() => workbook.Evaluate(@"=VLOOKUP(-1,Data!$B$2:$I$71,2,TRUE)"));
- Assert.That(() => workbook.Evaluate(@"=VLOOKUP(-1,Data!$B$2:$I$71,9,TRUE)"), Throws.Exception);
+ Assert.Throws(() => workbook.Evaluate(@"=VLOOKUP(20,Data!$B$2:$I$71,9,FALSE)"));
}
}
}
diff --git a/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs b/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs
new file mode 100644
index 0000000..5012bb5
--- /dev/null
+++ b/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs
@@ -0,0 +1,123 @@
+using ClosedXML.Excel;
+using NUnit.Framework;
+using System;
+
+namespace ClosedXML_Tests.Excel.CalcEngine
+{
+ [TestFixture]
+ public class MathTrigTests
+ {
+ private readonly double tolerance = 1e-10;
+
+ [Test]
+ public void Floor()
+ {
+ Object actual;
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(1.2)");
+ Assert.AreEqual(1, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(1.7)");
+ Assert.AreEqual(1, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(-1.7)");
+ Assert.AreEqual(-2, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(1.2, 1)");
+ Assert.AreEqual(1, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(1.7, 1)");
+ Assert.AreEqual(1, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(-1.7, 1)");
+ Assert.AreEqual(-2, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(0.4, 2)");
+ Assert.AreEqual(0, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(2.7, 2)");
+ Assert.AreEqual(2, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(7.8, 2)");
+ Assert.AreEqual(6, actual);
+
+ actual = XLWorkbook.EvaluateExpr(@"FLOOR(-5.5, -2)");
+ Assert.AreEqual(-4, actual);
+ }
+
+ [Test]
+ // Functions have to support a period first before we can implement this
+ public void FloorMath()
+ {
+ double actual;
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(24.3, 5)");
+ Assert.AreEqual(20, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(6.7)");
+ Assert.AreEqual(6, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(-8.1, 2)");
+ Assert.AreEqual(-10, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(5.5, 2.1, 0)");
+ Assert.AreEqual(4.2, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(5.5, -2.1, 0)");
+ Assert.AreEqual(4.2, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(5.5, 2.1, -1)");
+ Assert.AreEqual(4.2, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(5.5, -2.1, -1)");
+ Assert.AreEqual(4.2, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(-5.5, 2.1, 0)");
+ Assert.AreEqual(-6.3, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(-5.5, -2.1, 0)");
+ Assert.AreEqual(-6.3, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(-5.5, 2.1, -1)");
+ Assert.AreEqual(-4.2, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"FLOOR.MATH(-5.5, -2.1, -1)");
+ Assert.AreEqual(-4.2, actual, tolerance);
+ }
+
+ [Test]
+ public void Mod()
+ {
+ double actual;
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(1.5, 1)");
+ Assert.AreEqual(0.5, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(3, 2)");
+ Assert.AreEqual(1, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(-3, 2)");
+ Assert.AreEqual(1, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(3, -2)");
+ Assert.AreEqual(-1, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(-3, -2)");
+ Assert.AreEqual(-1, actual, tolerance);
+
+ //////
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(-4.3, -0.5)");
+ Assert.AreEqual(-0.3, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(6.9, -0.2)");
+ Assert.AreEqual(-0.1, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(0.7, 0.6)");
+ Assert.AreEqual(0.1, actual, tolerance);
+
+ actual = (double)XLWorkbook.EvaluateExpr(@"MOD(6.2, 1.1)");
+ Assert.AreEqual(0.7, actual, tolerance);
+ }
+ }
+}
diff --git a/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs b/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs
index c59e34d..2550868 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs
@@ -22,7 +22,7 @@
value = ws.Evaluate("AVERAGE(G3:G45)").CastTo();
Assert.AreEqual(49.3255814, value, tolerance);
- Assert.That(() => ws.Evaluate("AVERAGE(D3:D45)"), Throws.Exception);
+ Assert.That(() => ws.Evaluate("AVERAGE(D3:D45)"), Throws.TypeOf());
}
[Test]
@@ -146,7 +146,7 @@
{
var ws = workbook.Worksheets.First();
double value;
- Assert.That(() => ws.Evaluate(@"=STDEV(D3:D45)"), Throws.Exception);
+ Assert.That(() => ws.Evaluate(@"=STDEV(D3:D45)"), Throws.TypeOf());
value = ws.Evaluate(@"=STDEV(H3:H45)").CastTo();
Assert.AreEqual(47.34511769, value, tolerance);
@@ -163,7 +163,7 @@
{
var ws = workbook.Worksheets.First();
double value;
- Assert.That(() => ws.Evaluate(@"=STDEVP(D3:D45)"), Throws.Exception);
+ Assert.That(() => ws.Evaluate(@"=STDEVP(D3:D45)"), Throws.InvalidOperationException);
value = ws.Evaluate(@"=STDEVP(H3:H45)").CastTo();
Assert.AreEqual(46.79135458, value, tolerance);
@@ -180,7 +180,7 @@
{
var ws = workbook.Worksheets.First();
double value;
- Assert.That(() => ws.Evaluate(@"=VAR(D3:D45)"), Throws.Exception);
+ Assert.That(() => ws.Evaluate(@"=VAR(D3:D45)"), Throws.InvalidOperationException);
value = ws.Evaluate(@"=VAR(H3:H45)").CastTo();
Assert.AreEqual(2241.560169, value, tolerance);
@@ -197,7 +197,7 @@
{
var ws = workbook.Worksheets.First();
double value;
- Assert.That(() => ws.Evaluate(@"=VARP(D3:D45)"), Throws.Exception);
+ Assert.That(() => ws.Evaluate(@"=VARP(D3:D45)"), Throws.InvalidOperationException);
value = ws.Evaluate(@"=VARP(H3:H45)").CastTo();
Assert.AreEqual(2189.430863, value, tolerance);
diff --git a/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs b/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs
index 3a89de2..59d0a59 100644
--- a/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs
+++ b/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs
@@ -1,4 +1,6 @@
using ClosedXML.Excel;
+using ClosedXML.Excel.CalcEngine;
+using ClosedXML.Excel.CalcEngine.Exceptions;
using NUnit.Framework;
using System;
using System.Globalization;
@@ -19,13 +21,13 @@
[Test]
public void Char_Empty_Input_String()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Char("""")"), Throws.Exception);
+ Assert.Throws(() => XLWorkbook.EvaluateExpr(@"Char("""")"));
}
[Test]
public void Char_Input_Too_Large()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Char(9797)"), Throws.Exception);
+ Assert.Throws< CellValueException>(() => XLWorkbook.EvaluateExpr(@"Char(9797)"));
}
[Test]
@@ -56,7 +58,7 @@
public void Code_Empty_Input_String()
{
// Todo: more specific exception - ValueException?
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Code("""")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Code("""")"), Throws.TypeOf());
}
[Test]
@@ -82,7 +84,7 @@
[Test]
public void Dollar_Empty_Input_String()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Dollar("", 3)"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Dollar("", 3)"), Throws.TypeOf());
}
[Test]
@@ -121,26 +123,26 @@
[Test]
public void Find_Start_Position_Too_Large()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Find(""abc"", ""abcdef"", 10)"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Find(""abc"", ""abcdef"", 10)"), Throws.TypeOf());
}
[Test]
public void Find_String_In_Another_Empty_String()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Find(""abc"", """")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Find(""abc"", """")"), Throws.TypeOf());
}
[Test]
public void Find_String_Not_Found()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Find(""123"", ""asdf"")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Find(""123"", ""asdf"")"), Throws.TypeOf());
}
[Test]
public void Find_Case_Sensitive_String_Not_Found()
{
// Find is case-sensitive
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Find(""excel"", ""Microsoft Excel 2010"")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Find(""excel"", ""Microsoft Excel 2010"")"), Throws.TypeOf());
}
[Test]
@@ -159,7 +161,7 @@
[Test]
public void Fixed_Input_Is_String()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Fixed(""asdf"")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Fixed(""asdf"")"), Throws.TypeOf());
}
[Test]
@@ -297,7 +299,7 @@
[Test]
public void Rept_Start_Is_Negative()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Rept(""Francois"", -1)"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Rept(""Francois"", -1)"), Throws.TypeOf());
}
[Test]
@@ -344,7 +346,7 @@
[Test]
public void Search_No_Parameters_With_Values()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Search("""", """")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Search("""", """")"), Throws.TypeOf());
}
[Test]
@@ -357,31 +359,31 @@
[Test]
public void Search_Start_Position_Too_Large()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""abc"", ""abcdef"", 10)"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""abc"", ""abcdef"", 10)"), Throws.TypeOf());
}
[Test]
public void Search_Empty_Input_String()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""abc"", """")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""abc"", """")"), Throws.TypeOf());
}
[Test]
public void Search_String_Not_Found()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""123"", ""asdf"")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""123"", ""asdf"")"), Throws.TypeOf());
}
[Test]
public void Search_Wildcard_String_Not_Found()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""soft?2010"", ""Microsoft Excel 2010"")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""soft?2010"", ""Microsoft Excel 2010"")"), Throws.TypeOf());
}
[Test]
public void Search_Start_Position_Too_Large2()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""text"", ""This is some text"", 15)"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Search(""text"", ""This is some text"", 15)"), Throws.TypeOf());
}
// http://www.excel-easy.com/examples/find-vs-search.html
@@ -517,7 +519,7 @@
[Test]
public void Value_Input_String_Is_Not_A_Number()
{
- Assert.That(() => XLWorkbook.EvaluateExpr(@"Value(""asdf"")"), Throws.Exception);
+ Assert.That(() => XLWorkbook.EvaluateExpr(@"Value(""asdf"")"), Throws.TypeOf());
}
[Test]
diff --git a/ClosedXML_Tests/Excel/Cells/XLCellTests.cs b/ClosedXML_Tests/Excel/Cells/XLCellTests.cs
index 3ca287e..cfa1951 100644
--- a/ClosedXML_Tests/Excel/Cells/XLCellTests.cs
+++ b/ClosedXML_Tests/Excel/Cells/XLCellTests.cs
@@ -83,6 +83,22 @@
}
[Test]
+ public void InsertData2()
+ {
+ IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
+ IXLRange range = ws.Cell(2, 2).InsertData(new[] { "a", "b", "c" }, false);
+ Assert.AreEqual("Sheet1!B2:B4", range.ToString());
+ }
+
+ [Test]
+ public void InsertData3()
+ {
+ IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
+ IXLRange range = ws.Cell(2, 2).InsertData(new[] { "a", "b", "c" }, true);
+ Assert.AreEqual("Sheet1!B2:D2", range.ToString());
+ }
+
+ [Test]
public void IsEmpty1()
{
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
@@ -388,5 +404,27 @@
Assert.AreEqual("\u0018", wb.Worksheets.First().FirstCell().Value);
}
}
+
+ [Test]
+ public void CanClearCellValueBySettingNullValue()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet1");
+ var cell = ws.FirstCell();
+
+ cell.Value = "Test";
+ Assert.AreEqual("Test", cell.Value);
+ Assert.AreEqual(XLCellValues.Text, cell.DataType);
+
+ string s = null;
+ cell.SetValue(s);
+ Assert.AreEqual(string.Empty, cell.Value);
+
+ cell.Value = "Test";
+ cell.Value = null;
+ Assert.AreEqual(string.Empty, cell.Value);
+ }
+ }
}
}
diff --git a/ClosedXML_Tests/Excel/Coordinates/XLAddressTests.cs b/ClosedXML_Tests/Excel/Coordinates/XLAddressTests.cs
index 4d0329f..686c1f4 100644
--- a/ClosedXML_Tests/Excel/Coordinates/XLAddressTests.cs
+++ b/ClosedXML_Tests/Excel/Coordinates/XLAddressTests.cs
@@ -9,13 +9,14 @@
[Test]
public void ToStringTest()
{
- IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
+ var ws = new XLWorkbook().Worksheets.Add("Sheet1");
IXLAddress address = ws.Cell(1, 1).Address;
Assert.AreEqual("A1", address.ToString());
Assert.AreEqual("A1", address.ToString(XLReferenceStyle.A1));
Assert.AreEqual("R1C1", address.ToString(XLReferenceStyle.R1C1));
Assert.AreEqual("A1", address.ToString(XLReferenceStyle.Default));
+ Assert.AreEqual("Sheet1!A1", address.ToString(XLReferenceStyle.Default, true));
Assert.AreEqual("A1", address.ToStringRelative());
Assert.AreEqual("Sheet1!A1", address.ToStringRelative(true));
@@ -39,6 +40,7 @@
Assert.AreEqual("A1", address.ToString(XLReferenceStyle.A1));
Assert.AreEqual("R1C1", address.ToString(XLReferenceStyle.R1C1));
Assert.AreEqual("A1", address.ToString(XLReferenceStyle.Default));
+ Assert.AreEqual("'Sheet 1'!A1", address.ToString(XLReferenceStyle.Default, true));
Assert.AreEqual("A1", address.ToStringRelative());
Assert.AreEqual("'Sheet 1'!A1", address.ToStringRelative(true));
diff --git a/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs b/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
index b0ba0d6..a06902e 100644
--- a/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
+++ b/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
@@ -145,6 +145,35 @@
}
[Test]
+ public void TestDefaultIds()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet1");
+
+ using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClosedXML_Tests.Resource.Images.ImageHandling.png"))
+ {
+ ws.AddPicture(stream, XLPictureFormat.Png);
+ stream.Position = 0;
+
+ ws.AddPicture(stream, XLPictureFormat.Png);
+ stream.Position = 0;
+
+ ws.AddPicture(stream, XLPictureFormat.Png).Name = "Picture 4";
+ stream.Position = 0;
+
+ ws.AddPicture(stream, XLPictureFormat.Png);
+ stream.Position = 0;
+ }
+
+ Assert.AreEqual(1, ws.Pictures.Skip(0).First().Id);
+ Assert.AreEqual(2, ws.Pictures.Skip(1).First().Id);
+ Assert.AreEqual(3, ws.Pictures.Skip(2).First().Id);
+ Assert.AreEqual(4, ws.Pictures.Skip(3).First().Id);
+ }
+ }
+
+ [Test]
public void XLMarkerTests()
{
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
diff --git a/ClosedXML_Tests/Excel/Loading/LoadingTests.cs b/ClosedXML_Tests/Excel/Loading/LoadingTests.cs
index 218ae90..5b1fc42 100644
--- a/ClosedXML_Tests/Excel/Loading/LoadingTests.cs
+++ b/ClosedXML_Tests/Excel/Loading/LoadingTests.cs
@@ -1,6 +1,8 @@
using ClosedXML.Excel;
using ClosedXML.Excel.Drawings;
+using ClosedXML_Tests.Utils;
using NUnit.Framework;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -27,7 +29,10 @@
@"Misc\InvalidPrintTitles.xlsx",
@"Misc\ExcelProducedWorkbookWithImages.xlsx",
@"Misc\EmptyCellValue.xlsx",
- @"Misc\AllShapes.xlsx"
+ @"Misc\AllShapes.xlsx",
+ @"Misc\TableHeadersWithLineBreaks.xlsx",
+ @"Misc\TableWithNameNull.xlsx",
+ @"Misc\DuplicateImageNames.xlsx"
};
foreach (var file in files)
@@ -178,5 +183,26 @@
wb.SaveAs(ms, true);
}
}
+
+ [Test]
+ public void CanLoadFromTemplate()
+ {
+ using (var tf1 = new TemporaryFile())
+ using (var tf2 = new TemporaryFile())
+ {
+ using (var stream = TestHelper.GetStreamFromResource(TestHelper.GetResourcePath(@"Misc\AllShapes.xlsx")))
+ using (var wb = new XLWorkbook(stream))
+ {
+ // Save as temporary file
+ wb.SaveAs(tf1.Path);
+ }
+
+ var workbook = XLWorkbook.OpenFromTemplate(tf1.Path);
+ Assert.True(workbook.Worksheets.Any());
+ Assert.Throws(() => workbook.Save());
+
+ workbook.SaveAs(tf2.Path);
+ }
+ }
}
}
diff --git a/ClosedXML_Tests/Excel/Misc/FormulaTests.cs b/ClosedXML_Tests/Excel/Misc/FormulaTests.cs
index 8d2d470..3ff4c55 100644
--- a/ClosedXML_Tests/Excel/Misc/FormulaTests.cs
+++ b/ClosedXML_Tests/Excel/Misc/FormulaTests.cs
@@ -1,4 +1,5 @@
using ClosedXML.Excel;
+using ClosedXML.Excel.CalcEngine.Exceptions;
using NUnit.Framework;
using System;
using System.Linq;
@@ -156,5 +157,34 @@
Assert.AreEqual(6, actual);
}
}
+
+ [Test]
+ public void FormulaThatStartsWithEqualsAndPlus()
+ {
+ object actual;
+ actual = XLWorkbook.EvaluateExpr("=MID(\"This is a test\", 6, 2)");
+ Assert.AreEqual("is", actual);
+
+ actual = XLWorkbook.EvaluateExpr("=+MID(\"This is a test\", 6, 2)");
+ Assert.AreEqual("is", actual);
+
+ actual = XLWorkbook.EvaluateExpr("=+++++MID(\"This is a test\", 6, 2)");
+ Assert.AreEqual("is", actual);
+
+ actual = XLWorkbook.EvaluateExpr("+MID(\"This is a test\", 6, 2)");
+ Assert.AreEqual("is", actual);
+ }
+
+ [Test]
+ public void FormulasWithErrors()
+ {
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("YEAR(#REF!)"));
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("YEAR(#VALUE!)"));
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("YEAR(#DIV/0!)"));
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("YEAR(#NAME?)"));
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("YEAR(#N/A)"));
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("YEAR(#NULL!)"));
+ Assert.Throws(() => XLWorkbook.EvaluateExpr("YEAR(#NUM!)"));
+ }
}
}
diff --git a/ClosedXML_Tests/Excel/Misc/HyperlinkTests.cs b/ClosedXML_Tests/Excel/Misc/HyperlinkTests.cs
new file mode 100644
index 0000000..95b2431
--- /dev/null
+++ b/ClosedXML_Tests/Excel/Misc/HyperlinkTests.cs
@@ -0,0 +1,32 @@
+using ClosedXML.Excel;
+using NUnit.Framework;
+
+namespace ClosedXML_Tests.Excel.Misc
+{
+ [TestFixture]
+ public class HyperlinkTests
+ {
+ [Test]
+ public void TestHyperlinks()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws1 = wb.Worksheets.Add("Sheet1");
+ var ws2 = wb.Worksheets.Add("Sheet2");
+
+ var targetCell = ws2.Cell("A1");
+ var targetRange = ws2.Range("A1", "B1");
+
+ var linkCell1 = ws1.Cell("A1");
+ linkCell1.Value = "Link to IXLCell";
+ linkCell1.Hyperlink = new XLHyperlink(targetCell);
+ Assert.AreEqual("Sheet2!A1", linkCell1.Hyperlink.InternalAddress);
+
+ var linkRange1 = ws1.Cell("A2");
+ linkRange1.Value = "Link to IXLRangeBase";
+ linkRange1.Hyperlink = new XLHyperlink(targetRange);
+ Assert.AreEqual("Sheet2!A1:B1", linkRange1.Hyperlink.InternalAddress);
+ }
+ }
+ }
+}
diff --git a/ClosedXML_Tests/Excel/Misc/SearchTests.cs b/ClosedXML_Tests/Excel/Misc/SearchTests.cs
new file mode 100644
index 0000000..21e299d
--- /dev/null
+++ b/ClosedXML_Tests/Excel/Misc/SearchTests.cs
@@ -0,0 +1,78 @@
+using ClosedXML.Excel;
+using NUnit.Framework;
+using System.Globalization;
+using System.Linq;
+
+namespace ClosedXML_Tests.Excel.Misc
+{
+ [TestFixture]
+ public class SearchTests
+ {
+ [Test]
+ public void TestSearch()
+ {
+ using (var stream = TestHelper.GetStreamFromResource(TestHelper.GetResourcePath(@"Examples\Misc\CellValues.xlsx")))
+ using (var wb = new XLWorkbook(stream))
+ {
+ var ws = wb.Worksheets.First();
+
+ IXLCells foundCells;
+
+ foundCells = ws.Search("Initial Value");
+ Assert.AreEqual(1, foundCells.Count());
+ Assert.AreEqual("B2", foundCells.Single().Address.ToString());
+ Assert.AreEqual("Initial Value", foundCells.Single().GetString());
+
+ foundCells = ws.Search("Using");
+ Assert.AreEqual(2, foundCells.Count());
+ Assert.AreEqual("D2", foundCells.First().Address.ToString());
+ Assert.AreEqual("Using Get...()", foundCells.First().GetString());
+ Assert.AreEqual(2, foundCells.Count());
+ Assert.AreEqual("E2", foundCells.Last().Address.ToString());
+ Assert.AreEqual("Using GetValue()", foundCells.Last().GetString());
+
+ foundCells = ws.Search("1234");
+ Assert.AreEqual(4, foundCells.Count());
+ Assert.AreEqual("C5,D5,E5,F5", string.Join(",", foundCells.Select(c => c.Address.ToString()).ToArray()));
+
+ foundCells = ws.Search("Sep");
+ Assert.AreEqual(2, foundCells.Count());
+ Assert.AreEqual("B3,G3", string.Join(",", foundCells.Select(c => c.Address.ToString()).ToArray()));
+
+ foundCells = ws.Search("1234", CompareOptions.Ordinal, true);
+ Assert.AreEqual(5, foundCells.Count());
+ Assert.AreEqual("B5,C5,D5,E5,F5", string.Join(",", foundCells.Select(c => c.Address.ToString()).ToArray()));
+
+ foundCells = ws.Search("test case", CompareOptions.Ordinal);
+ Assert.AreEqual(0, foundCells.Count());
+
+ foundCells = ws.Search("test case", CompareOptions.OrdinalIgnoreCase);
+ Assert.AreEqual(6, foundCells.Count());
+ }
+ }
+
+ [Test]
+ public void TestSearch2()
+ {
+ using (var stream = TestHelper.GetStreamFromResource(TestHelper.GetResourcePath(@"Examples\Misc\Formulas.xlsx")))
+ using (var wb = new XLWorkbook(stream))
+ {
+ var ws = wb.Worksheets.First();
+
+ IXLCells foundCells;
+
+ foundCells = ws.Search("3", CompareOptions.Ordinal);
+ Assert.AreEqual(10, foundCells.Count());
+ Assert.AreEqual("C2", foundCells.First().Address.ToString());
+
+ foundCells = ws.Search("A2", CompareOptions.Ordinal, true);
+ Assert.AreEqual(6, foundCells.Count());
+ Assert.AreEqual("C2,D2,B6,C6,D6,A11", string.Join(",", foundCells.Select(c => c.Address.ToString()).ToArray()));
+
+ foundCells = ws.Search("RC", CompareOptions.Ordinal, true);
+ Assert.AreEqual(3, foundCells.Count());
+ Assert.AreEqual("E2,E3,E4", string.Join(",", foundCells.Select(c => c.Address.ToString()).ToArray()));
+ }
+ }
+ }
+}
diff --git a/ClosedXML_Tests/Excel/NamedRanges/NamedRangesTests.cs b/ClosedXML_Tests/Excel/NamedRanges/NamedRangesTests.cs
index 907bc96..afe5c7b 100644
--- a/ClosedXML_Tests/Excel/NamedRanges/NamedRangesTests.cs
+++ b/ClosedXML_Tests/Excel/NamedRanges/NamedRangesTests.cs
@@ -140,5 +140,38 @@
Assert.Throws(() => wb.NamedRanges.Add("MyRange", "A1:C1"));
}
}
+
+ [Test]
+ public void NamedRangesWhenCopyingWorksheets()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws1 = wb.AddWorksheet("Sheet1");
+ ws1.FirstCell().Value = Enumerable.Range(1, 10);
+ wb.NamedRanges.Add("wbNamedRange", ws1.Range("A1:A10"));
+ ws1.NamedRanges.Add("wsNamedRange", ws1.Range("A3"));
+
+ var ws2 = wb.AddWorksheet("Sheet2");
+ ws2.FirstCell().Value = Enumerable.Range(101, 10);
+ ws1.NamedRanges.Add("wsNamedRangeAcrossSheets", ws2.Range("A4"));
+
+ ws1.Cell("C1").FormulaA1 = "=wbNamedRange";
+ ws1.Cell("C2").FormulaA1 = "=wsNamedRange";
+ ws1.Cell("C3").FormulaA1 = "=wsNamedRangeAcrossSheets";
+
+ Assert.AreEqual(1, ws1.Cell("C1").Value);
+ Assert.AreEqual(3, ws1.Cell("C2").Value);
+ Assert.AreEqual(104, ws1.Cell("C3").Value);
+
+ var wsCopy = ws1.CopyTo("Copy");
+ Assert.AreEqual(1, wsCopy.Cell("C1").Value);
+ Assert.AreEqual(3, wsCopy.Cell("C2").Value);
+ Assert.AreEqual(104, wsCopy.Cell("C3").Value);
+
+ Assert.AreEqual("Sheet1!A1:A10", wb.NamedRange("wbNamedRange").Ranges.First().RangeAddress.ToStringRelative(true));
+ Assert.AreEqual("Copy!A3:A3", wsCopy.NamedRange("wsNamedRange").Ranges.First().RangeAddress.ToStringRelative(true));
+ Assert.AreEqual("Sheet2!A4:A4", wsCopy.NamedRange("wsNamedRangeAcrossSheets").Ranges.First().RangeAddress.ToStringRelative(true));
+ }
+ }
}
}
diff --git a/ClosedXML_Tests/Excel/Ranges/XLRangeAddressTests.cs b/ClosedXML_Tests/Excel/Ranges/XLRangeAddressTests.cs
index 669e811..c103c6e 100644
--- a/ClosedXML_Tests/Excel/Ranges/XLRangeAddressTests.cs
+++ b/ClosedXML_Tests/Excel/Ranges/XLRangeAddressTests.cs
@@ -13,6 +13,7 @@
IXLRangeAddress address = ws.Cell(1, 1).AsRange().RangeAddress;
Assert.AreEqual("A1:A1", address.ToString());
+ Assert.AreEqual("Sheet1!R1C1:R1C1", address.ToString(XLReferenceStyle.R1C1, true));
Assert.AreEqual("A1:A1", address.ToStringRelative());
Assert.AreEqual("Sheet1!A1:A1", address.ToStringRelative(true));
@@ -33,6 +34,7 @@
IXLRangeAddress address = ws.Cell(1, 1).AsRange().RangeAddress;
Assert.AreEqual("A1:A1", address.ToString());
+ Assert.AreEqual("'Sheet 1'!R1C1:R1C1", address.ToString(XLReferenceStyle.R1C1, true));
Assert.AreEqual("A1:A1", address.ToStringRelative());
Assert.AreEqual("'Sheet 1'!A1:A1", address.ToStringRelative(true));
diff --git a/ClosedXML_Tests/Excel/Rows/RowTests.cs b/ClosedXML_Tests/Excel/Rows/RowTests.cs
index 17cddeb..bb74d4f 100644
--- a/ClosedXML_Tests/Excel/Rows/RowTests.cs
+++ b/ClosedXML_Tests/Excel/Rows/RowTests.cs
@@ -185,6 +185,36 @@
}
[Test]
+ public void InsertingRowsAbove4()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.Worksheets.Add("Sheet1");
+
+ ws.Row(2).Height = 15;
+ ws.Row(3).Height = 20;
+ ws.Row(4).Height = 25;
+ ws.Row(5).Height = 35;
+
+ ws.Row(2).FirstCell().SetValue("Row height: 15");
+ ws.Row(3).FirstCell().SetValue("Row height: 20");
+ ws.Row(4).FirstCell().SetValue("Row height: 25");
+ ws.Row(5).FirstCell().SetValue("Row height: 35");
+
+ ws.Range("3:3").InsertRowsAbove(1);
+
+ Assert.AreEqual(15, ws.Row(2).Height);
+ Assert.AreEqual(20, ws.Row(4).Height);
+ Assert.AreEqual(25, ws.Row(5).Height);
+ Assert.AreEqual(35, ws.Row(6).Height);
+
+ Assert.AreEqual(20, ws.Row(3).Height);
+ ws.Row(3).ClearHeight();
+ Assert.AreEqual(ws.RowHeight, ws.Row(3).Height);
+ }
+ }
+
+ [Test]
public void NoRowsUsed()
{
var wb = new XLWorkbook();
@@ -224,4 +254,4 @@
ws.Rows(1, 2).Ungroup(true);
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Excel/Saving/SavingTests.cs b/ClosedXML_Tests/Excel/Saving/SavingTests.cs
index ca2fd98..60a1d7a 100644
--- a/ClosedXML_Tests/Excel/Saving/SavingTests.cs
+++ b/ClosedXML_Tests/Excel/Saving/SavingTests.cs
@@ -34,6 +34,35 @@
}
[Test]
+ public void CanSaveFileMultipleTimesAfterDeletingWorksheet()
+ {
+ // https://github.com/ClosedXML/ClosedXML/issues/435
+
+
+ using (var ms = new MemoryStream())
+ {
+ using (XLWorkbook book1 = new XLWorkbook())
+ {
+ book1.AddWorksheet("sheet1");
+ book1.AddWorksheet("sheet2");
+
+ book1.SaveAs(ms);
+ }
+ ms.Position = 0;
+
+ using (XLWorkbook book2 = new XLWorkbook(ms))
+ {
+ var ws = book2.Worksheet(1);
+ Assert.AreEqual("sheet1", ws.Name);
+ ws.Delete();
+ book2.Save();
+ book2.Save();
+ }
+ }
+ }
+
+
+ [Test]
public void CanSaveAndValidateFileInAnotherCulture()
{
string[] cultures = new string[] { "it", "de-AT" };
diff --git a/ClosedXML_Tests/Excel/Styles/NumberFormatTests.cs b/ClosedXML_Tests/Excel/Styles/NumberFormatTests.cs
index 04d7a8b..87ab21a 100644
--- a/ClosedXML_Tests/Excel/Styles/NumberFormatTests.cs
+++ b/ClosedXML_Tests/Excel/Styles/NumberFormatTests.cs
@@ -2,7 +2,6 @@
using NUnit.Framework;
using System;
using System.Data;
-using System.Linq;
namespace ClosedXML_Tests.Excel
{
@@ -14,7 +13,6 @@
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("Sheet1");
- ws.Column(1).Style.NumberFormat.Format = "yy-MM-dd";
var table = new DataTable();
table.Columns.Add("Date", typeof(DateTime));
@@ -24,9 +22,13 @@
table.Rows.Add(new DateTime(2017, 1, 1).AddMonths(i));
}
+ ws.Column(1).Style.NumberFormat.Format = "yy-MM-dd";
ws.Cell("A1").InsertData(table);
-
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);
+ 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 1a3819b..adbe14b 100644
--- a/ClosedXML_Tests/Excel/Tables/TablesTests.cs
+++ b/ClosedXML_Tests/Excel/Tables/TablesTests.cs
@@ -1,4 +1,4 @@
-using ClosedXML.Attributes;
+using ClosedXML.Attributes;
using ClosedXML.Excel;
using NUnit.Framework;
using System;
@@ -42,100 +42,112 @@
dt.Columns.Add("col1", typeof(string));
dt.Columns.Add("col2", typeof(double));
- var wb = new XLWorkbook();
- wb.AddWorksheet(dt);
+ using (var wb = new XLWorkbook())
+ {
+ wb.AddWorksheet(dt);
- using (var ms = new MemoryStream())
- wb.SaveAs(ms, true);
+ using (var ms = new MemoryStream())
+ wb.SaveAs(ms, true);
+ }
}
[Test]
public void CanSaveTableCreatedFromSingleRow()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().SetValue("Title");
- ws.Range("A1").CreateTable();
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().SetValue("Title");
+ ws.Range("A1").CreateTable();
- using (var ms = new MemoryStream())
- wb.SaveAs(ms, true);
+ using (var ms = new MemoryStream())
+ wb.SaveAs(ms, true);
+ }
}
[Test]
public void CreatingATableFromHeadersPushCellsBelow()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().SetValue("Title")
- .CellBelow().SetValue("X");
- ws.Range("A1").CreateTable();
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().SetValue("Title")
+ .CellBelow().SetValue("X");
+ ws.Range("A1").CreateTable();
- Assert.AreEqual(ws.Cell("A2").GetString(), String.Empty);
- Assert.AreEqual(ws.Cell("A3").GetString(), "X");
+ Assert.AreEqual(ws.Cell("A2").GetString(), String.Empty);
+ Assert.AreEqual(ws.Cell("A3").GetString(), "X");
+ }
}
[Test]
public void Inserting_Column_Sets_Header()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().SetValue("Categories")
- .CellBelow().SetValue("A")
- .CellBelow().SetValue("B")
- .CellBelow().SetValue("C");
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().SetValue("Categories")
+ .CellBelow().SetValue("A")
+ .CellBelow().SetValue("B")
+ .CellBelow().SetValue("C");
- IXLTable table = ws.RangeUsed().CreateTable();
- table.InsertColumnsAfter(1);
- Assert.AreEqual("Column2", table.HeadersRow().LastCell().GetString());
+ IXLTable table = ws.RangeUsed().CreateTable();
+ table.InsertColumnsAfter(1);
+ Assert.AreEqual("Column2", table.HeadersRow().LastCell().GetString());
+ }
}
[Test]
public void SavingLoadingTableWithNewLineInHeader()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- string columnName = "Line1" + Environment.NewLine + "Line2";
- ws.FirstCell().SetValue(columnName)
- .CellBelow().SetValue("A");
- ws.RangeUsed().CreateTable();
- using (var ms = new MemoryStream())
+ using (var wb = new XLWorkbook())
{
- wb.SaveAs(ms, true);
- var wb2 = new XLWorkbook(ms);
- IXLWorksheet ws2 = wb2.Worksheet(1);
- IXLTable table2 = ws2.Table(0);
- string fieldName = table2.Field(0).Name;
- Assert.AreEqual("Line1\nLine2", fieldName);
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ string columnName = "Line1" + Environment.NewLine + "Line2";
+ ws.FirstCell().SetValue(columnName)
+ .CellBelow().SetValue("A");
+ ws.RangeUsed().CreateTable();
+ using (var ms = new MemoryStream())
+ {
+ wb.SaveAs(ms, true);
+ var wb2 = new XLWorkbook(ms);
+ IXLWorksheet ws2 = wb2.Worksheet(1);
+ IXLTable table2 = ws2.Table(0);
+ string fieldName = table2.Field(0).Name;
+ Assert.AreEqual("Line1\nLine2", fieldName);
+ }
}
}
[Test]
public void SavingLoadingTableWithNewLineInHeader2()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.Worksheets.Add("Test");
-
- var dt = new DataTable();
- string columnName = "Line1" + Environment.NewLine + "Line2";
- dt.Columns.Add(columnName);
-
- DataRow dr = dt.NewRow();
- dr[columnName] = "some text";
- dt.Rows.Add(dr);
- ws.Cell(1, 1).InsertTable(dt);
-
- IXLTable table1 = ws.Table(0);
- string fieldName1 = table1.Field(0).Name;
- Assert.AreEqual(columnName, fieldName1);
-
- using (var ms = new MemoryStream())
+ using (var wb = new XLWorkbook())
{
- wb.SaveAs(ms, true);
- var wb2 = new XLWorkbook(ms);
- IXLWorksheet ws2 = wb2.Worksheet(1);
- IXLTable table2 = ws2.Table(0);
- string fieldName2 = table2.Field(0).Name;
- Assert.AreEqual("Line1\nLine2", fieldName2);
+ IXLWorksheet ws = wb.Worksheets.Add("Test");
+
+ var dt = new DataTable();
+ string columnName = "Line1" + Environment.NewLine + "Line2";
+ dt.Columns.Add(columnName);
+
+ DataRow dr = dt.NewRow();
+ dr[columnName] = "some text";
+ dt.Rows.Add(dr);
+ ws.Cell(1, 1).InsertTable(dt);
+
+ IXLTable table1 = ws.Table(0);
+ string fieldName1 = table1.Field(0).Name;
+ Assert.AreEqual(columnName, fieldName1);
+
+ using (var ms = new MemoryStream())
+ {
+ wb.SaveAs(ms, true);
+ var wb2 = new XLWorkbook(ms);
+ IXLWorksheet ws2 = wb2.Worksheet(1);
+ IXLTable table2 = ws2.Table(0);
+ string fieldName2 = table2.Field(0).Name;
+ Assert.AreEqual("Line1\nLine2", fieldName2);
+ }
}
}
@@ -146,10 +158,12 @@
dt.Columns.Add("col1", typeof(string));
dt.Columns.Add("col2", typeof(double));
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().InsertTable(dt);
- Assert.AreEqual(2, ws.Tables.First().ColumnCount());
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().InsertTable(dt);
+ Assert.AreEqual(2, ws.Tables.First().ColumnCount());
+ }
}
[Test]
@@ -157,10 +171,12 @@
{
var l = new List();
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().InsertTable(l);
- Assert.AreEqual(1, ws.Tables.First().ColumnCount());
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().InsertTable(l);
+ Assert.AreEqual(1, ws.Tables.First().ColumnCount());
+ }
}
[Test]
@@ -168,10 +184,12 @@
{
var l = new List();
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().InsertTable(l);
- Assert.AreEqual(2, ws.Tables.First().ColumnCount());
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().InsertTable(l);
+ Assert.AreEqual(2, ws.Tables.First().ColumnCount());
+ }
}
[Test]
@@ -183,184 +201,384 @@
new TestObjectWithAttributes() { Column1 = "c", Column2 = "d", MyField = 5, UnOrderedColumn = 777 }
};
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().InsertTable(l);
- Assert.AreEqual(4, ws.Tables.First().ColumnCount());
- Assert.AreEqual("FirstColumn", ws.FirstCell().Value);
- Assert.AreEqual("SecondColumn", ws.FirstCell().CellRight().Value);
- Assert.AreEqual("SomeFieldNotProperty", ws.FirstCell().CellRight().CellRight().Value);
- Assert.AreEqual("UnOrderedColumn", ws.FirstCell().CellRight().CellRight().CellRight().Value);
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().InsertTable(l);
+ Assert.AreEqual(4, ws.Tables.First().ColumnCount());
+ Assert.AreEqual("FirstColumn", ws.FirstCell().Value);
+ Assert.AreEqual("SecondColumn", ws.FirstCell().CellRight().Value);
+ Assert.AreEqual("SomeFieldNotProperty", ws.FirstCell().CellRight().CellRight().Value);
+ Assert.AreEqual("UnOrderedColumn", ws.FirstCell().CellRight().CellRight().CellRight().Value);
+ }
}
[Test]
public void TableInsertAboveFromData()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().SetValue("Value");
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().SetValue("Value");
- IXLTable table = ws.Range("A1:A2").CreateTable();
- table.SetShowTotalsRow()
- .Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
+ IXLTable table = ws.Range("A1:A2").CreateTable();
+ table.SetShowTotalsRow()
+ .Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
- IXLTableRow row = table.DataRange.FirstRow();
- row.Field("Value").Value = 3;
- row = table.DataRange.InsertRowsAbove(1).First();
- row.Field("Value").Value = 2;
- row = table.DataRange.InsertRowsAbove(1).First();
- row.Field("Value").Value = 1;
+ IXLTableRow row = table.DataRange.FirstRow();
+ row.Field("Value").Value = 3;
+ row = table.DataRange.InsertRowsAbove(1).First();
+ row.Field("Value").Value = 2;
+ row = table.DataRange.InsertRowsAbove(1).First();
+ row.Field("Value").Value = 1;
- Assert.AreEqual(1, ws.Cell(2, 1).GetDouble());
- Assert.AreEqual(2, ws.Cell(3, 1).GetDouble());
- Assert.AreEqual(3, ws.Cell(4, 1).GetDouble());
+ Assert.AreEqual(1, ws.Cell(2, 1).GetDouble());
+ Assert.AreEqual(2, ws.Cell(3, 1).GetDouble());
+ Assert.AreEqual(3, ws.Cell(4, 1).GetDouble());
+ }
}
[Test]
public void TableInsertAboveFromRows()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().SetValue("Value");
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().SetValue("Value");
- IXLTable table = ws.Range("A1:A2").CreateTable();
- table.SetShowTotalsRow()
- .Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
+ IXLTable table = ws.Range("A1:A2").CreateTable();
+ table.SetShowTotalsRow()
+ .Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
- IXLTableRow row = table.DataRange.FirstRow();
- row.Field("Value").Value = 3;
- row = row.InsertRowsAbove(1).First();
- row.Field("Value").Value = 2;
- row = row.InsertRowsAbove(1).First();
- row.Field("Value").Value = 1;
+ IXLTableRow row = table.DataRange.FirstRow();
+ row.Field("Value").Value = 3;
+ row = row.InsertRowsAbove(1).First();
+ row.Field("Value").Value = 2;
+ row = row.InsertRowsAbove(1).First();
+ row.Field("Value").Value = 1;
- Assert.AreEqual(1, ws.Cell(2, 1).GetDouble());
- Assert.AreEqual(2, ws.Cell(3, 1).GetDouble());
- Assert.AreEqual(3, ws.Cell(4, 1).GetDouble());
+ Assert.AreEqual(1, ws.Cell(2, 1).GetDouble());
+ Assert.AreEqual(2, ws.Cell(3, 1).GetDouble());
+ Assert.AreEqual(3, ws.Cell(4, 1).GetDouble());
+ }
}
[Test]
public void TableInsertBelowFromData()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().SetValue("Value");
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().SetValue("Value");
- IXLTable table = ws.Range("A1:A2").CreateTable();
- table.SetShowTotalsRow()
- .Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
+ IXLTable table = ws.Range("A1:A2").CreateTable();
+ table.SetShowTotalsRow()
+ .Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
- IXLTableRow row = table.DataRange.FirstRow();
- row.Field("Value").Value = 1;
- row = table.DataRange.InsertRowsBelow(1).First();
- row.Field("Value").Value = 2;
- row = table.DataRange.InsertRowsBelow(1).First();
- row.Field("Value").Value = 3;
+ IXLTableRow row = table.DataRange.FirstRow();
+ row.Field("Value").Value = 1;
+ row = table.DataRange.InsertRowsBelow(1).First();
+ row.Field("Value").Value = 2;
+ row = table.DataRange.InsertRowsBelow(1).First();
+ row.Field("Value").Value = 3;
- Assert.AreEqual(1, ws.Cell(2, 1).GetDouble());
- Assert.AreEqual(2, ws.Cell(3, 1).GetDouble());
- Assert.AreEqual(3, ws.Cell(4, 1).GetDouble());
+ Assert.AreEqual(1, ws.Cell(2, 1).GetDouble());
+ Assert.AreEqual(2, ws.Cell(3, 1).GetDouble());
+ Assert.AreEqual(3, ws.Cell(4, 1).GetDouble());
+ }
}
[Test]
public void TableInsertBelowFromRows()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().SetValue("Value");
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().SetValue("Value");
- IXLTable table = ws.Range("A1:A2").CreateTable();
- table.SetShowTotalsRow()
- .Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
+ IXLTable table = ws.Range("A1:A2").CreateTable();
+ table.SetShowTotalsRow()
+ .Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
- IXLTableRow row = table.DataRange.FirstRow();
- row.Field("Value").Value = 1;
- row = row.InsertRowsBelow(1).First();
- row.Field("Value").Value = 2;
- row = row.InsertRowsBelow(1).First();
- row.Field("Value").Value = 3;
+ IXLTableRow row = table.DataRange.FirstRow();
+ row.Field("Value").Value = 1;
+ row = row.InsertRowsBelow(1).First();
+ row.Field("Value").Value = 2;
+ row = row.InsertRowsBelow(1).First();
+ row.Field("Value").Value = 3;
- Assert.AreEqual(1, ws.Cell(2, 1).GetDouble());
- Assert.AreEqual(2, ws.Cell(3, 1).GetDouble());
- Assert.AreEqual(3, ws.Cell(4, 1).GetDouble());
+ Assert.AreEqual(1, ws.Cell(2, 1).GetDouble());
+ Assert.AreEqual(2, ws.Cell(3, 1).GetDouble());
+ Assert.AreEqual(3, ws.Cell(4, 1).GetDouble());
+ }
}
[Test]
public void TableShowHeader()
{
- var wb = new XLWorkbook();
- IXLWorksheet ws = wb.AddWorksheet("Sheet1");
- ws.FirstCell().SetValue("Categories")
- .CellBelow().SetValue("A")
- .CellBelow().SetValue("B")
- .CellBelow().SetValue("C");
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().SetValue("Categories")
+ .CellBelow().SetValue("A")
+ .CellBelow().SetValue("B")
+ .CellBelow().SetValue("C");
- IXLTable table = ws.RangeUsed().CreateTable();
+ IXLTable table = ws.RangeUsed().CreateTable();
- Assert.AreEqual("Categories", table.Fields.First().Name);
+ Assert.AreEqual("Categories", table.Fields.First().Name);
- table.SetShowHeaderRow(false);
+ table.SetShowHeaderRow(false);
- Assert.AreEqual("Categories", table.Fields.First().Name);
+ Assert.AreEqual("Categories", table.Fields.First().Name);
- Assert.IsTrue(ws.Cell(1, 1).IsEmpty(true));
- Assert.AreEqual(null, table.HeadersRow());
- Assert.AreEqual("A", table.DataRange.FirstRow().Field("Categories").GetString());
- Assert.AreEqual("C", table.DataRange.LastRow().Field("Categories").GetString());
- Assert.AreEqual("A", table.DataRange.FirstCell().GetString());
- Assert.AreEqual("C", table.DataRange.LastCell().GetString());
+ Assert.IsTrue(ws.Cell(1, 1).IsEmpty(true));
+ Assert.AreEqual(null, table.HeadersRow());
+ Assert.AreEqual("A", table.DataRange.FirstRow().Field("Categories").GetString());
+ Assert.AreEqual("C", table.DataRange.LastRow().Field("Categories").GetString());
+ Assert.AreEqual("A", table.DataRange.FirstCell().GetString());
+ Assert.AreEqual("C", table.DataRange.LastCell().GetString());
- table.SetShowHeaderRow();
- IXLRangeRow headerRow = table.HeadersRow();
- Assert.AreNotEqual(null, headerRow);
- Assert.AreEqual("Categories", headerRow.Cell(1).GetString());
+ table.SetShowHeaderRow();
+ IXLRangeRow headerRow = table.HeadersRow();
+ Assert.AreNotEqual(null, headerRow);
+ Assert.AreEqual("Categories", headerRow.Cell(1).GetString());
- table.SetShowHeaderRow(false);
+ table.SetShowHeaderRow(false);
- ws.FirstCell().SetValue("x");
+ ws.FirstCell().SetValue("x");
- table.SetShowHeaderRow();
+ table.SetShowHeaderRow();
- Assert.AreEqual("x", ws.FirstCell().GetString());
- Assert.AreEqual("Categories", ws.Cell("A2").GetString());
- Assert.AreNotEqual(null, headerRow);
- Assert.AreEqual("A", table.DataRange.FirstRow().Field("Categories").GetString());
- Assert.AreEqual("C", table.DataRange.LastRow().Field("Categories").GetString());
- Assert.AreEqual("A", table.DataRange.FirstCell().GetString());
- Assert.AreEqual("C", table.DataRange.LastCell().GetString());
+ Assert.AreEqual("x", ws.FirstCell().GetString());
+ Assert.AreEqual("Categories", ws.Cell("A2").GetString());
+ Assert.AreNotEqual(null, headerRow);
+ Assert.AreEqual("A", table.DataRange.FirstRow().Field("Categories").GetString());
+ Assert.AreEqual("C", table.DataRange.LastRow().Field("Categories").GetString());
+ Assert.AreEqual("A", table.DataRange.FirstCell().GetString());
+ Assert.AreEqual("C", table.DataRange.LastCell().GetString());
+ }
}
[Test]
public void ChangeFieldName()
{
- XLWorkbook wb = new XLWorkbook();
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet");
+ ws.Cell("A1").SetValue("FName")
+ .CellBelow().SetValue("John");
- var ws = wb.AddWorksheet("Sheet");
- ws.Cell("A1").SetValue("FName")
- .CellBelow().SetValue("John");
+ ws.Cell("B1").SetValue("LName")
+ .CellBelow().SetValue("Doe");
- ws.Cell("B1").SetValue("LName")
- .CellBelow().SetValue("Doe");
+ var tbl = ws.RangeUsed().CreateTable();
+ var nameBefore = tbl.Field(tbl.Fields.Last().Index).Name;
+ tbl.Field(tbl.Fields.Last().Index).Name = "LastName";
+ var nameAfter = tbl.Field(tbl.Fields.Last().Index).Name;
- var tbl = ws.RangeUsed().CreateTable();
- var nameBefore = tbl.Field(tbl.Fields.Last().Index).Name;
- tbl.Field(tbl.Fields.Last().Index).Name = "LastName";
- var nameAfter = tbl.Field(tbl.Fields.Last().Index).Name;
+ var cellValue = ws.Cell("B1").GetString();
- var cellValue = ws.Cell("B1").GetString();
+ Assert.AreEqual("LName", nameBefore);
+ Assert.AreEqual("LastName", nameAfter);
+ Assert.AreEqual("LastName", cellValue);
- Assert.AreEqual("LName", nameBefore);
- Assert.AreEqual("LastName", nameAfter);
- Assert.AreEqual("LastName", cellValue);
+ tbl.ShowHeaderRow = false;
+ tbl.Field(tbl.Fields.Last().Index).Name = "LastNameChanged";
+ nameAfter = tbl.Field(tbl.Fields.Last().Index).Name;
+ Assert.AreEqual("LastNameChanged", nameAfter);
- tbl.ShowHeaderRow = false;
- tbl.Field(tbl.Fields.Last().Index).Name = "LastNameChanged";
- nameAfter = tbl.Field(tbl.Fields.Last().Index).Name;
- Assert.AreEqual("LastNameChanged", nameAfter);
+ tbl.SetShowHeaderRow(true);
+ nameAfter = tbl.Cell("B1").Value.ToString();
+ Assert.AreEqual("LastNameChanged", nameAfter);
- tbl.SetShowHeaderRow(true);
- nameAfter = tbl.Cell("B1").Value.ToString();
- Assert.AreEqual("LastNameChanged", nameAfter);
+ var field = tbl.Field("LastNameChanged");
+ Assert.AreEqual("LastNameChanged", field.Name);
+
+ tbl.Cell(1, 1).Value = "FirstName";
+ Assert.AreEqual("FirstName", tbl.Field(0).Name);
+ }
}
+
+ [Test]
+ public void CanDeleteTableColumn()
+ {
+ 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");
+ var table = ws.FirstCell().InsertTable(l);
+
+ table.Column("C").Delete();
+
+ Assert.AreEqual(3, table.Fields.Count());
+
+ Assert.AreEqual("FirstColumn", table.Fields.First().Name);
+ Assert.AreEqual(0, table.Fields.First().Index);
+
+ Assert.AreEqual("UnOrderedColumn", table.Fields.Last().Name);
+ Assert.AreEqual(2, table.Fields.Last().Index);
+ }
+ }
+
+ [Test]
+ public void CanDeleteTableField()
+ {
+ 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");
+ var table = ws.FirstCell().InsertTable(l);
+
+ table.Field("SomeFieldNotProperty").Delete();
+
+ Assert.AreEqual(3, table.Fields.Count());
+
+ Assert.AreEqual("FirstColumn", table.Fields.First().Name);
+ Assert.AreEqual(0, table.Fields.First().Index);
+
+ Assert.AreEqual("UnOrderedColumn", table.Fields.Last().Name);
+ Assert.AreEqual(2, table.Fields.Last().Index);
+ }
+ }
+
+ [Test]
+ public void OverlappingTablesThrowsException()
+ {
+ var dt = new DataTable("sheet1");
+ dt.Columns.Add("col1", typeof(string));
+ dt.Columns.Add("col2", typeof(double));
+
+ using (var wb = new XLWorkbook())
+ {
+ IXLWorksheet ws = wb.AddWorksheet("Sheet1");
+ ws.FirstCell().InsertTable(dt, true);
+ Assert.Throws(() => ws.FirstCell().CellRight().InsertTable(dt, true));
+ }
+ }
+
+ [Test]
+ public void OverwritingTableTotalsRow()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet1");
+
+ var data1 = Enumerable.Range(1, 10)
+ .Select(i =>
+ new
+ {
+ Index = i,
+ Character = Convert.ToChar(64 + i),
+ String = new String('a', i)
+ });
+
+ var table = ws.FirstCell().InsertTable(data1, true)
+ .SetShowHeaderRow()
+ .SetShowTotalsRow();
+ table.Fields.First().TotalsRowFunction = XLTotalsRowFunction.Sum;
+
+ var data2 = Enumerable.Range(1, 20)
+ .Select(i =>
+ new
+ {
+ Index = i,
+ Character = Convert.ToChar(64 + i),
+ String = new String('b', i),
+ Int = 64 + i
+ });
+
+ ws.FirstCell().CellBelow().InsertData(data2);
+
+ table.Fields.ForEach(f => Assert.AreEqual(XLTotalsRowFunction.None, f.TotalsRowFunction));
+
+ Assert.AreEqual("11", table.Field(0).TotalsRowLabel);
+ Assert.AreEqual("K", table.Field(1).TotalsRowLabel);
+ Assert.AreEqual("bbbbbbbbbbb", table.Field(2).TotalsRowLabel);
+ }
+ }
+
+ [Test]
+ public void CanResizeTable()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet1");
+
+ var data1 = Enumerable.Range(1, 10)
+ .Select(i =>
+ new
+ {
+ Index = i,
+ Character = Convert.ToChar(64 + i),
+ String = new String('a', i)
+ });
+
+ var table = ws.FirstCell().InsertTable(data1, true)
+ .SetShowHeaderRow()
+ .SetShowTotalsRow();
+ table.Fields.First().TotalsRowFunction = XLTotalsRowFunction.Sum;
+
+ var data2 = Enumerable.Range(1, 10)
+ .Select(i =>
+ new
+ {
+ Index = i,
+ Character = Convert.ToChar(64 + i),
+ String = new String('b', i),
+ Integer = 64 + i
+ });
+
+ ws.FirstCell().CellBelow().InsertData(data2);
+ table.Resize(table.FirstCell().Address, table.AsRange().LastCell().CellRight().Address);
+
+ Assert.AreEqual(4, table.Fields.Count());
+
+ Assert.AreEqual("Column4", table.Field(3).Name);
+
+ ws.Cell("D1").Value = "Integer";
+ Assert.AreEqual("Integer", table.Field(3).Name);
+ }
+ }
+
+ [Test]
+ public void TestTableCellTypes()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet1");
+
+ var data1 = Enumerable.Range(1, 10)
+ .Select(i =>
+ new
+ {
+ Index = i,
+ Character = Convert.ToChar(64 + i),
+ String = new String('a', i)
+ });
+
+ var table = ws.FirstCell().InsertTable(data1, true)
+ .SetShowHeaderRow()
+ .SetShowTotalsRow();
+ table.Fields.First().TotalsRowFunction = XLTotalsRowFunction.Sum;
+
+ Assert.AreEqual(XLTableCellType.Header, table.HeadersRow().Cell(1).TableCellType());
+ Assert.AreEqual(XLTableCellType.Data, table.HeadersRow().Cell(1).CellBelow().TableCellType());
+ Assert.AreEqual(XLTableCellType.Total, table.TotalsRow().Cell(1).TableCellType());
+ Assert.AreEqual(XLTableCellType.None, ws.Cell("Z100").TableCellType());
+ }
+ }
+
+ //TODO: Delete table (not underlying range)
}
}
diff --git a/ClosedXML_Tests/Excel/Worksheets/XLWorksheetTests.cs b/ClosedXML_Tests/Excel/Worksheets/XLWorksheetTests.cs
index f679187..76f612e 100644
--- a/ClosedXML_Tests/Excel/Worksheets/XLWorksheetTests.cs
+++ b/ClosedXML_Tests/Excel/Worksheets/XLWorksheetTests.cs
@@ -1,6 +1,7 @@
using ClosedXML.Excel;
using NUnit.Framework;
using System;
+using System.IO;
using System.Linq;
namespace ClosedXML_Tests
@@ -140,5 +141,57 @@
Assert.AreEqual(6, value);
}
}
+
+ [Test]
+ public void CanRenameWorksheet()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws1 = wb.AddWorksheet("Sheet1");
+ var ws2 = wb.AddWorksheet("Sheet2");
+
+ ws1.Name = "New sheet name";
+ Assert.AreEqual("New sheet name", ws1.Name);
+
+ ws2.Name = "sheet2";
+ Assert.AreEqual("sheet2", ws2.Name);
+
+ Assert.Throws(() => ws1.Name = "SHEET2");
+ }
+ }
+
+ [Test]
+ public void HideWorksheet()
+ {
+ using (var ms = new MemoryStream())
+ {
+ using (var wb = new XLWorkbook())
+ {
+ wb.Worksheets.Add("VisibleSheet");
+ wb.Worksheets.Add("HiddenSheet").Hide();
+ wb.SaveAs(ms);
+ }
+
+ // unhide the hidden sheet
+ using (var wb = new XLWorkbook(ms))
+ {
+ Assert.AreEqual(XLWorksheetVisibility.Visible, wb.Worksheet("VisibleSheet").Visibility);
+ Assert.AreEqual(XLWorksheetVisibility.Hidden, wb.Worksheet("HiddenSheet").Visibility);
+
+ var ws = wb.Worksheet("HiddenSheet");
+ ws.Unhide().Name = "NoAlsoVisible";
+
+ Assert.AreEqual(XLWorksheetVisibility.Visible, ws.Visibility);
+
+ wb.Save();
+ }
+
+ using (var wb = new XLWorkbook(ms))
+ {
+ Assert.AreEqual(XLWorksheetVisibility.Visible, wb.Worksheet("VisibleSheet").Visibility);
+ Assert.AreEqual(XLWorksheetVisibility.Visible, wb.Worksheet("NoAlsoVisible").Visibility);
+ }
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/OleDb/OleDbTests.cs b/ClosedXML_Tests/OleDb/OleDbTests.cs
index e502614..2aa897c 100644
--- a/ClosedXML_Tests/OleDb/OleDbTests.cs
+++ b/ClosedXML_Tests/OleDb/OleDbTests.cs
@@ -1,4 +1,5 @@
using ClosedXML.Excel;
+using ClosedXML_Tests.Utils;
using NUnit.Framework;
using System;
using System.Collections.Generic;
@@ -16,7 +17,7 @@
[Test]
public void TestOleDbValues()
{
- using (var tf = new TestFile(CreateTestFile()))
+ using (var tf = new TemporaryFile(CreateTestFile()))
{
Console.Write("Using temporary file\t{0}", tf.Path);
var connectionString = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1';", tf.Path);
@@ -115,32 +116,5 @@
return path;
}
}
-
- internal class TestFile : IDisposable
- {
- internal TestFile(string path)
- : this(path, false)
- { }
-
- internal TestFile(string path, bool preserve)
- {
- this.Path = path;
- this.Preserve = preserve;
- }
-
- public string Path { get; private set; }
- public bool Preserve { get; private set; }
-
- public void Dispose()
- {
- if (!Preserve)
- File.Delete(Path);
- }
-
- public override string ToString()
- {
- return this.Path;
- }
- }
}
}
diff --git a/ClosedXML_Tests/Resource/Examples/Columns/DeletingColumns.xlsx b/ClosedXML_Tests/Resource/Examples/Columns/DeletingColumns.xlsx
index bac6e30..e2ac29f 100644
--- a/ClosedXML_Tests/Resource/Examples/Columns/DeletingColumns.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Columns/DeletingColumns.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Comments/AddingComments.xlsx b/ClosedXML_Tests/Resource/Examples/Comments/AddingComments.xlsx
index 3879998..5c9ae0a 100644
--- a/ClosedXML_Tests/Resource/Examples/Comments/AddingComments.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Comments/AddingComments.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/ConditionalFormatting/CFIsBlank.xlsx b/ClosedXML_Tests/Resource/Examples/ConditionalFormatting/CFIsBlank.xlsx
index 80be4ab..e57b38d 100644
--- a/ClosedXML_Tests/Resource/Examples/ConditionalFormatting/CFIsBlank.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/ConditionalFormatting/CFIsBlank.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/ConditionalFormatting/CFNotBlank.xlsx b/ClosedXML_Tests/Resource/Examples/ConditionalFormatting/CFNotBlank.xlsx
index 5f4f6ce..e233171 100644
--- a/ClosedXML_Tests/Resource/Examples/ConditionalFormatting/CFNotBlank.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/ConditionalFormatting/CFNotBlank.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/ImageHandling/ImageAnchors.xlsx b/ClosedXML_Tests/Resource/Examples/ImageHandling/ImageAnchors.xlsx
index 53aa802..d2a90ba 100644
--- a/ClosedXML_Tests/Resource/Examples/ImageHandling/ImageAnchors.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/ImageHandling/ImageAnchors.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/ImageHandling/ImageFormats.xlsx b/ClosedXML_Tests/Resource/Examples/ImageHandling/ImageFormats.xlsx
index 237d910..3ec78e0 100644
--- a/ClosedXML_Tests/Resource/Examples/ImageHandling/ImageFormats.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/ImageHandling/ImageFormats.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/BlankCells.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/BlankCells.xlsx
index 21ea101..3f4195a 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/BlankCells.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/BlankCells.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/CopyingWorksheets.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/CopyingWorksheets.xlsx
index 6d14038..28c4b9b 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/CopyingWorksheets.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/CopyingWorksheets.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/DataTypes.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/DataTypes.xlsx
index 87f74be..d7b9afd 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/DataTypes.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/DataTypes.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/DataTypesUnderDifferentCulture.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/DataTypesUnderDifferentCulture.xlsx
index 5d0b538..f451273 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/DataTypesUnderDifferentCulture.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/DataTypesUnderDifferentCulture.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/Formulas.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/Formulas.xlsx
index dea7693..c49d20a 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/Formulas.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/Formulas.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/FormulasWithEvaluation.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/FormulasWithEvaluation.xlsx
index 7a93ddb..f1dde09 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/FormulasWithEvaluation.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/FormulasWithEvaluation.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/HideUnhide.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/HideUnhide.xlsx
index a3c6ea5..1f99477 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/HideUnhide.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/HideUnhide.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/Hyperlinks.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/Hyperlinks.xlsx
index 222ba7b..d724e36 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/Hyperlinks.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/Hyperlinks.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/InsertingData.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/InsertingData.xlsx
index 9e9d20f..d9d1a57 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/InsertingData.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/InsertingData.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/InsertingTables.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/InsertingTables.xlsx
deleted file mode 100644
index 212cbfe..0000000
--- a/ClosedXML_Tests/Resource/Examples/Misc/InsertingTables.xlsx
+++ /dev/null
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/MergeMoves.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/MergeMoves.xlsx
index 9839a6f..2cbaac9 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/MergeMoves.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/MergeMoves.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/ShiftingFormulas.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/ShiftingFormulas.xlsx
index 81bc2a4..a1aa8d0 100644
--- a/ClosedXML_Tests/Resource/Examples/Misc/ShiftingFormulas.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Misc/ShiftingFormulas.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/PivotTables/PivotTables.xlsx b/ClosedXML_Tests/Resource/Examples/PivotTables/PivotTables.xlsx
index 6e3156d..369bb0c 100644
--- a/ClosedXML_Tests/Resource/Examples/PivotTables/PivotTables.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/PivotTables/PivotTables.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/ClearingRanges.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/ClearingRanges.xlsx
index c1c9431..5e18500 100644
--- a/ClosedXML_Tests/Resource/Examples/Ranges/ClearingRanges.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Ranges/ClearingRanges.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/InsertingDeletingRows.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/InsertingDeletingRows.xlsx
index 6cdd101..9588f7d 100644
--- a/ClosedXML_Tests/Resource/Examples/Ranges/InsertingDeletingRows.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Ranges/InsertingDeletingRows.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/NamedRanges.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/NamedRanges.xlsx
index 8d4e6a2..2b450d6 100644
--- a/ClosedXML_Tests/Resource/Examples/Ranges/NamedRanges.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Ranges/NamedRanges.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/SelectingRanges.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/SelectingRanges.xlsx
index a33e2a6..adecfee 100644
--- a/ClosedXML_Tests/Resource/Examples/Ranges/SelectingRanges.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Ranges/SelectingRanges.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/ShiftingRanges.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/ShiftingRanges.xlsx
index 3f1bafd..453328f 100644
--- a/ClosedXML_Tests/Resource/Examples/Ranges/ShiftingRanges.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Ranges/ShiftingRanges.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/SortExample.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/SortExample.xlsx
index 8b26d86..bd2c3d6 100644
--- a/ClosedXML_Tests/Resource/Examples/Ranges/SortExample.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Ranges/SortExample.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/TransposeRangesPlus.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/TransposeRangesPlus.xlsx
index 44fbbbe..037fc86 100644
--- a/ClosedXML_Tests/Resource/Examples/Ranges/TransposeRangesPlus.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Ranges/TransposeRangesPlus.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/UsingTables.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/UsingTables.xlsx
deleted file mode 100644
index 288d1fe..0000000
--- a/ClosedXML_Tests/Resource/Examples/Ranges/UsingTables.xlsx
+++ /dev/null
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Ranges/WalkingRanges.xlsx b/ClosedXML_Tests/Resource/Examples/Ranges/WalkingRanges.xlsx
index 4a705f7..e12dfc5 100644
--- a/ClosedXML_Tests/Resource/Examples/Ranges/WalkingRanges.xlsx
+++ b/ClosedXML_Tests/Resource/Examples/Ranges/WalkingRanges.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Styles/UsingPhonetics.xlsx b/ClosedXML_Tests/Resource/Examples/Styles/UsingPhonetics.xlsx
new file mode 100644
index 0000000..86fe3e6
--- /dev/null
+++ b/ClosedXML_Tests/Resource/Examples/Styles/UsingPhonetics.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Tables/InsertingTables.xlsx b/ClosedXML_Tests/Resource/Examples/Tables/InsertingTables.xlsx
new file mode 100644
index 0000000..89de679
--- /dev/null
+++ b/ClosedXML_Tests/Resource/Examples/Tables/InsertingTables.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Tables/ResizingTables.xlsx b/ClosedXML_Tests/Resource/Examples/Tables/ResizingTables.xlsx
new file mode 100644
index 0000000..dad3954
--- /dev/null
+++ b/ClosedXML_Tests/Resource/Examples/Tables/ResizingTables.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Examples/Tables/UsingTables.xlsx b/ClosedXML_Tests/Resource/Examples/Tables/UsingTables.xlsx
new file mode 100644
index 0000000..288d1fe
--- /dev/null
+++ b/ClosedXML_Tests/Resource/Examples/Tables/UsingTables.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Misc/DuplicateImageNames.xlsx b/ClosedXML_Tests/Resource/Misc/DuplicateImageNames.xlsx
new file mode 100644
index 0000000..29df50b
--- /dev/null
+++ b/ClosedXML_Tests/Resource/Misc/DuplicateImageNames.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Misc/TableHeadersWithLineBreaks.xlsx b/ClosedXML_Tests/Resource/Misc/TableHeadersWithLineBreaks.xlsx
new file mode 100644
index 0000000..8e7dbdc
--- /dev/null
+++ b/ClosedXML_Tests/Resource/Misc/TableHeadersWithLineBreaks.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Resource/Misc/TableWithNameNull.xlsx b/ClosedXML_Tests/Resource/Misc/TableWithNameNull.xlsx
new file mode 100644
index 0000000..0a5a8de
--- /dev/null
+++ b/ClosedXML_Tests/Resource/Misc/TableWithNameNull.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/Utils/TemporaryFile.cs b/ClosedXML_Tests/Utils/TemporaryFile.cs
new file mode 100644
index 0000000..6d95b1f
--- /dev/null
+++ b/ClosedXML_Tests/Utils/TemporaryFile.cs
@@ -0,0 +1,37 @@
+using System;
+using System.IO;
+
+namespace ClosedXML_Tests.Utils
+{
+ internal class TemporaryFile : IDisposable
+ {
+ internal TemporaryFile()
+ : this(System.IO.Path.ChangeExtension(System.IO.Path.GetTempFileName(), "xlsx"))
+ { }
+
+ internal TemporaryFile(string path)
+ : this(path, false)
+ { }
+
+ internal TemporaryFile(String path, bool preserve)
+ {
+ this.Path = path;
+ this.Preserve = preserve;
+ }
+
+
+ public string Path { get; private set; }
+ public bool Preserve { get; private set; }
+
+ public void Dispose()
+ {
+ if (!Preserve)
+ File.Delete(Path);
+ }
+
+ public override string ToString()
+ {
+ return this.Path;
+ }
+ }
+}
diff --git a/ClosedXML_Tests/packages.config b/ClosedXML_Tests/packages.config
index c32aa84..5e0ab7c 100644
--- a/ClosedXML_Tests/packages.config
+++ b/ClosedXML_Tests/packages.config
@@ -1,5 +1,5 @@
-
-
-
-
+
+
+
+
\ No newline at end of file