Last active
March 13, 2022 02:21
-
-
Save fiddyschmitt/3929e6305814088e3b9f5f0790c7e96f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var columnFilters = new[] | |
{ | |
new {SheetName = "Sheet1", ColumnName = "FirstName", Values = new [] { "Bob", "John"}}, | |
new {SheetName = "Sheet1", ColumnName = "Age", Values = new [] { 30"}}, | |
}.ToList(); | |
//Apply filters | |
using (var pck = new ExcelPackage(new FileInfo(parametricsLogFilename))) | |
{ | |
columnFilters.ForEach(columnFilter => | |
{ | |
//Find the worksheet | |
var worksheet = pck.Workbook.Worksheets.FirstOrDefault(sheet => sheet.Name.Equals(columnFilter.SheetName)); | |
if (worksheet == null) return; | |
//Get the column names | |
var columnInfos = worksheet | |
.Cells[worksheet.Dimension.Start.Row, worksheet.Dimension.Start.Column, 1, worksheet.Dimension.End.Column] | |
.Select((cell, index) => new | |
{ | |
ColumnCell = cell, | |
Index = index | |
}) | |
.ToList(); | |
//Find the column | |
var columnInfo = columnInfos.FirstOrDefault(info => info.ColumnCell.Value.Equals(columnFilter.ColumnName)); | |
if (columnInfo == null) return; | |
//Get reference to the worksheet xml for proper namespace | |
var xdoc = worksheet.WorksheetXml; | |
var nsm = new XmlNamespaceManager(xdoc.NameTable); | |
nsm.AddNamespace("default", xdoc.DocumentElement.NamespaceURI); | |
//Create the filters themselves | |
var filterNodes = columnFilter.Values.Select(filterValue => | |
{ | |
var filterNode = xdoc.CreateNode(XmlNodeType.Element, "filter", xdoc.DocumentElement.NamespaceURI); | |
var filterAtt = xdoc.CreateAttribute("val"); | |
filterAtt.Value = filterValue; | |
filterNode.Attributes.Append(filterAtt); | |
return filterNode; | |
}) | |
.ToList(); | |
//Add filters to the collection | |
var filtersNode = xdoc.CreateNode(XmlNodeType.Element, "filters", xdoc.DocumentElement.NamespaceURI); | |
filterNodes.ForEach(filterNode => | |
{ | |
filtersNode.AppendChild(filterNode); | |
}); | |
//Create the parent filter container | |
var filterColumnNode = xdoc.CreateNode(XmlNodeType.Element, "filterColumn", xdoc.DocumentElement.NamespaceURI); | |
var att = xdoc.CreateAttribute("colId"); | |
att.Value = $"{columnInfo.Index}"; | |
filterColumnNode.Attributes.Append(att); | |
filterColumnNode.AppendChild(filtersNode); | |
//Now add it to the autoFilters node | |
var autoFilter = xdoc.SelectSingleNode("/default:worksheet/default:autoFilter", nsm); | |
autoFilter.AppendChild(filterColumnNode); | |
//Get a list of cells in the column. We can't just iterate over worksheet.Cells because if a column is completely blank, the IEnumerable is empty | |
var rawCellsInColumn = (object[,])worksheet.Cells[worksheet.Dimension.Start.Row, columnInfo.Index + 1, worksheet.Dimension.End.Row, columnInfo.Index + 1].Value; | |
var cellsInColumn = new List<(int RowNumber, object Value)>(); | |
for (int rowNumber = 0; rowNumber < rawCellsInColumn.GetLength(0); rowNumber++) | |
{ | |
cellsInColumn.Add((rowNumber, rawCellsInColumn[rowNumber, 0])); | |
} | |
//Have to manually hide rows based on criteria | |
var rowsToHide = cellsInColumn | |
.Skip(1) | |
.Where(cell => cell.Value == null || !columnFilter.Values.Contains(cell.Value)) | |
.ToList(); | |
rowsToHide | |
.ForEach(cell => worksheet.Row(cell.RowNumber + 1).Hidden = true); | |
}); | |
pck.Save(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment