Export Class To Excel
Fri Aug 26 2022 07:14:42 GMT+0000 (UTC)
// The class: ExportHandler /// <summary> // Подава се лист от модели и генерира Xcel файл, като колоните се подреждат според реда на пропъртитата в класа /// Модела в листа трябва задължително да има атрибут (XcelHeader) със стойност за колоните, които ще се генерират // </summary> public static CheckResult SaveExcelByClass<T>(List<T> models, string sheetName) { var modelType = typeof(T); // типа на обекта var props = modelType.GetProperties().Where(x => Attribute.IsDefined(x, typeof(XcelHeaderAttribute))).ToList(); // всички пропъртита с атрибута if (props.Count == 0) // Ако няма нито един атрибут - излизаме { return CheckResult.Error("Липсват колони за ексел файла."); } string exportFileName = ""; // файла, където ще запазваме Xcel-а using (var dlg = new SaveFileDialog()) { dlg.DefaultExt = ".xlsx"; if (dlg.ShowDialog() != DialogResult.OK) { return CheckResult.Default; } exportFileName = dlg.FileName; } SplashScreenManager.ShowDefaultWaitForm("Експорт", "Данни"); // Показваме съобщение, че вършим работата JFileHelper.ExcelWork((book) => { var sheet = book.Worksheets[0]; // първия лист на ексела, който ще попълваме sheet.Name = sheetName; for (int i = 0; i < props.Count; i++) // въртим всички пропъртита, които сме извлекли от класа { var currentProp = props[i]; // текущото пропърти // атрибута закачен за пропъртито var attr = (XcelHeaderAttribute)currentProp .GetCustomAttributes(typeof(XcelHeaderAttribute), false) .FirstOrDefault(); // извличаме всички стойности на пропъртито от листа и взимаме дължината на най-дългата стойност в него var maxLengthFromAllProps = models.Select(x => x.GetType().GetProperties().Where(x => x.Name == currentProp.Name) .Select(y => y.GetValue(x)).FirstOrDefault()?.ToString()?.Length) .Max(); // 13 е по дефолт, за да не са сплескани клетките. Ако дължината е по-голяма, взимаме нея + 2, за да има отстъп var columnWidth = (maxLengthFromAllProps.HasValue && maxLengthFromAllProps.Value > 13) ? maxLengthFromAllProps.Value + 2 : 13; var column = ((char)(65 + i)).ToString(); // Взимаме името на колоната (А,B,C,D...) sheet.Columns[column].ColumnWidthInCharacters = columnWidth; // Сетваме дължината на колоната var colCell = sheet.Cells[0, i]; colCell.Value = attr.HeaderName; // Слагаме хедъра на ексела colCell.FillColor = Color.LightBlue; // Цвета на клетката colCell.Alignment.WrapText = true; // да се чупи на нов ред ако не се събира в клетката, а не да изчезва colCell.Borders.SetAllBorders(Color.Black, BorderLineStyle.Thin); sheet.AutoFilter.Apply(sheet[$"{column}1"]); // Слагаме филтър на всяка една колона // Въртим всички модели и взимаме стойностите на пропъртитата за текущата колона, която правим for (int j = 0; j < models.Count; j++) { var row = models[j]; var propValue = currentProp.GetValue(row); var rowCell = sheet.Cells[j + 1, i]; rowCell.Value = propValue?.ToString(); rowCell.Borders.SetAllBorders(Color.Black, BorderLineStyle.Thin); } } SplashScreenManager.CloseDefaultSplashScreen(); book.SaveAndAskShow(exportFileName); }); return CheckResult.Default; } // JFileHelper.ExcelWork: public static void ExcelWork(Action<Workbook> book) { using (Workbook excel = new Workbook()) { book(excel); } } // The book extension public static void SaveAndAskShow(this Workbook book, string filePath) { book.SaveDocument(filePath); book.Dispose(); Mess.boxConfirm("Желаете ли да отворите файла?", () => { ProcessStartInfo info = new ProcessStartInfo(filePath); info.UseShellExecute = true; Process.Start(info); }); } // Example Model public class HonorariumBM { public int AcodeID { get; set; } public string Acode { get; set; } public int AcodePos { get; set; } public string Acodename { get; set; } [XcelHeader("ID доктор")] public int doctorid { get; set; } [XcelHeader("Имена")] public string doctor_name { get; set; } public int serviceid { get; set; } public int external_code { get; set; } [XcelHeader("Име на услугата")] public string service_or_cp_name { get; set; } [XcelHeader("Твърда сума")] public decimal hard_price { get; set; } [XcelHeader("Процент")] public decimal percent { get; set; } public decimal cost_price { get; set; } [XcelHeader("юрид. лице")] public int hospitalinfoid { get; set; } public bool IsNew { get; set; } public bool IsEdit { get; set; } public bool IsDelete { get; set; } } // Attribute public class XcelHeaderAttribute : Attribute { public XcelHeaderAttribute(string headerName) { this.HeaderName = headerName; } public string HeaderName { get; set; } }
Comments