Ignorare le properties; quando si chiama LoadFromCollection in EPPlus

Sto cercando di generare un file Excel utilizzando il seguente codice:

public static Stream GenerateFileFromClass<T>(IEnumerable<T> collection, int startrow, int startcolumn, byte[]templateResource) { using (Stream template = new MemoryStream(templateResource))//this is an excel file I am using for a base/template { using (var tmpl = new ExcelPackage(template)) { ExcelWorkbook wb = tmpl.Workbook; if (wb != null) { if (wb.Worksheets.Count > 0) { ExcelWorksheet ws = wb.Worksheets.First(); ws.Cells[startrow, startcolumn].LoadFromCollection<T>(collection, false); } return new MemoryStream(tmpl.GetAsByteArray()); } else { throw new ArgumentException("Unable to load template WorkBook"); } } } } 

Questo funziona come un trattamento, però .. Voglio ignorare un paio di properties; della mia collezione di classi, in modo che corrisponda al mio model. So che LoadFromCollection genererà colonne nel file Excel in base alle properties; pubbliche della class, ma mentre sto caricando la class usando Entity Framework, se contrassegno il field come privato, EF si lamenta – per lo più perché uno dei campi Non voglio mostrare è la chiave.

Ho cercato di contrassegnare le properties; che non voglio utilizzare [XmlIgnore] , senza alcun risultato. C'è un modo per farlo, a less che non carichi l'intera collezione in un set di dati o in un altro e ne taglia le colonne? O il casting a una class di base senza le properties; che non ho bisogno?

Sì, EPPlus fornisce un sovraccarico del .LoadFromCollection<T>() con un parametro MemberInfo[] per le properties; che si desidera includere.

Ci dà tutto ciò che dobbiamo ignorare qualsiasi properties; con un determinato attributo.

Ad esempio, se vogliamo ignorare le properties; con questo attributo personalizzato:

 public class EpplusIgnore : Attribute { } 

allora possiamo scrivere un piccolo metodo di estensione per prima trovare tutti gli oggetti MemberInfo per le properties; senza l'attributo [EpplusIgnore] quindi restituire il risultato del corretto overload del metodo .LoadFromCollection nel dll EPPlus.

Qualcosa come questo:

 public static class Extensions { public static ExcelRangeBase LoadFromCollectionFiltered<T>(this ExcelRangeBase @this, IEnumerable<T> collection) where T:class { MemberInfo[] membersToInclude = typeof(T) .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p=>!Attribute.IsDefined(p,typeof(EpplusIgnore))) .ToArray(); return @this.LoadFromCollection<T>(collection, false, OfficeOpenXml.Table.TableStyles.None, BindingFlags.Instance | BindingFlags.Public, membersToInclude); } } 

Così, per esempio, usando come questo ignorerà la properties; .Key quando esport una collezione Person per eccellere:

 public class Person { [EpplusIgnore] public int Key { get; set; } public string Name { get; set; } public int Age { get; set; } } class Program { static void Main(string[] args) { var demoData = new List<Person> { new Person { Key = 1, Age = 40, Name = "Fred" }, new Person { Key = 2, Name = "Eve", Age = 21 } }; FileInfo fInfo = new FileInfo(@"C:\Temp\Book1.xlsx"); using (var excel = new ExcelPackage()) { var ws = excel.Workbook.Worksheets.Add("People"); ws.Cells[1, 1].LoadFromCollectionFiltered(demoData); excel.SaveAs(fInfo); } } } 

Dando l'output che ci aspetteremmo:

immettere qui la descrizione dell'immagine

Grazie Stewart_R, basandomi sul tuo lavoro ho fatto una nuova che riceve i nomi delle properties;:

 public static ExcelRangeBase LoadFromCollection<T>(this ExcelRangeBase @this, IEnumerable<T> collection, string[] propertyNames, bool printHeaders) where T:class { MemberInfo[] membersToInclude = typeof(T) .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p=>propertyNames.Contains(p.Name)) .ToArray(); return @this.LoadFromCollection<T>(collection, printHeaders, OfficeOpenXml.Table.TableStyles.None, BindingFlags.Instance | BindingFlags.Public, membersToInclude); }