using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Office.Interop.Excel; using System.Reflection; namespace Components.LogicalComponents { public partial class ExcelTableComponent : Component { public ExcelTableComponent() { InitializeComponent(); } public ExcelTableComponent(IContainer container) { container.Add(this); InitializeComponent(); } private string GetExcelColumnName(int columnNumber) { string columnName = ""; while (columnNumber > 0) { int modulo = (columnNumber - 1) % 26; columnName = Convert.ToChar('A' + modulo) + columnName; columnNumber = (columnNumber - modulo) / 26; } return columnName; } public bool createWithTable(string path, string title, List<(int, int)> merges, List heights, List<(string, string)> headers, List items) { if (merges.Count == 0 || heights.Count == 0 || headers.Count == 0 || items.Count == 0) throw new ArgumentException("Недостаточно данных"); int[] cellsArray = new int[heights.Count]; foreach (var merge in merges) { if (merge.Item1 >= merge.Item2) throw new ArgumentException("Неправильно заполнены объединения строк"); for (int i = merge.Item1; i < merge.Item2; i++) { cellsArray[i]++; } } foreach (int cell in cellsArray) { if (cell > 1) throw new ArgumentException("Объединения заходят друг на друга"); } var excelApp = new Microsoft.Office.Interop.Excel.Application { SheetsInNewWorkbook = 1 }; Workbook workbook = excelApp.Workbooks.Add(Type.Missing); try { //create Worksheet worksheet = (Worksheet)workbook.Worksheets.get_Item(1); //header var excelcells = worksheet.get_Range("A1", "A1"); excelcells.Font.Bold = true; excelcells.Font.Size = 14; excelcells.Font.Name = "Times New Roman"; excelcells.ColumnWidth = 8; excelcells.RowHeight = 25; excelcells.HorizontalAlignment = Constants.xlCenter; excelcells.VerticalAlignment = Constants.xlCenter; excelcells.Value2 = title; //checks List ranges = new List(); foreach (var merge in merges) { ranges.Add(worksheet.get_Range("A" + (merge.Item1 + 2), "A" + (merge.Item2 + 2))); } int rangeIndex = 0; int headerIndex = 0; List cellFields = new List(); var type = typeof(T); for (int i = 0; i < heights.Count; i++) { if (cellsArray[i] == 1) { //work with merge if (!string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают"); var groupRange = ranges[rangeIndex]; groupRange.Merge(Type.Missing); groupRange.Font.Bold = true; groupRange.Font.Size = 14; groupRange.Font.Name = "Times New Roman"; groupRange.ColumnWidth = 20; groupRange.HorizontalAlignment = Constants.xlCenter; groupRange.VerticalAlignment = Constants.xlCenter; groupRange.Value2 = headers[headerIndex].Item2; headerIndex++; //work with cells in merge for (; i <= merges[rangeIndex].Item2; i++) { //work with cell if (string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают"); var field = type.GetField(headers[headerIndex].Item1); if (field == null) throw new ArgumentException("В заголовках указано поле, которого нет в переданном классе"); //format header var range = worksheet.get_Range("B" + (i + 2), "B" + (i + 2)); range.Font.Bold = true; range.Font.Size = 14; range.Font.Name = "Times New Roman"; range.ColumnWidth = 20; range.RowHeight = heights[i]; range.HorizontalAlignment = Constants.xlCenter; range.VerticalAlignment = Constants.xlCenter; range.Value2 = headers[headerIndex].Item2; cellFields.Add(field); headerIndex++; } i--; rangeIndex++; } else { //work with cell if (string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают"); var field = type.GetField(headers[headerIndex].Item1); if (field == null) throw new ArgumentException("В заголовках указано поле, которого нет в переданном классе"); //format header var range = worksheet.get_Range("A" + (i + 2), "B" + (i + 2)); range.Merge(Type.Missing); range.Font.Bold = true; range.Font.Size = 14; range.Font.Name = "Times New Roman"; range.ColumnWidth = 40; range.RowHeight = heights[i]; range.HorizontalAlignment = Constants.xlCenter; range.VerticalAlignment = Constants.xlCenter; range.Value2 = headers[headerIndex].Item2; cellFields.Add(field); headerIndex++; } } int columnNum = 3; foreach (T item in items) { string column = GetExcelColumnName(columnNum); int rowNum = 2; foreach (var cellField in cellFields) { var range = worksheet.get_Range(column + rowNum, column + rowNum); range.Font.Size = 14; range.Font.Name = "Times New Roman"; range.ColumnWidth = 20; range.HorizontalAlignment = Constants.xlCenter; range.VerticalAlignment = Constants.xlCenter; range.Value2 = cellField.FieldType == typeof(bool) ? ((bool)cellField.GetValue(item) ? "Да" : "Нет") : cellField.GetValue(item); rowNum++; } columnNum++; } var borderRange = worksheet.get_Range("A2", GetExcelColumnName(columnNum - 1) + (headerIndex - 1)); borderRange.Borders.LineStyle = XlLineStyle.xlContinuous; borderRange.Borders.Weight = 2d; //save object missing = System.Reflection.Missing.Value; workbook.SaveAs(path, XlFileFormat.xlOpenXMLWorkbook, missing, missing, false, false, XlSaveAsAccessMode.xlNoChange, XlSaveConflictResolution.xlUserResolution, true, missing, missing, missing); workbook.Close(); excelApp.Quit(); return true; } catch (Exception ex) { workbook.Close(); excelApp.Quit(); throw; } } } }