Skip to content

Commit

Permalink
Addresses import by sheet name #26
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchelsellers committed Dec 30, 2022
1 parent 095da36 commit 34da96d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,23 @@ public void ParseDocument_ShouldReturnProperData()
Assert.Equal("John Smith", firstRecord.Name);
Assert.Equal(55, firstRecord.Age);
}

[Fact]
public void ParseDocument_ShouldReturnProperData_BySheetName()
{
//Arrange
var filePath = "../../../SampleFiles/ImportSample.xlsx";
var expectedCount = 3;

//Act
var result = _spreadsheetParser.ParseDocument<PersonRecord>(File.OpenRead(filePath), "Test Sheet", true);

//Assert
Assert.Equal(expectedCount, result.Count);
var firstRecord = result.First();
Assert.Equal("John Smith", firstRecord.Name);
Assert.Equal(55, firstRecord.Age);
var lastRecord = result.Last();
Assert.Equal("Adam", lastRecord.Name);
}
}
Binary file not shown.
10 changes: 10 additions & 0 deletions src/NetCore.Utilities.Spreadsheet/ISpreadsheetParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,14 @@ public interface ISpreadsheetParser
/// <param name="skipHeaderRow">If set to true will skip the first row of data as header information</param>
/// <returns>The parsed information</returns>
List<T> ParseDocument<T>(Stream fileStream, int worksheetNumber, bool skipHeaderRow) where T : new();

/// <summary>
/// Parses the provided document and returns a list of T objects based on the input data, using the specific worksheet by name
/// </summary>
/// <typeparam name="T">The type to use for importing</typeparam>
/// <param name="fileStream">The contents of the Excel File (XLSX format</param>
/// <param name="worksheetName"></param>
/// <param name="skipHeaderRow">If set to true will skip the first row of data as header information</param>
/// <returns></returns>
List<T> ParseDocument<T>(Stream fileStream, string worksheetName, bool skipHeaderRow) where T : new();
}
34 changes: 29 additions & 5 deletions src/NetCore.Utilities.Spreadsheet/OpenXmlSpreadsheetParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ public class OpenXmlSpreadsheetParser : ISpreadsheetParser

/// <inheritdoc />
public List<T> ParseDocument<T>(Stream fileStream, int worksheetNumber, bool skipHeaderRow) where T : new()
{
return ParseDocumentInternal<T>(fileStream, worksheetNumber, string.Empty, skipHeaderRow);
}

/// <inheritdoc />
public List<T> ParseDocument<T>(Stream fileStream, string worksheetName, bool skipHeaderRow) where T : new()
{
return ParseDocumentInternal<T>(fileStream, null, worksheetName, skipHeaderRow);
}

private List<T> ParseDocumentInternal<T>(Stream fileStream, int? worksheetNumber, string worksheetName,
bool skipHeaderRow) where T : new()
{
//Validate object is properly created
var importColumnDefinitions = typeof(T)
Expand All @@ -49,13 +61,24 @@ public class OpenXmlSpreadsheetParser : ISpreadsheetParser
var workbookPart = excelDoc.WorkbookPart;
if (workbookPart == null) throw new SpreadsheetParserException("Spreadsheet has no WorkbookPart");

var sheet = workbookPart.Workbook.Descendants<Sheet>().Skip(worksheetNumber - 1).FirstOrDefault();
if (sheet == null) throw new SpreadsheetParserException($"Workbook does not have {worksheetNumber} sheets");
Sheet sheet;
if (worksheetNumber.HasValue)
{
sheet = workbookPart.Workbook.Descendants<Sheet>().Skip(worksheetNumber.Value - 1).FirstOrDefault();
if (sheet == null) throw new SpreadsheetParserException($"Workbook does not have {worksheetNumber} sheets");
}
else
{
sheet = workbookPart.Workbook.Descendants<Sheet>().First(s => s.Name == worksheetName);
if (sheet == null)
throw new SpreadsheetParserException($"Workbook does not have a sheet named '{worksheetName}'");
}

if (sheet.Id == null || !sheet.Id.HasValue || sheet.Id.Value == null) throw new SpreadsheetParserException($"Sheet {worksheetNumber} has a null Id");

if (workbookPart.GetPartById(sheet.Id.Value) is not WorksheetPart wsPart)
if (workbookPart.GetPartById(sheet.Id.Value) is not WorksheetPart wsPart)
throw new SpreadsheetParserException($"Sheet {worksheetNumber} with Id {sheet.Id.Value} is not in the workbook");

var collection = new Collection<T>();
var skipRows = skipHeaderRow ? 1 : 0;
var expectedColumns = importColumnDefinitions.Max(c => c.Column) - 1;
Expand Down Expand Up @@ -86,8 +109,9 @@ public class OpenXmlSpreadsheetParser : ISpreadsheetParser


return collection.ToList();

}


private static bool IsOfType<T>(Type t)
{
var typeToCheck = typeof(T);
Expand Down

0 comments on commit 34da96d

Please sign in to comment.