Initial commit of the ClosedXML library

Establishes the foundational structure, core Excel functionality, and tooling.

- Implements base components for cells, ranges, columns, and rows.
- Integrates a custom calculation engine with a wide range of Excel functions.
- Adds comprehensive support for styling, conditional formatting, data validation, comments, pictures, and charts.
- Configures build setup, project metadata (NuGet), and developer guidelines.
- Includes editor and Git attributes for consistent code style and line endings.
This commit is contained in:
Thom Lamb
2026-06-23 11:02:53 -05:00
parent 28bc05cf54
commit 2cd6df6481
1092 changed files with 97270 additions and 408 deletions
@@ -0,0 +1,134 @@
using ClosedXML.Excel;
using NUnit.Framework;
using System.Linq;
namespace ClosedXML_Tests.Excel.Misc
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestFixture]
public class CopyContentsTests
{
private static void CopyRowAsRange(IXLWorksheet originalSheet, int originalRowNumber, IXLWorksheet destSheet,
int destRowNumber)
{
{
IXLRow destinationRow = destSheet.Row(destRowNumber);
destinationRow.Clear();
IXLRow originalRow = originalSheet.Row(originalRowNumber);
int columnNumber = originalRow.LastCellUsed(XLCellsUsedOptions.All).Address.ColumnNumber;
IXLRange originalRange = originalSheet.Range(originalRowNumber, 1, originalRowNumber, columnNumber);
IXLRange destRange = destSheet.Range(destRowNumber, 1, destRowNumber, columnNumber);
originalRange.CopyTo(destRange);
}
}
[Test]
public void CopyConditionalFormatsCount()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().AddConditionalFormat().WhenContains("1").Fill.SetBackgroundColor(XLColor.Blue);
ws.Cell("A2").Value = ws.FirstCell();
Assert.AreEqual(2, ws.ConditionalFormats.Count());
}
[Test]
public void CopyConditionalFormatsFixedNum()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.Cell("A1").Value = "1";
ws.Cell("B1").Value = "1";
ws.Cell("A1").AddConditionalFormat().WhenEquals(1).Fill.SetBackgroundColor(XLColor.Blue);
ws.Cell("A2").Value = ws.Cell("A1");
Assert.IsTrue(ws.ConditionalFormats.Any(cf => cf.Values.Any(v => v.Value.Value == "1" && !v.Value.IsFormula)));
Assert.IsTrue(ws.ConditionalFormats.Any(cf => cf.Values.Any(v => v.Value.Value == "1" && !v.Value.IsFormula)));
}
[Test]
public void CopyConditionalFormatsFixedString()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.Cell("A1").Value = "A";
ws.Cell("B1").Value = "B";
ws.Cell("A1").AddConditionalFormat().WhenEquals("A").Fill.SetBackgroundColor(XLColor.Blue);
ws.Cell("A2").Value = ws.Cell("A1");
Assert.IsTrue(ws.ConditionalFormats.Any(cf => cf.Values.Any(v => v.Value.Value == "A" && !v.Value.IsFormula)));
Assert.IsTrue(ws.ConditionalFormats.Any(cf => cf.Values.Any(v => v.Value.Value == "A" && !v.Value.IsFormula)));
}
[Test]
public void CopyConditionalFormatsFixedStringNum()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.Cell("A1").Value = "1";
ws.Cell("B1").Value = "1";
ws.Cell("A1").AddConditionalFormat().WhenEquals("1").Fill.SetBackgroundColor(XLColor.Blue);
ws.Cell("A2").Value = ws.Cell("A1");
Assert.IsTrue(ws.ConditionalFormats.Any(cf => cf.Values.Any(v => v.Value.Value == "1" && !v.Value.IsFormula)));
Assert.IsTrue(ws.ConditionalFormats.Any(cf => cf.Values.Any(v => v.Value.Value == "1" && !v.Value.IsFormula)));
}
[Test]
public void CopyConditionalFormatsRelative()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.Cell("A1").Value = "1";
ws.Cell("B1").Value = "1";
ws.Cell("A1").AddConditionalFormat().WhenEquals("=B1").Fill.SetBackgroundColor(XLColor.Blue);
ws.Cell("A2").Value = ws.Cell("A1");
Assert.IsTrue(ws.ConditionalFormats.Any(cf => cf.Values.Any(v => v.Value.Value == "B1" && v.Value.IsFormula)));
Assert.IsTrue(ws.ConditionalFormats.Any(cf => cf.Values.Any(v => v.Value.Value == "B2" && v.Value.IsFormula)));
}
[Test]
public void TestRowCopyContents()
{
var workbook = new XLWorkbook();
IXLWorksheet originalSheet = workbook.Worksheets.Add("original");
IXLWorksheet copyRowSheet = workbook.Worksheets.Add("copy row");
IXLWorksheet copyRowAsRangeSheet = workbook.Worksheets.Add("copy row as range");
IXLWorksheet copyRangeSheet = workbook.Worksheets.Add("copy range");
originalSheet.Cell("A2").SetValue("test value");
originalSheet.Range("A2:E2").Merge();
{
IXLRange originalRange = originalSheet.Range("A2:E2");
IXLRange destinationRange = copyRangeSheet.Range("A2:E2");
originalRange.CopyTo(destinationRange);
}
CopyRowAsRange(originalSheet, 2, copyRowAsRangeSheet, 3);
{
IXLRow originalRow = originalSheet.Row(2);
IXLRow destinationRow = copyRowSheet.Row(2);
copyRowSheet.Cell("G2").Value = "must be removed after copy";
originalRow.CopyTo(destinationRow);
}
TestHelper.SaveWorkbook(workbook, "Misc", "CopyRowContents.xlsx");
}
[Test]
public void UpdateCellsWorksheetTest()
{
using (var wb = new XLWorkbook())
{
var ws1 = wb.Worksheets.Add("Sheet1");
ws1.Cell(1, 1).Value = "hello, world.";
var ws2 = ws1.CopyTo("Sheet2");
Assert.AreEqual("Sheet1", ws1.FirstCell().Address.Worksheet.Name);
Assert.AreEqual("Sheet2", ws2.FirstCell().Address.Worksheet.Name);
}
}
}
}
@@ -0,0 +1,87 @@
using System;
using ClosedXML.Excel;
using NUnit.Framework;
using DocumentFormat.OpenXml;
namespace ClosedXML_Tests.Excel
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestFixture]
public class ExtensionsTests
{
[Test]
public void FixNewLines()
{
Assert.AreEqual("\n".FixNewLines(), Environment.NewLine);
Assert.AreEqual("\r\n".FixNewLines(), Environment.NewLine);
Assert.AreEqual("\rS\n".FixNewLines(), "\rS" + Environment.NewLine);
Assert.AreEqual("\r\n\n".FixNewLines(), Environment.NewLine + Environment.NewLine);
}
[Test]
public void DoubleSaveRound()
{
Double value = 1234.1234567;
Assert.AreEqual(value.SaveRound(), Math.Round(value, 6));
}
[Test]
public void DoubleValueSaveRound()
{
Double value = 1234.1234567;
Assert.AreEqual(new DoubleValue(value).SaveRound().Value, Math.Round(value, 6));
}
[TestCase("NoEscaping", ExpectedResult = "NoEscaping")]
[TestCase("1", ExpectedResult = "'1'")]
[TestCase("AB-CD", ExpectedResult = "'AB-CD'")]
[TestCase(" AB", ExpectedResult = "' AB'")]
[TestCase("Test sheet", ExpectedResult = "'Test sheet'")]
[TestCase("O'Kelly", ExpectedResult = "'O''Kelly'")]
[TestCase("A2+3", ExpectedResult = "'A2+3'")]
[TestCase("A\"B", ExpectedResult = "'A\"B'")]
[TestCase("A!B", ExpectedResult = "'A!B'")]
[TestCase("A~B", ExpectedResult = "'A~B'")]
[TestCase("A^B", ExpectedResult = "'A^B'")]
[TestCase("A&B", ExpectedResult = "'A&B'")]
[TestCase("A>B", ExpectedResult = "'A>B'")]
[TestCase("A<B", ExpectedResult = "'A<B'")]
[TestCase("A.B", ExpectedResult = "A.B")]
[TestCase(".", ExpectedResult = "'.'")]
[TestCase("A_B", ExpectedResult = "A_B")]
[TestCase("_", ExpectedResult = "_")]
[TestCase("=", ExpectedResult = "'='")]
[TestCase("A,B", ExpectedResult = "'A,B'")]
[TestCase("A@B", ExpectedResult = "'A@B'")]
[TestCase("(Test)", ExpectedResult = "'(Test)'")]
[TestCase("A#", ExpectedResult = "'A#'")]
[TestCase("A$", ExpectedResult = "'A$'")]
[TestCase("A%", ExpectedResult = "'A%'")]
[TestCase("ABC1", ExpectedResult = "'ABC1'")]
[TestCase("ABCD1", ExpectedResult = "ABCD1")]
[TestCase("R1C1", ExpectedResult = "'R1C1'")]
[TestCase("A{", ExpectedResult = "'A{'")]
[TestCase("A}", ExpectedResult = "'A}'")]
[TestCase("A`", ExpectedResult = "'A`'")]
[TestCase("Русский", ExpectedResult = "Русский")]
[TestCase("日本語", ExpectedResult = "日本語")]
[TestCase("한국어", ExpectedResult = "한국어")]
[TestCase("Slovenščina", ExpectedResult = "Slovenščina")]
[TestCase("", ExpectedResult = "")]
[TestCase(null, ExpectedResult = null)]
public string CanEscapeSheetName(string sheetName)
{
return StringExtensions.EscapeSheetName(sheetName);
}
[TestCase("TestSheet", ExpectedResult = "TestSheet")]
[TestCase("'Test sheet'", ExpectedResult = "Test sheet")]
[TestCase("'O''Kelly'", ExpectedResult = "O'Kelly")]
public string CanUnescapeSheetName(string sheetName)
{
return StringExtensions.UnescapeSheetName(sheetName);
}
}
}
+228
View File
@@ -0,0 +1,228 @@
using ClosedXML.Excel;
using ClosedXML.Excel.CalcEngine.Exceptions;
using NUnit.Framework;
using System;
using System.Linq;
namespace ClosedXML_Tests.Excel
{
[TestFixture]
public class FormulaTests
{
[Test]
public void CopyFormula()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell("A1").FormulaA1 = "B1";
ws.Cell("A1").CopyTo("A2");
Assert.AreEqual("B2", ws.Cell("A2").FormulaA1);
}
[Test]
public void CopyFormula2()
{
using (var wb = new XLWorkbook())
{
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell("A1").FormulaA1 = "A2-1";
ws.Cell("A1").CopyTo("B1");
Assert.AreEqual("R[1]C-1", ws.Cell("A1").FormulaR1C1);
Assert.AreEqual("R[1]C-1", ws.Cell("B1").FormulaR1C1);
Assert.AreEqual("B2-1", ws.Cell("B1").FormulaA1);
ws.Cell("A1").FormulaA1 = "B1+1";
ws.Cell("A1").CopyTo("A2");
Assert.AreEqual("RC[1]+1", ws.Cell("A1").FormulaR1C1);
Assert.AreEqual("RC[1]+1", ws.Cell("A2").FormulaR1C1);
Assert.AreEqual("B2+1", ws.Cell("A2").FormulaA1);
}
}
[Test]
public void CopyFormulaWithSheetNameThatResemblesFormula()
{
using (var wb = new XLWorkbook())
{
IXLWorksheet ws = wb.Worksheets.Add("S10 Data");
ws.Cell("A1").Value = "Some value";
ws.Cell("A2").Value = 123;
ws = wb.Worksheets.Add("Summary");
ws.Cell("A1").FormulaA1 = "='S10 Data'!A1";
Assert.AreEqual("Some value", ws.Cell("A1").Value);
ws.Cell("A1").CopyTo("A2");
Assert.AreEqual("'S10 Data'!A2", ws.Cell("A2").FormulaA1);
ws.Cell("A1").CopyTo("B1");
Assert.AreEqual("'S10 Data'!B1", ws.Cell("B1").FormulaA1);
ws.Cell("A3").FormulaA1 = "=SUM('S10 Data'!A2)";
Assert.AreEqual(123, ws.Cell("A3").Value);
}
}
[Test]
public void FormulaWithReferenceIncludingSheetName()
{
using (var wb = new XLWorkbook())
{
object value;
var ws = wb.AddWorksheet("Sheet1");
ws.Cell("A1").InsertData(Enumerable.Range(1, 50));
ws.Cell("B1").FormulaA1 = "=SUM(A1:A50)";
value = ws.Cell("B1").Value;
Assert.AreEqual(1275, value);
ws = wb.AddWorksheet("Sheet2");
ws.Cell("A1").FormulaA1 = "=SUM(Sheet1!A1:Sheet1!A50)";
value = ws.Cell("A1").Value;
Assert.AreEqual(1275, value);
ws.Cell("B1").FormulaA1 = "=SUM(Sheet1!A1:A50)";
value = ws.Cell("B1").Value;
Assert.AreEqual(1275, value);
}
}
[Test]
public void InvalidReferences()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("Sheet1");
ws.Cell("A1").InsertData(Enumerable.Range(1, 50));
ws = wb.AddWorksheet("Sheet2");
ws.Cell("A1").FormulaA1 = "=SUM(Sheet1!A1:Sheet2!A50)";
Assert.That(() => ws.Cell("A1").Value, Throws.InstanceOf<ArgumentOutOfRangeException>());
ws.Cell("B1").FormulaA1 = "=SUM(Sheet1!A1:UnknownSheet!A50)";
Assert.That(() => ws.Cell("B1").Value, Throws.InstanceOf<ArgumentOutOfRangeException>());
}
}
[Test]
public void DateAgainstStringComparison()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("Sheet1");
ws.Cell("A1").Value = new DateTime(2016, 1, 1);
ws.Cell("A1").DataType = XLDataType.DateTime;
ws.Cell("A2").FormulaA1 = @"=IF(A1 = """", ""A"", ""B"")";
var actual = ws.Cell("A2").Value;
Assert.AreEqual(actual, "B");
ws.Cell("A3").FormulaA1 = @"=IF("""" = A1, ""A"", ""B"")";
actual = ws.Cell("A3").Value;
Assert.AreEqual(actual, "B");
}
}
[Test]
public void FormulaThatReferencesEntireRow()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().Value = 1;
ws.FirstCell().CellRight().Value = 2;
ws.FirstCell().CellRight(5).Value = 3;
ws.FirstCell().CellBelow().FormulaA1 = "=SUM(1:1)";
var actual = ws.FirstCell().CellBelow().Value;
Assert.AreEqual(6, actual);
}
}
[Test]
public void FormulaThatReferencesEntireColumn()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().Value = 1;
ws.FirstCell().CellBelow().Value = 2;
ws.FirstCell().CellBelow(5).Value = 3;
ws.FirstCell().CellRight().FormulaA1 = "=SUM(A:A)";
var actual = ws.FirstCell().CellRight().Value;
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<CellReferenceException>(() => XLWorkbook.EvaluateExpr("YEAR(#REF!)"));
Assert.Throws<CellValueException>(() => XLWorkbook.EvaluateExpr("YEAR(#VALUE!)"));
Assert.Throws<DivisionByZeroException>(() => XLWorkbook.EvaluateExpr("YEAR(#DIV/0!)"));
Assert.Throws<NameNotRecognizedException>(() => XLWorkbook.EvaluateExpr("YEAR(#NAME?)"));
Assert.Throws<NoValueAvailableException>(() => XLWorkbook.EvaluateExpr("YEAR(#N/A)"));
Assert.Throws<NullValueException>(() => XLWorkbook.EvaluateExpr("YEAR(#NULL!)"));
Assert.Throws<NumberException>(() => XLWorkbook.EvaluateExpr("YEAR(#NUM!)"));
}
[Test]
public void UnicodeLetterParsing()
{
using (var wb = new XLWorkbook())
{
var ws1 = wb.AddWorksheet("Sheet C CÄ");
var ws2 = wb.AddWorksheet("ÖC");
var ws3 = wb.AddWorksheet("Sheet3");
ws1.FirstCell().SetValue(100);
ws2.FirstCell().SetValue(50);
ws3.FirstCell().FormulaA1 = "='Sheet C CÄ'!A1";
ws3.FirstCell().CellBelow().FormulaA1 = "ÖC!A1";
Assert.AreEqual(100, ws3.FirstCell().Value);
Assert.AreEqual(50, ws3.FirstCell().CellBelow().Value);
}
}
[Test]
public void ShiftFormula()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
ws.Cell("B1").FormulaA1 = "ATAN2(C1,C2)";
ws.Cell("B2").FormulaA1 = "DEC2HEX(C2)";
ws.Range("B3:B5").FormulaA1 = "{DAYS360(C3:C5, D3:D5)}";
ws.Column(1).Delete();
Assert.AreEqual("ATAN2(B1,B2)", ws.Cell("A1").FormulaA1);
Assert.AreEqual("DEC2HEX(B2)", ws.Cell("A2").FormulaA1);
Assert.AreEqual("{DAYS360(B3:B5, C3:C5)}", ws.Cell("A3").FormulaA1);
}
}
}
}
@@ -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);
}
}
}
}
+78
View File
@@ -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<T>()", 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()));
}
}
}
}
+114
View File
@@ -0,0 +1,114 @@
using ClosedXML.Excel;
using NUnit.Framework;
namespace ClosedXML_Tests.Excel.Misc
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestFixture]
public class StylesTests
{
private static void SetupBorders(IXLRange range)
{
range.FirstRow().Cell(1).Style.Border.TopBorder = XLBorderStyleValues.None;
range.FirstRow().Cell(2).Style.Border.TopBorder = XLBorderStyleValues.Thick;
range.FirstRow().Cell(3).Style.Border.TopBorder = XLBorderStyleValues.Double;
range.LastRow().Cell(1).Style.Border.BottomBorder = XLBorderStyleValues.None;
range.LastRow().Cell(2).Style.Border.BottomBorder = XLBorderStyleValues.Thick;
range.LastRow().Cell(3).Style.Border.BottomBorder = XLBorderStyleValues.Double;
range.FirstColumn().Cell(1).Style.Border.LeftBorder = XLBorderStyleValues.None;
range.FirstColumn().Cell(2).Style.Border.LeftBorder = XLBorderStyleValues.Thick;
range.FirstColumn().Cell(3).Style.Border.LeftBorder = XLBorderStyleValues.Double;
range.LastColumn().Cell(1).Style.Border.RightBorder = XLBorderStyleValues.None;
range.LastColumn().Cell(2).Style.Border.RightBorder = XLBorderStyleValues.Thick;
range.LastColumn().Cell(3).Style.Border.RightBorder = XLBorderStyleValues.Double;
}
[Test]
public void InsideBorderTest()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
IXLRange range = ws.Range("B2:D4");
SetupBorders(range);
range.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
range.Style.Border.InsideBorderColor = XLColor.Red;
IXLCell center = range.Cell(2, 2);
Assert.AreEqual(XLColor.Red, center.Style.Border.TopBorderColor);
Assert.AreEqual(XLColor.Red, center.Style.Border.BottomBorderColor);
Assert.AreEqual(XLColor.Red, center.Style.Border.LeftBorderColor);
Assert.AreEqual(XLColor.Red, center.Style.Border.RightBorderColor);
Assert.AreEqual(XLBorderStyleValues.None, range.FirstRow().Cell(1).Style.Border.TopBorder);
Assert.AreEqual(XLBorderStyleValues.Thick, range.FirstRow().Cell(2).Style.Border.TopBorder);
Assert.AreEqual(XLBorderStyleValues.Double, range.FirstRow().Cell(3).Style.Border.TopBorder);
Assert.AreEqual(XLBorderStyleValues.None, range.LastRow().Cell(1).Style.Border.BottomBorder);
Assert.AreEqual(XLBorderStyleValues.Thick, range.LastRow().Cell(2).Style.Border.BottomBorder);
Assert.AreEqual(XLBorderStyleValues.Double, range.LastRow().Cell(3).Style.Border.BottomBorder);
Assert.AreEqual(XLBorderStyleValues.None, range.FirstColumn().Cell(1).Style.Border.LeftBorder);
Assert.AreEqual(XLBorderStyleValues.Thick, range.FirstColumn().Cell(2).Style.Border.LeftBorder);
Assert.AreEqual(XLBorderStyleValues.Double, range.FirstColumn().Cell(3).Style.Border.LeftBorder);
Assert.AreEqual(XLBorderStyleValues.None, range.LastColumn().Cell(1).Style.Border.RightBorder);
Assert.AreEqual(XLBorderStyleValues.Thick, range.LastColumn().Cell(2).Style.Border.RightBorder);
Assert.AreEqual(XLBorderStyleValues.Double, range.LastColumn().Cell(3).Style.Border.RightBorder);
}
[Test]
public void ResolveThemeColors()
{
using (var wb = new XLWorkbook())
{
string color;
color = wb.Theme.ResolveThemeColor(XLThemeColor.Accent1).Color.ToHex();
Assert.AreEqual("FF4F81BD", color);
color = wb.Theme.ResolveThemeColor(XLThemeColor.Background1).Color.ToHex();
Assert.AreEqual("FFFFFFFF", color);
}
}
[Theory]
public void CanResolveAllThemeColors(XLThemeColor themeColor)
{
var theme = new XLWorkbook().Theme;
var color = theme.ResolveThemeColor(themeColor);
Assert.IsNotNull(color);
}
[Test]
public void SetStyleViaRowReference()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("Sheet1");
ws.Style
.Font.SetFontSize(8)
.Font.SetFontColor(XLColor.Green)
.Font.SetBold(true);
var row = ws.Row(1);
ws.Cell(1, 1).Value = "Test";
row.Cell(2).Value = "Test";
row.Cells(3, 3).Value = "Test";
foreach (var cell in ws.CellsUsed())
{
Assert.AreEqual(8, ws.Cell("A1").Style.Font.FontSize);
Assert.AreEqual(XLColor.Green, ws.Cell("B1").Style.Font.FontColor);
Assert.AreEqual(true, ws.Cell("C1").Style.Font.Bold);
}
}
}
}
}
@@ -0,0 +1,463 @@
using ClosedXML.Excel;
using NUnit.Framework;
using System;
using System.IO;
using System.Linq;
namespace ClosedXML_Tests.Excel
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestFixture]
public class XLWorkbookTests
{
[Test]
public void Cell1()
{
var wb = new XLWorkbook();
IXLCell cell = wb.Cell("ABC");
Assert.IsNull(cell);
}
[Test]
public void Cell2()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result", XLScope.Worksheet);
IXLCell cell = wb.Cell("Sheet1!Result");
Assert.IsNotNull(cell);
Assert.AreEqual(1, cell.GetValue<Int32>());
}
[Test]
public void Cell3()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result");
IXLCell cell = wb.Cell("Sheet1!Result");
Assert.IsNotNull(cell);
Assert.AreEqual(1, cell.GetValue<Int32>());
}
[Test]
public void Cells1()
{
var wb = new XLWorkbook();
IXLCells cells = wb.Cells("ABC");
Assert.IsNotNull(cells);
Assert.AreEqual(0, cells.Count());
}
[Test]
public void Cells2()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result", XLScope.Worksheet);
IXLCells cells = wb.Cells("Sheet1!Result, ABC");
Assert.IsNotNull(cells);
Assert.AreEqual(1, cells.Count());
Assert.AreEqual(1, cells.First().GetValue<Int32>());
}
[Test]
public void Cells3()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result");
IXLCells cells = wb.Cells("Sheet1!Result, ABC");
Assert.IsNotNull(cells);
Assert.AreEqual(1, cells.Count());
Assert.AreEqual(1, cells.First().GetValue<Int32>());
}
[Test]
public void GetCellFromFullAddress()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
IXLWorksheet ws2 = wb.AddWorksheet("O'Sheet 2");
var c1 = ws.Cell("C123");
var c2 = ws2.Cell("B7");
var c1_full = wb.Cell("Sheet1!C123");
var c2_full = wb.Cell("'O'Sheet 2'!B7");
Assert.AreSame(c1, c1_full);
Assert.AreSame(c2, c2_full);
Assert.NotNull(c1_full);
Assert.NotNull(c2_full);
}
[TestCase("Sheet1")]
[TestCase("Sheet1!")]
[TestCase("Sheet2!")]
[TestCase("Sheet2!C1")]
[TestCase("Sheet1!ZZZ1")]
[TestCase("Sheet1!A")]
public void GetCellFromNonExistingFullAddress(string address)
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
var c = wb.Cell(address);
Assert.IsNull(c);
}
[Test]
public void GetRangeFromFullAddress()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
var r1 = ws.Range("C123:D125");
var r2 = wb.Range("Sheet1!C123:D125");
Assert.AreSame(r1, r2);
Assert.NotNull(r2);
}
[TestCase("Sheet2!C1:D2")]
[TestCase("Sheet1!A")]
public void GetRangeFromNonExistingFullAddress(string rangeAddress)
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
var r = wb.Range(rangeAddress);
Assert.IsNull(r);
}
[Test]
public void GetRangesFromFullAddress()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
var r1 = ws.Ranges("A1:B2,C1:E3");
var r2 = wb.Ranges("Sheet1!A1:B2,Sheet1!C1:E3");
Assert.AreEqual(2, r2.Count);
Assert.AreSame(r1.First(), r2.First());
Assert.AreSame(r1.Last(), r2.Last());
}
[TestCase("Sheet2!C1:D2,Sheet2!F1:G4")]
[TestCase("Sheet1!A,Sheet1!B")]
public void GetRangesFromNonExistingFullAddress(string rangesAddress)
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
var r = wb.Ranges(rangesAddress);
Assert.NotNull(r);
Assert.False(r.Any());
}
[Test]
public void NamedRange1()
{
var wb = new XLWorkbook();
IXLNamedRange range = wb.NamedRange("ABC");
Assert.IsNull(range);
}
[Test]
public void NamedRange2()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result", XLScope.Worksheet);
IXLNamedRange range = wb.NamedRange("Sheet1!Result");
Assert.IsNotNull(range);
Assert.AreEqual(1, range.Ranges.Count);
Assert.AreEqual(1, range.Ranges.Cells().Count());
Assert.AreEqual(1, range.Ranges.First().FirstCell().GetValue<Int32>());
}
[Test]
public void NamedRange3()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
IXLNamedRange range = wb.NamedRange("Sheet1!Result");
Assert.IsNull(range);
}
[Test]
public void NamedRange4()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result");
IXLNamedRange range = wb.NamedRange("Sheet1!Result");
Assert.IsNotNull(range);
Assert.AreEqual(1, range.Ranges.Count);
Assert.AreEqual(1, range.Ranges.Cells().Count());
Assert.AreEqual(1, range.Ranges.First().FirstCell().GetValue<Int32>());
}
[Test]
public void Range1()
{
var wb = new XLWorkbook();
IXLRange range = wb.Range("ABC");
Assert.IsNull(range);
}
[Test]
public void Range2()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result", XLScope.Worksheet);
IXLRange range = wb.Range("Sheet1!Result");
Assert.IsNotNull(range);
Assert.AreEqual(1, range.Cells().Count());
Assert.AreEqual(1, range.FirstCell().GetValue<Int32>());
}
[Test]
public void Range3()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result");
IXLRange range = wb.Range("Sheet1!Result");
Assert.IsNotNull(range);
Assert.AreEqual(1, range.Cells().Count());
Assert.AreEqual(1, range.FirstCell().GetValue<Int32>());
}
[Test]
public void Ranges1()
{
var wb = new XLWorkbook();
IXLRanges ranges = wb.Ranges("ABC");
Assert.IsNotNull(ranges);
Assert.AreEqual(0, ranges.Count());
}
[Test]
public void Ranges2()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result", XLScope.Worksheet);
IXLRanges ranges = wb.Ranges("Sheet1!Result, ABC");
Assert.IsNotNull(ranges);
Assert.AreEqual(1, ranges.Cells().Count());
Assert.AreEqual(1, ranges.First().FirstCell().GetValue<Int32>());
}
[Test]
public void Ranges3()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().SetValue(1).AddToNamed("Result");
IXLRanges ranges = wb.Ranges("Sheet1!Result, ABC");
Assert.IsNotNull(ranges);
Assert.AreEqual(1, ranges.Cells().Count());
Assert.AreEqual(1, ranges.First().FirstCell().GetValue<Int32>());
}
[Test]
public void WbNamedCell()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell(1, 1).SetValue("Test").AddToNamed("TestCell");
Assert.AreEqual("Test", wb.Cell("TestCell").GetString());
Assert.AreEqual("Test", ws.Cell("TestCell").GetString());
}
[Test]
public void WbNamedCells()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell(1, 1).SetValue("Test").AddToNamed("TestCell");
ws.Cell(2, 1).SetValue("B").AddToNamed("Test2");
IXLCells wbCells = wb.Cells("TestCell, Test2");
Assert.AreEqual("Test", wbCells.First().GetString());
Assert.AreEqual("B", wbCells.Last().GetString());
IXLCells wsCells = ws.Cells("TestCell, Test2");
Assert.AreEqual("Test", wsCells.First().GetString());
Assert.AreEqual("B", wsCells.Last().GetString());
}
[Test]
public void WbNamedRange()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell(1, 1).SetValue("A");
ws.Cell(2, 1).SetValue("B");
IXLRange original = ws.Range("A1:A2");
original.AddToNamed("TestRange");
Assert.AreEqual(original.RangeAddress.ToStringFixed(), wb.Range("TestRange").RangeAddress.ToString());
Assert.AreEqual(original.RangeAddress.ToStringFixed(), ws.Range("TestRange").RangeAddress.ToString());
}
[Test]
public void WbNamedRanges()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell(1, 1).SetValue("A");
ws.Cell(2, 1).SetValue("B");
ws.Cell(3, 1).SetValue("C").AddToNamed("Test2");
IXLRange original = ws.Range("A1:A2");
original.AddToNamed("TestRange");
IXLRanges wbRanges = wb.Ranges("TestRange, Test2");
Assert.AreEqual(original.RangeAddress.ToStringFixed(), wbRanges.First().RangeAddress.ToString());
Assert.AreEqual("$A$3:$A$3", wbRanges.Last().RangeAddress.ToStringFixed());
IXLRanges wsRanges = wb.Ranges("TestRange, Test2");
Assert.AreEqual(original.RangeAddress.ToStringFixed(), wsRanges.First().RangeAddress.ToString());
Assert.AreEqual("$A$3:$A$3", wsRanges.Last().RangeAddress.ToStringFixed());
}
[Test]
public void WbNamedRangesOneString()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
wb.NamedRanges.Add("TestRange", "Sheet1!$A$1,Sheet1!$A$3");
IXLRanges wbRanges = ws.Ranges("TestRange");
Assert.AreEqual("$A$1:$A$1", wbRanges.First().RangeAddress.ToStringFixed());
Assert.AreEqual("$A$3:$A$3", wbRanges.Last().RangeAddress.ToStringFixed());
IXLRanges wsRanges = ws.Ranges("TestRange");
Assert.AreEqual("$A$1:$A$1", wsRanges.First().RangeAddress.ToStringFixed());
Assert.AreEqual("$A$3:$A$3", wsRanges.Last().RangeAddress.ToStringFixed());
}
[Test]
public void WbProtect1()
{
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("Sheet1");
wb.Protect();
Assert.IsTrue(wb.LockStructure);
Assert.IsFalse(wb.LockWindows);
Assert.IsFalse(wb.IsPasswordProtected);
}
}
[Test]
public void WbProtect2()
{
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("Sheet1");
wb.Protect(true, false);
Assert.IsTrue(wb.LockStructure);
Assert.IsFalse(wb.LockWindows);
Assert.IsFalse(wb.IsPasswordProtected);
}
}
[Test]
public void WbProtect3()
{
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("Sheet1");
wb.Protect("Abc@123");
Assert.IsTrue(wb.LockStructure);
Assert.IsFalse(wb.LockWindows);
Assert.IsTrue(wb.IsPasswordProtected);
Assert.Throws<InvalidOperationException>(() => wb.Protect());
Assert.Throws<InvalidOperationException>(() => wb.Unprotect());
Assert.Throws<ArgumentException>(() => wb.Unprotect("Cde@345"));
}
}
[Test]
public void WbProtect4()
{
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("Sheet1");
wb.Protect();
Assert.IsTrue(wb.LockStructure);
Assert.IsFalse(wb.LockWindows);
Assert.IsFalse(wb.IsPasswordProtected);
wb.Unprotect();
wb.Protect("Abc@123");
Assert.IsTrue(wb.LockStructure);
Assert.IsFalse(wb.LockWindows);
Assert.IsTrue(wb.IsPasswordProtected);
}
}
[Test]
public void WbProtect5()
{
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("Sheet1");
wb.Protect(true, false, "Abc@123");
Assert.IsTrue(wb.LockStructure);
Assert.IsFalse(wb.LockWindows);
Assert.IsTrue(wb.IsPasswordProtected);
wb.Unprotect("Abc@123");
Assert.IsFalse(wb.LockStructure);
Assert.IsFalse(wb.LockWindows);
Assert.IsFalse(wb.IsPasswordProtected);
}
}
[Test]
public void FileSharingProperties()
{
using (var ms = new MemoryStream())
{
using (var wb = new XLWorkbook())
{
wb.AddWorksheet("Sheet1").Cell("A1").Value = "Hello world!";
wb.FileSharing.ReadOnlyRecommended = true;
wb.FileSharing.UserName = Environment.UserName;
wb.SaveAs(ms);
}
ms.Seek(0, SeekOrigin.Begin);
using (var wb = new XLWorkbook(ms))
{
Assert.IsTrue(wb.FileSharing.ReadOnlyRecommended);
Assert.AreEqual(Environment.UserName, wb.FileSharing.UserName);
}
}
}
#if _NET40_
[Ignore(".NET 40 does not support Janitor.Fody")]
#endif
[Test]
public void AccessDisposedWorkbookThrowsException()
{
IXLWorkbook wb;
using (wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
ws.FirstCell().SetValue("Hello world");
}
Assert.Throws<ObjectDisposedException>(() => Console.WriteLine(wb.Worksheets.First().FirstCell().Value));
}
}
}
+200
View File
@@ -0,0 +1,200 @@
using ClosedXML.Excel;
using NUnit.Framework;
using System;
using System.Collections.Generic;
namespace ClosedXML_Tests.Excel
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestFixture]
public class XlHelperTests
{
private static void CheckColumnNumber(int column)
{
Assert.AreEqual(column, XLHelper.GetColumnNumberFromLetter(XLHelper.GetColumnLetterFromNumber(column)));
}
[Test]
public void InvalidA1Addresses()
{
Assert.IsFalse(XLHelper.IsValidA1Address(""));
Assert.IsFalse(XLHelper.IsValidA1Address("A"));
Assert.IsFalse(XLHelper.IsValidA1Address("a"));
Assert.IsFalse(XLHelper.IsValidA1Address("1"));
Assert.IsFalse(XLHelper.IsValidA1Address("-1"));
Assert.IsFalse(XLHelper.IsValidA1Address("AAAA1"));
Assert.IsFalse(XLHelper.IsValidA1Address("XFG1"));
Assert.IsFalse(XLHelper.IsValidA1Address("@A1"));
Assert.IsFalse(XLHelper.IsValidA1Address("@AA1"));
Assert.IsFalse(XLHelper.IsValidA1Address("@AAA1"));
Assert.IsFalse(XLHelper.IsValidA1Address("[A1"));
Assert.IsFalse(XLHelper.IsValidA1Address("[AA1"));
Assert.IsFalse(XLHelper.IsValidA1Address("[AAA1"));
Assert.IsFalse(XLHelper.IsValidA1Address("{A1"));
Assert.IsFalse(XLHelper.IsValidA1Address("{AA1"));
Assert.IsFalse(XLHelper.IsValidA1Address("{AAA1"));
Assert.IsFalse(XLHelper.IsValidA1Address("A1@"));
Assert.IsFalse(XLHelper.IsValidA1Address("AA1@"));
Assert.IsFalse(XLHelper.IsValidA1Address("AAA1@"));
Assert.IsFalse(XLHelper.IsValidA1Address("A1["));
Assert.IsFalse(XLHelper.IsValidA1Address("AA1["));
Assert.IsFalse(XLHelper.IsValidA1Address("AAA1["));
Assert.IsFalse(XLHelper.IsValidA1Address("A1{"));
Assert.IsFalse(XLHelper.IsValidA1Address("AA1{"));
Assert.IsFalse(XLHelper.IsValidA1Address("AAA1{"));
Assert.IsFalse(XLHelper.IsValidA1Address("@A1@"));
Assert.IsFalse(XLHelper.IsValidA1Address("@AA1@"));
Assert.IsFalse(XLHelper.IsValidA1Address("@AAA1@"));
Assert.IsFalse(XLHelper.IsValidA1Address("[A1["));
Assert.IsFalse(XLHelper.IsValidA1Address("[AA1["));
Assert.IsFalse(XLHelper.IsValidA1Address("[AAA1["));
Assert.IsFalse(XLHelper.IsValidA1Address("{A1{"));
Assert.IsFalse(XLHelper.IsValidA1Address("{AA1{"));
Assert.IsFalse(XLHelper.IsValidA1Address("{AAA1{"));
}
[Test]
public void PlusAA1_Is_Not_an_address()
{
Assert.IsFalse(XLHelper.IsValidA1Address("+AA1"));
}
[Test]
public void TestConvertColumnLetterToNumberAnd()
{
CheckColumnNumber(1);
CheckColumnNumber(27);
CheckColumnNumber(28);
CheckColumnNumber(52);
CheckColumnNumber(53);
CheckColumnNumber(1000);
CheckColumnNumber(1353);
}
[Test]
public void ValidA1Addresses()
{
Assert.IsTrue(XLHelper.IsValidA1Address("A1"));
Assert.IsTrue(XLHelper.IsValidA1Address("A" + XLHelper.MaxRowNumber));
Assert.IsTrue(XLHelper.IsValidA1Address("Z1"));
Assert.IsTrue(XLHelper.IsValidA1Address("Z" + XLHelper.MaxRowNumber));
Assert.IsTrue(XLHelper.IsValidA1Address("AA1"));
Assert.IsTrue(XLHelper.IsValidA1Address("AA" + XLHelper.MaxRowNumber));
Assert.IsTrue(XLHelper.IsValidA1Address("ZZ1"));
Assert.IsTrue(XLHelper.IsValidA1Address("ZZ" + XLHelper.MaxRowNumber));
Assert.IsTrue(XLHelper.IsValidA1Address("AAA1"));
Assert.IsTrue(XLHelper.IsValidA1Address("AAA" + XLHelper.MaxRowNumber));
Assert.IsTrue(XLHelper.IsValidA1Address(XLHelper.MaxColumnLetter + "1"));
Assert.IsTrue(XLHelper.IsValidA1Address(XLHelper.MaxColumnLetter + XLHelper.MaxRowNumber));
}
[Test]
public void TestColumnLetterLookup()
{
var columnLetters = new List<String>();
for (int c = 1; c <= XLHelper.MaxColumnNumber; c++)
{
var columnLetter = NaiveGetColumnLetterFromNumber(c);
columnLetters.Add(columnLetter);
Assert.AreEqual(columnLetter, XLHelper.GetColumnLetterFromNumber(c));
}
foreach (var cl in columnLetters)
{
var columnNumber = NaiveGetColumnNumberFromLetter(cl);
Assert.AreEqual(columnNumber, XLHelper.GetColumnNumberFromLetter(cl));
}
}
[TestCase("R")]
[TestCase("C")]
[TestCase("RC")]
[TestCase("R111C222")]
[TestCase("R[]C")]
[TestCase("RC[]")]
[TestCase("R[]C[]")]
[TestCase("R[111]C222")]
[TestCase("R111C[222]")]
[TestCase("R[111]C[222]")]
[TestCase("R[-111]C[-222]")]
public void ValidRCAddresses(string address)
{
Assert.IsTrue(XLHelper.IsValidRCAddress(address));
}
[TestCase("RD")]
[TestCase("CC")]
[TestCase("R[-]C222")]
[TestCase("R[]C[-]")]
[TestCase("_R111C222")]
public void InvalidRCAddresses(string address)
{
Assert.IsFalse(XLHelper.IsValidRCAddress(address));
}
#region Old XLHelper methods
private static readonly string[] letters = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
/// <summary>
/// These used to be the methods in XLHelper, but were later changed
/// We now use them as a check against the new methods
/// Gets the column number of a given column letter.
/// </summary>
/// <param name="columnLetter"> The column letter to translate into a column number. </param>
private static int NaiveGetColumnNumberFromLetter(string columnLetter)
{
if (string.IsNullOrEmpty(columnLetter)) throw new ArgumentNullException("columnLetter");
int retVal;
columnLetter = columnLetter.ToUpper();
//Extra check because we allow users to pass row col positions in as strings
if (columnLetter[0] <= '9')
{
retVal = Int32.Parse(columnLetter, XLHelper.NumberStyle, XLHelper.ParseCulture);
return retVal;
}
int sum = 0;
for (int i = 0; i < columnLetter.Length; i++)
{
sum *= 26;
sum += (columnLetter[i] - 'A' + 1);
}
return sum;
}
/// <summary>
/// Gets the column letter of a given column number.
/// </summary>
/// <param name="columnNumber">The column number to translate into a column letter.</param>
/// <param name="trimToAllowed">if set to <c>true</c> the column letter will be restricted to the allowed range.</param>
/// <returns></returns>
private static string NaiveGetColumnLetterFromNumber(int columnNumber, bool trimToAllowed = false)
{
if (trimToAllowed) columnNumber = XLHelper.TrimColumnNumber(columnNumber);
columnNumber--; // Adjust for start on column 1
if (columnNumber <= 25)
{
return letters[columnNumber];
}
var firstPart = (columnNumber) / 26;
var remainder = ((columnNumber) % 26) + 1;
return NaiveGetColumnLetterFromNumber(firstPart) + NaiveGetColumnLetterFromNumber(remainder);
}
#endregion Old XLHelper methods
}
}
@@ -0,0 +1,23 @@
using ClosedXML.Utils;
using NUnit.Framework;
namespace ClosedXML_Tests.Excel
{
[TestFixture]
public class XmlEncoderTest
{
[Test]
public void TestControlChars()
{
Assert.AreEqual("_x0001_ _x0002_ _x0003_ _x0004_", XmlEncoder.EncodeString("\u0001 \u0002 \u0003 \u0004"));
Assert.AreEqual("_x0005_ _x0006_ _x0007_ _x0008_", XmlEncoder.EncodeString("\u0005 \u0006 \u0007 \u0008"));
Assert.AreEqual("\u0001 \u0002 \u0003 \u0004", XmlEncoder.DecodeString("_x0001_ _x0002_ _x0003_ _x0004_"));
Assert.AreEqual("\u0005 \u0006 \u0007 \u0008", XmlEncoder.DecodeString("_x0005_ _x0006_ _x0007_ _x0008_"));
Assert.AreEqual("\uAABB \uAABB", XmlEncoder.DecodeString("_xaaBB_ _xAAbb_"));
// https://github.com/ClosedXML/ClosedXML/issues/1154
Assert.AreEqual("_Xceed_Something", XmlEncoder.DecodeString("_Xceed_Something"));
}
}
}