Пример #1
0
        public async Task <IActionResult> GetMonthlyReport(int managerId, DateTime date)
        {
            var report = await _reportService.GetMonthlyReportAsync(managerId, date);

            byte[] fileContents;

            using (var package = new ExcelPackage())
            {
                var worksheet = package.Workbook.Worksheets.Add("Часы");

                //Header
                var header = new List <string>()
                {
                    "№", "ФИО", "Ставка", "Норма часов", "Итого"
                };

                using (ExcelRange range = worksheet.Cells[1, 1, 1, header.Count])
                {
                    //формируется статическая шапка, задаются стили
                    range.LoadFromArrays(new List <string[]>(new[] { header.ToArray() }));
                    AddColorForRangeCells(range, Color.FromArgb(204, 204, 255));
                    range.Style.Font.Bold = true;
                    using (ExcelRange headerRange = worksheet.Cells[1, 3, 1, header.Count])
                    {
                        headerRange.Style.TextRotation = 90;
                    }
                }

                // к шапке добавляются проекты и типы отпусков работников
                for (int i = 0; i < report.Events.Count(); i++)
                {
                    var item = report.Events.ElementAt(i);
                    var cell = worksheet.Cells[1, header.Count + 1 + i];
                    cell.Value = item.Name;
                    cell.Style.TextRotation = 90;
                    cell.Style.Font.Bold    = true;
                    Color color;
                    // в зависимости от типа, назначается цвет
                    switch (item.EventType)
                    {
                    case EventType.ManagerProject:
                        color = Color.LightGreen;
                        break;

                    case EventType.NotManagerProject:
                        color = Color.FromArgb(255, 255, 204);
                        break;

                    case EventType.Vacation:
                        color = Color.FromArgb(255, 204, 0);
                        break;

                    case EventType.AnotherLeave:
                        color = Color.FromArgb(204, 153, 255);
                        break;

                    default:
                        color = Color.White;
                        break;
                    }
                    AddColorForRangeCells(cell, color);
                }

                //Header Two, формируется вторая шапка под первой, которая содержит суммы часов по проектам
                worksheet.Cells[2, 2].Value           = "Итого";
                worksheet.Cells[2, 2].Style.Font.Bold = true;
                using (ExcelRange range = worksheet.Cells[2, header.Count, 2, header.Count + report.Events.Count()])
                {
                    for (int column = 1; column <= range.Columns; column++)
                    {
                        var cell      = worksheet.Cells[range.Start.Row, column + header.Count - 1];
                        var startCell = cell.Start;
                        // формула для сложения все часов за элемент в шапке один (вертикальный столбец)
                        cell.Formula = $"SUM({worksheet.Cells[startCell.Row + 1, startCell.Column].Address}:{worksheet.Cells[startCell.Row + report.Users.Count(), startCell.Column].Address})";
                    }

                    range.Style.Font.Bold = true;
                }
                AddColorForRangeCells(worksheet, 2, 1, 2, header.Count + report.Events.Count(), Color.FromArgb(153, 204, 255));

                //Формирование списка пользователей
                var userIndex = 1;
                foreach (var user in report.Users)
                {
                    using (ExcelRange range = worksheet.Cells[2 + userIndex, 1, 3 + userIndex, header.Count + report.Events.Count()])
                    {
                        var row = new List <string>
                        {
                            userIndex.ToString(), $"{user.FirstName} {user.Surname}", user.Rate.ToString(CultureInfo.InvariantCulture), user.NormHours.ToString(CultureInfo.InvariantCulture)
                        };
                        range.LoadFromArrays(new List <string[]>(new[] { row.ToArray() }));
                        var currentCell = worksheet.Cells[2 + userIndex, 5];
                        currentCell.Formula = $"SUM({worksheet.Cells[2 + userIndex, currentCell.Start.Column + 1].Address}:{worksheet.Cells[2 + userIndex, range.End.Column].Address})";
                        currentCell.Style.Fill.PatternType = ExcelFillStyle.Solid;
                        currentCell.Style.Fill.BackgroundColor.SetColor(Color.FromArgb(204, 204, 255));

                        // проставляются часы по проектам в соответствующие ячейки
                        using (ExcelRange headerProjectRange = worksheet.Cells[1, header.Count + 1, 1, header.Count + report.Events.Count()])
                        {
                            foreach (var project in user.Projects)
                            {
                                var eventCell = headerProjectRange.FirstOrDefault(h => (string)h.Value == project.ProjectName);
                                if (eventCell == null)
                                {
                                    throw new Exception();
                                }

                                if (project.Hours > 0)
                                {
                                    worksheet.Cells[2 + userIndex, eventCell.Start.Column].Value = project.Hours;
                                }
                            }
                        }

                        // проставляются часы по отпускам в соответствующие ячейки
                        using (ExcelRange headerProjectRange = worksheet.Cells[1, header.Count + 1, 1, header.Count + report.Events.Count()])
                        {
                            foreach (var leave in user.Leaves)
                            {
                                var eventCell = headerProjectRange.FirstOrDefault(h => (string)h.Value == leave.Name);
                                if (eventCell == null)
                                {
                                    throw new Exception();
                                }

                                worksheet.Cells[2 + userIndex, eventCell.Start.Column].Value = leave.Hours;
                            }
                        }

                        userIndex++;
                    }
                }
                // стилизация ячеек с часами
                using (ExcelRange range = worksheet.Cells[3, header.Count + 1, 3 + report.Users.Count() - 1, header.Count + report.Events.Count()])
                {
                    AddColorForRangeCells(range, Color.FromArgb(204, 255, 204));
                }
                //общаяя стилизация листа
                using (ExcelRange range = worksheet.Cells[1, 1, report.Users.Count() + 2, report.Events.Count() + 5])
                {
                    range.Style.Border.Top.Style    = ExcelBorderStyle.Thin;
                    range.Style.Border.Left.Style   = ExcelBorderStyle.Thin;
                    range.Style.Border.Right.Style  = ExcelBorderStyle.Thin;
                    range.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
                    range.Style.Font.Size           = 10;
                }

                //атоподбор размеров ячеек
                worksheet.Cells.AutoFitColumns();

                fileContents = package.GetAsByteArray();
            }

            if (fileContents == null || fileContents.Length == 0)
            {
                return(NotFound());
            }

            return(File(fileContents, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"monthly_report_{date.Year}_{date.Month}.xlsx"));
        }