using UniversityBusinessLogic.OfficePackage.Models; using UniversityContracts.ViewModels; using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; namespace CaseAccountingBusinessLogic.OfficePackage { public class ExcelBuilderProvider { private readonly string tempFileName = "temp.xlsx"; private SpreadsheetDocument? spreadsheetDocument; private SharedStringTablePart? shareStringPart; private Worksheet? worksheet; private void CreateStyles(WorkbookPart workbookpart) { var sp = workbookpart.AddNewPart(); sp.Stylesheet = new Stylesheet(); var fonts = new Fonts() { Count = 2U, KnownFonts = true }; var fontUsual = new Font(); fontUsual.Append(new FontSize() { Val = 12D }); fonts.Append(fontUsual); var fontTitle = new Font(); fontTitle.Append(new Bold()); fontTitle.Append(new FontSize() { Val = 12D }); fonts.Append(fontTitle); var fills = new Fills() { Count = 3U }; var fill1 = new Fill(); fill1.Append(new PatternFill() { PatternType = PatternValues.None }); var fill2 = new Fill(); fill2.Append(new PatternFill() { PatternType = PatternValues.Gray125 }); var fill3 = new Fill(); fill3.Append(new PatternFill() { PatternType = PatternValues.Solid, ForegroundColor = new() { Rgb = "e0e8ff" } }); var fill4 = new Fill(); fill1.Append(new PatternFill() { PatternType = PatternValues.None }); fills.Append(fill1); fills.Append(fill2); fills.Append(fill3); fills.Append(fill4); var borders = new Borders() { Count = 2U }; var borderNoBorder = new Border(); borderNoBorder.Append(new LeftBorder()); borderNoBorder.Append(new RightBorder()); borderNoBorder.Append(new TopBorder()); borderNoBorder.Append(new BottomBorder()); borderNoBorder.Append(new DiagonalBorder()); var borderThin = new Border(); var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin }; leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U }); var rightBorder = new RightBorder() { Style = BorderStyleValues.Thin }; rightBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U }); var topBorder = new TopBorder() { Style = BorderStyleValues.Thin }; topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U }); var bottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin }; bottomBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U }); borderThin.Append(leftBorder); borderThin.Append(rightBorder); borderThin.Append(topBorder); borderThin.Append(bottomBorder); borderThin.Append(new DiagonalBorder()); borders.Append(borderNoBorder); borders.Append(borderThin); CellFormats cellFormats = new() { Count = 4U }; CellFormat cellFormatEmpty = new() { FontId = 0U, FillId = 0U, BorderId = 1U, ApplyFont = true }; CellFormat cellFormatDefault = new() { FontId = 0U, FillId = 3U, BorderId = 1U, ApplyFont = true }; CellFormat cellFormatTitle = new() { FontId = 1U, FillId = 2U, BorderId = 1U, ApplyFont = true, ApplyBorder = true, Alignment = new Alignment() { Vertical = VerticalAlignmentValues.Center, Horizontal = HorizontalAlignmentValues.Center, WrapText = true } }; cellFormats.Append(cellFormatEmpty); cellFormats.Append(cellFormatDefault); cellFormats.Append(cellFormatTitle); sp.Stylesheet.Append(fonts); sp.Stylesheet.Append(fills); sp.Stylesheet.Append(borders); sp.Stylesheet.Append(cellFormats); } public void CreateDocument() { spreadsheetDocument = SpreadsheetDocument.Create(tempFileName, SpreadsheetDocumentType.Workbook); WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart(); workbookpart.Workbook = new Workbook(); CreateStyles(workbookpart); shareStringPart = spreadsheetDocument.WorkbookPart! .GetPartsOfType() .Any() ? spreadsheetDocument.WorkbookPart .GetPartsOfType() .First() : spreadsheetDocument.WorkbookPart .AddNewPart(); if (shareStringPart.SharedStringTable == null) { shareStringPart.SharedStringTable = new SharedStringTable(); } WorksheetPart worksheetPart = workbookpart.AddNewPart(); worksheetPart.Worksheet = new Worksheet(new SheetData()); Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets()); Sheet sheet = new() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Лист" }; sheets.Append(sheet); worksheet = worksheetPart.Worksheet; } public void InsertCellInWorksheet(ExcelCellData cellData) { if (worksheet == null || shareStringPart == null) { return; } var sheetData = worksheet.GetFirstChild(); if (sheetData == null) { return; } Row? row = sheetData.Elements() .Where(r => r.RowIndex! == cellData.RowIndex) .FirstOrDefault(); if (row == null) { row = new Row() { RowIndex = cellData.RowIndex }; sheetData.Append(row); } Cell? cell = row.Elements() .Where(c => c.CellReference!.Value == cellData.CellReference) .FirstOrDefault(); if (cell == null) { Cell? refCell = null; foreach (Cell rowCell in row.Elements()) { if (string.Compare(rowCell.CellReference!.Value, cellData.CellReference, true) > 0) { refCell = rowCell; break; } } var newCell = new Cell() { CellReference = cellData.CellReference }; row.InsertBefore(newCell, refCell); cell = newCell; } shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(cellData.Text))); shareStringPart.SharedStringTable.Save(); cell.CellValue = new CellValue((shareStringPart.SharedStringTable.Elements().Count() - 1).ToString()); cell.DataType = new EnumValue(CellValues.SharedString); cell.StyleIndex = cellData.StyleIndex; } private void MergeCells(ExcelMergeParameters excelParams) { if (worksheet == null) { return; } MergeCells mergeCells; if (worksheet.Elements().Any()) { mergeCells = worksheet.Elements().First(); } else { mergeCells = new MergeCells(); if (worksheet.Elements().Any()) { worksheet.InsertAfter(mergeCells, worksheet.Elements().First()); } else { worksheet.InsertAfter(mergeCells, worksheet.Elements().First()); } } var mergeCell = new MergeCell() { Reference = new StringValue(excelParams.Merge) }; mergeCells.Append(mergeCell); } private void Save() { if (spreadsheetDocument == null) { return; } spreadsheetDocument.WorkbookPart!.Workbook.Save(); spreadsheetDocument.Dispose(); } public byte[] GetFile() { Save(); byte[] file = File.ReadAllBytes(tempFileName); File.Delete(tempFileName); return file; } public void CreateTitle(string text) { MergeCells(new ExcelMergeParameters { CellFromName = "A1", CellToName = "B1" }); InsertCellInWorksheet(new ExcelCellData { ColumnName = "A", RowIndex = 1, Text = text, StyleIndex = 0 }); } public void CreateStudentsDisciplineTable(List data) { if (worksheet == null || shareStringPart == null) { return; } Columns columns = new(); Column columnA = new() { Min = 1, Max = 1, Width = 30, CustomWidth = true }; columns.Append(columnA); Column columnB = new() { Min = 2, Max = 2, Width = 30, CustomWidth = true }; columns.Append(columnB); worksheet.InsertAt(columns, 0); InsertCellInWorksheet(new ExcelCellData { ColumnName = "A", RowIndex = 2, Text = "Студент", StyleIndex = 2 }); InsertCellInWorksheet(new ExcelCellData { ColumnName = "B", RowIndex = 2, Text = "Дисциплина", StyleIndex = 2 }); uint currentRow = 3; foreach (ReportStudentsDisciplineViewModel student in data) { InsertCellInWorksheet(new ExcelCellData { ColumnName = "A", RowIndex = currentRow, Text = student.Student, StyleIndex = 1 }); InsertCellInWorksheet(new ExcelCellData { ColumnName = "B", RowIndex = currentRow, Text = "", StyleIndex = 1 }); currentRow++; foreach (string discipline in student.Disciplines) { InsertCellInWorksheet(new ExcelCellData { ColumnName = "A", RowIndex = currentRow, Text = "", StyleIndex = 1 }); InsertCellInWorksheet(new ExcelCellData { ColumnName = "B", RowIndex = currentRow, Text = discipline, StyleIndex = 1 }); currentRow++; } } } } }