Skip to content

Commit e41d2de

Browse files
committed
- Fixed null exception problem when converting an empty worksheet into list of objects,
- Incremented version (v2.1.0)
1 parent 5926e01 commit e41d2de

7 files changed

Lines changed: 61 additions & 42 deletions

File tree

common.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<VersionPrefix>2.0.0</VersionPrefix>
3+
<VersionPrefix>2.1.0</VersionPrefix>
44
<Description>An extensions library for both EPPlus and EPPlus.Core packages to generate and manipulate Excel files easily.</Description>
55

66
<NoWarn>$(NoWarn);CS1591</NoWarn>

src/EPPlus.Core.Extensions/ExcelTableExtensions.cs

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@
1111
using OfficeOpenXml.Table;
1212

1313
namespace EPPlus.Core.Extensions
14-
{
15-
/// <summary>
16-
/// Class holds extensions on ExcelTable object
17-
/// </summary>
14+
{
1815
public static class ExcelTableExtensions
1916
{
2017
/// <summary>
21-
/// Returns table data bounds with regards to header and totals row visibility
18+
/// Returns data bounds of the Excel table with regards to header and totals row visibility
2219
/// </summary>
2320
/// <param name="table">Extended object</param>
2421
/// <returns>Address range</returns>
@@ -35,12 +32,12 @@ public static ExcelAddress GetDataBounds(this ExcelTable table)
3532
}
3633

3734
/// <summary>
38-
/// Validates the excel table against the generating type.
35+
/// Validates the Excel table against the generating type.
3936
/// </summary>
40-
/// <typeparam name="T">Generating class type</typeparam>
41-
/// <param name="table">Extended object</param>
37+
/// <typeparam name="T"></typeparam>
38+
/// <param name="table"></param>
4239
/// <param name="configurationAction"></param>
43-
/// <returns>An enumerable of <see cref="ExcelExceptionArgs" /> containing </returns>
40+
/// <returns>An enumerable of <see cref="ExcelExceptionArgs" /> containing</returns>
4441
public static IEnumerable<ExcelExceptionArgs> Validate<T>(this ExcelTable table, Action<ExcelReadConfiguration<T>> configurationAction = null) where T : class, new()
4542
{
4643
ExcelReadConfiguration<T> configuration = DefaultExcelReadConfiguration<T>.Instance;
@@ -87,7 +84,6 @@ public static ExcelAddress GetDataBounds(this ExcelTable table)
8784
/// Generic extension method yielding objects of specified type from table.
8885
/// </summary>
8986
/// <remarks>
90-
/// Exceptions are not catched. It works on all or nothing basis.
9187
/// Only primitives and enums are supported as property.
9288
/// Currently supports only tables with header.
9389
/// </remarks>
@@ -150,20 +146,8 @@ public static ExcelAddress GetDataBounds(this ExcelTable table)
150146
yield return item;
151147
}
152148
}
153-
}
154-
155-
/// <summary>
156-
/// Returns objects of specified type from table as list.
157-
/// </summary>
158-
/// <remarks>
159-
/// Exceptions are not catched. It works on all or nothing basis.
160-
/// Only primitives and enums are supported as property.
161-
/// Currently supports only tables with header.
162-
/// </remarks>
163-
/// <typeparam name="T">Type to map to. Type should be a class and should have parameterless constructor.</typeparam>
164-
/// <param name="table">Table object to fetch</param>
165-
/// <param name="configurationAction"></param>
166-
/// <returns>An enumerable of the generating type</returns>
149+
}
150+
167151
public static List<T> ToList<T>(this ExcelTable table, Action<ExcelReadConfiguration<T>> configurationAction = null) where T : class, new() => AsEnumerable(table, configurationAction).ToList();
168152

169153
/// <summary>

src/EPPlus.Core.Extensions/ExcelWorksheetExtensions.cs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public static class ExcelWorksheetExtensions
2222
/// <returns></returns>
2323
public static ExcelAddress GetDataBounds(this ExcelWorksheet worksheet, bool hasHeaderRow = true)
2424
{
25-
ExcelAddressBase valuedDimension = worksheet.GetValuedDimension();
25+
ExcelAddressBase valuedDimension = worksheet.GetValuedDimension() ?? worksheet.Dimension;
2626

2727
if (valuedDimension == null)
2828
{
@@ -43,7 +43,17 @@ public static ExcelAddress GetDataBounds(this ExcelWorksheet worksheet, bool has
4343
/// <param name="worksheet"></param>
4444
/// <param name="hasHeaderRow"></param>
4545
/// <returns></returns>
46-
public static ExcelRange GetExcelRange(this ExcelWorksheet worksheet, bool hasHeaderRow = true) => worksheet.Cells[worksheet.GetDataBounds(hasHeaderRow).Address];
46+
public static ExcelRange GetExcelRange(this ExcelWorksheet worksheet, bool hasHeaderRow = true)
47+
{
48+
ExcelAddress dataBounds = worksheet.GetDataBounds(hasHeaderRow);
49+
50+
if (dataBounds == null)
51+
{
52+
return null;
53+
}
54+
55+
return worksheet.Cells[dataBounds.Address];
56+
}
4757

4858
/// <summary>
4959
/// Extracts an ExcelTable from given ExcelWorkSheet
@@ -82,7 +92,9 @@ public static ExcelTable AsExcelTable(this ExcelWorksheet worksheet, string tabl
8292
}
8393
}
8494

85-
worksheet.Tables.Add(worksheet.GetExcelRange(false), tableName);
95+
ExcelRange dataRange = worksheet.GetExcelRange(false) ?? worksheet.Cells[1, 1, 1, 1];
96+
97+
worksheet.Tables.Add(dataRange, tableName);
8698
worksheet.Tables[tableName].ShowHeader = hasHeaderRow;
8799

88100
return worksheet.Tables[tableName];
@@ -358,13 +370,13 @@ public static ExcelWorksheet DeleteColumns(this ExcelWorksheet worksheet, string
358370
}
359371

360372
/// <summary>
361-
/// Checks and throws if column value is wrong on specified index
373+
/// Checks and throws the <see cref="ExcelValidationException"/> if column value is wrong on specified index
362374
/// </summary>
363375
/// <param name="worksheet"></param>
364376
/// <param name="rowIndex"></param>
365377
/// <param name="columnIndex"></param>
366378
/// <param name="expectedValue"></param>
367-
/// <param name="exceptionMessage">The {columnIndex}. column of worksheet should be '{expectedValue}'.</param>
379+
/// <param name="exceptionMessage">Custom exception message with format parameters: columnIndex, expectedValue</param>
368380
public static void CheckAndThrowColumn(this ExcelWorksheet worksheet, int rowIndex, int columnIndex, string expectedValue, string exceptionMessage = null)
369381
{
370382
if (!worksheet.GetColumns(rowIndex).Any(x => x.Value == expectedValue && x.Key == columnIndex))
@@ -379,7 +391,7 @@ public static void CheckAndThrowColumn(this ExcelWorksheet worksheet, int rowInd
379391
}
380392

381393
/// <summary>
382-
/// Checks and throws an exception if the worksheet has any formula
394+
/// Checks and throws the <see cref="ExcelValidationException"/> if the worksheet has any formula
383395
/// </summary>
384396
/// <param name="sheet"></param>
385397
/// <param name="withMessage"></param>
@@ -392,7 +404,7 @@ public static void CheckAndThrowIfThereIsAnyFormula(this ExcelWorksheet sheet, s
392404
}
393405

394406
/// <summary>
395-
/// Checks and throws if header columns does not match with ExcelColumnAttribute
407+
/// Checks and throws the <see cref="ExcelValidationException"/> if header columns does not match with properties of object
396408
/// </summary>
397409
/// <typeparam name="T"></typeparam>
398410
/// <param name="worksheet"></param>

src/EPPlus.Core.Extensions/Style/ExcelWorkbookExtensions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ namespace EPPlus.Core.Extensions.Style
1010
public static class ExcelWorkbookExtensions
1111
{
1212
/// <summary>
13-
/// Creates a named style on the Excel workbook. If the named style is already exists, then throws an argument
14-
/// exception.
13+
/// Creates a named style on the Excel workbook. If the named style is already exists then throws the <see cref="ArgumentException"/>
1514
/// </summary>
1615
/// <param name="workbook">The workbook</param>
1716
/// <param name="styleName">The name of style</param>

src/EPPlus.Core.Extensions/ToExcelExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace EPPlus.Core.Extensions
1111
public static class ToExcelExtensions
1212
{
1313
/// <summary>
14-
/// Generates an Excel worksheet from a list
14+
/// Generates an Excel worksheet from given list
1515
/// </summary>
1616
/// <typeparam name="T"></typeparam>
1717
/// <param name="rows"></param>
@@ -30,7 +30,7 @@ public static WorksheetWrapper<T> ToWorksheet<T>(this IEnumerable<T> rows, strin
3030
}
3131

3232
/// <summary>
33-
/// Starts new worksheet on same Excel package
33+
/// Starts a new worksheet on the same Excel package
3434
/// </summary>
3535
/// <typeparam name="T"></typeparam>
3636
/// <typeparam name="K"></typeparam>
@@ -233,7 +233,7 @@ public static ExcelPackage AsExcelPackage(this Stream stream, string password)
233233
}
234234

235235
/// <summary>
236-
/// Converts list of items to Excel and returns the Excel file as a bytearray.
236+
/// Converts list of items to Excel and returns the Excel file as bytearray.
237237
/// </summary>
238238
/// <typeparam name="T">Type of object</typeparam>
239239
/// <param name="rows">List of objects</param>
@@ -252,7 +252,7 @@ public static byte[] ToXlsx<T>(this IEnumerable<T> rows, bool addHeaderRow = tru
252252
}
253253

254254
/// <summary>
255-
/// Returns the Excel file as a bytearray.
255+
/// Returns the Excel file as byte array.
256256
/// </summary>
257257
/// <typeparam name="T"></typeparam>
258258
/// <param name="lastWorksheet"></param>

test/EPPlus.Core.Extensions.Tests/ExcelTableExtensions_Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public void Should_automatically_map_if_column_name_and_index_not_specified()
2121
//-----------------------------------------------------------------------------------------------------------
2222
// Arrange
2323
//-----------------------------------------------------------------------------------------------------------
24-
ExcelTable table = excelPackage.GetWorksheet("TEST1").GetTable("TEST1");
24+
ExcelTable table = excelPackage.GetTable("TEST1");
2525

2626
//-----------------------------------------------------------------------------------------------------------
2727
// Act

test/EPPlus.Core.Extensions.Tests/ExcelWorksheetExtensions_Tests.cs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,26 @@ public void Should_parse_datetime_value_as_correctly_if_formatted_customly()
700700
nullableStocks[1].UpdatedDate.Value.Should().Be(new DateTime(2016, 11, 03, 01, 30, 53));
701701
}
702702

703+
[Fact]
704+
public void Should_throw_Excel_validation_exception_if_worksheet_does_not_have_valued_dimension()
705+
{
706+
//-----------------------------------------------------------------------------------------------------------
707+
// Arrange
708+
//-----------------------------------------------------------------------------------------------------------
709+
ExcelWorksheet worksheet = excelPackage.GetWorksheet("EmptySheet");
710+
711+
//-----------------------------------------------------------------------------------------------------------
712+
// Act
713+
//-----------------------------------------------------------------------------------------------------------
714+
List<Cars> cars = worksheet.ToList<Cars>();
715+
716+
//-----------------------------------------------------------------------------------------------------------
717+
// Assert
718+
//-----------------------------------------------------------------------------------------------------------
719+
cars.Count.Should().Be(0);
720+
}
721+
722+
703723
[Fact]
704724
public void Should_set_horizontal_alignment_of_the_worksheet()
705725
{
@@ -745,7 +765,8 @@ public void Should_throw_an_exception_when_columns_of_worksheet_not_matched_with
745765
// Arrange
746766
//-----------------------------------------------------------------------------------------------------------
747767
ExcelWorksheet worksheet1 = excelPackage.GetWorksheet("TEST6");
748-
ExcelWorksheet emptySheet = excelPackage.Workbook.Worksheets["EmptySheet"];
768+
ExcelWorksheet emptySheet1 = excelPackage.GetWorksheet("EmptySheet");
769+
ExcelWorksheet emptySheet2 = excelPackage.GetWorksheet("EmptySheet");
749770

750771
//-----------------------------------------------------------------------------------------------------------
751772
// Act
@@ -755,7 +776,9 @@ public void Should_throw_an_exception_when_columns_of_worksheet_not_matched_with
755776
Action action3 = () => { worksheet1.CheckHeadersAndThrow<StocksNullable>(2); };
756777
Action action4 = () => { worksheet1.CheckHeadersAndThrow<Car>(2); };
757778

758-
Action actionForEmptySheet = () => emptySheet.CheckHeadersAndThrow<StocksValidation>(1, "The {0}.column of worksheet should be '{1}'.");
779+
Action actionForEmptySheet1 = () => emptySheet1.CheckHeadersAndThrow<StocksValidation>(1, "The {0}.column of worksheet should be '{1}'.");
780+
Action actionForEmptySheet2 = () => emptySheet2.CheckHeadersAndThrow<Cars>(1, "The {0}.column of worksheet should be '{1}'.");
781+
759782

760783
//-----------------------------------------------------------------------------------------------------------
761784
// Assert
@@ -765,7 +788,8 @@ public void Should_throw_an_exception_when_columns_of_worksheet_not_matched_with
765788
action3.Should().NotThrow<ExcelValidationException>();
766789
action4.Should().Throw<ArgumentException>();
767790

768-
actionForEmptySheet.Should().Throw<ExcelValidationException>().And.Message.Should().Be("The 1.column of worksheet should be 'Barcode'.");
791+
actionForEmptySheet1.Should().Throw<ExcelValidationException>().And.Message.Should().Be("The 1.column of worksheet should be 'Barcode'.");
792+
actionForEmptySheet2.Should().Throw<ExcelValidationException>().And.Message.Should().Be("The 1.column of worksheet should be 'LicensePlate'.");
769793
}
770794

771795
[Fact]

0 commit comments

Comments
 (0)