No mundo moderno de desenvolvimento de aplicativos, geralmente é necessário trabalhar com documentos do Excel. Na maioria das vezes, são vários tipos de relatórios, mas às vezes os arquivos xls / x são usados como armazenamento de dados. Por exemplo, se um usuário precisa ser capaz de carregar dados em um aplicativo ou carregá-los em um formato legível, o Excel é o padrão de fato. Interface relativamente amigável, estrutura transparente, juntamente com sua prevalência ... é difícil nomear uma solução melhor de imediato.
No entanto, muitas pessoas ainda associam o Excel a algo pesado, desajeitado e complexo. Vamos ver como nós, desenvolvedores C # comuns, podemos gerar facilmente um documento simples do Excel usando um relatório tabular como exemplo.
Referência histórica
Os dias em que o .xls (Formato de Arquivo Binário do Excel) proprietário dominava já se foi e agora só temos .xlsx (Pasta de Trabalho do Excel), dentro do Office Open XML. O último é um arquivo .zip regular com arquivos XML. Não vamos nos aprofundar em sua estrutura, espero sinceramente que você nunca precise dela.
github, , , . EPPlus. , Excel, EPPlus. 4 , 5‐ .
, , - , Excel - 100500%. - - — .
, . — . — , . , - backend- - , id . , id , .
, , - " excel MarketReport". , , — :

EPPlus 4.5.3.3 .
Generate. ExcelPackage , . .
main , Excel . .
, exception:InvalidOperationException: The workbook must contain at least one worksheet
, Excel , . , :
var sheet = package.Workbook.Worksheets
.Add("Market Report");... ! , , 2,5KB - Excel .
. Cells . , , - :
sheet.Cells["B2"].Value = "Company:";
sheet.Cells[2, 3].Value = report.Company.Name;.
sheet.Cells["B2"].Value = "Company:";
sheet.Cells[2, 3].Value = report.Company.Name;
sheet.Cells["B3"].Value = "Location:";
sheet.Cells["C3"].Value = $"{report.Company.Address}, " +
$"{report.Company.City}, " +
$"{report.Company.Country}";
sheet.Cells["B4"].Value = "Sector:";
sheet.Cells["C4"].Value = report.Company.Sector;
sheet.Cells["B5"].Value = report.Company.Description;History:
sheet.Cells[8, 2, 8, 4].LoadFromArrays(new object[][]{ new []{"Capitalization", "SharePrice", "Date"} });
var row = 9;
var column = 2;
foreach (var item in report.History)
{
sheet.Cells[row, column].Value = item.Capitalization;
sheet.Cells[row, column + 1].Value = item.SharePrice;
sheet.Cells[row, column + 2].Value = item.Date;
row++;
}LoadFromArrays, () . , object EPPlus ToString, .
, , .

-, , - ... , , " - " - .
, , , , , ... , backend , Excel Sheet!
. — , — . ?
- Excel, , . , ... , :
sheet.Cells[1, 1, row, column + 2].AutoFitColumns();
sheet.Column(2).Width = 14;
sheet.Column(3).Width = 12;, Style. 3- . , ...
sheet.Cells[9, 4, 9 + report.History.Length, 4].Style.Numberformat.Format = "yyyy";
sheet.Cells[9, 2, 9 + report.History.Length, 2].Style.Numberformat.Format = "### ### ### ##0";, . , EPPlus, — ExcelRange, , 1 .
sheet.Column(2).Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
sheet.Cells[8, 3, 8 + report.History.Length, 3].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;, Style.Font, , , 2- , , Excel:
sheet.Cells[8, 2, 8, 4].Style.Font.Bold = true;
sheet.Cells["B2:C4"].Style.Font.Bold = true;, . - - , ... ?
sheet.Cells[8, 2, 8 + report.History.Length, 4].Style.Border.BorderAround(ExcelBorderStyle.Double);
sheet.Cells[8, 2, 8, 4].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;" , , ?" - , , 9-...
, EPPlus API. , :
var capitalizationChart = sheet.Drawings.AddChart("FindingsChart", OfficeOpenXml.Drawing.Chart.eChartType.Line);
capitalizationChart.Title.Text = "Capitalization";
capitalizationChart.SetPosition(7, 0, 5, 0);
capitalizationChart.SetSize(800, 400);
var capitalizationData = (ExcelChartSerie)(capitalizationChart.Series.Add(sheet.Cells["B9:B28"], sheet.Cells["D9:D28"]));
capitalizationData.Header = report.Company.Currency;, :
sheet.Protection.IsProtected = true;O que diz a versão final do método Generate?
public byte[] Generate(MarketReport report)
{
var package = new ExcelPackage();
var sheet = package.Workbook.Worksheets
.Add("Market Report");
sheet.Cells["B2"].Value = "Company:";
sheet.Cells[2, 3].Value = report.Company.Name;
sheet.Cells["B3"].Value = "Location:";
sheet.Cells["C3"].Value = $"{report.Company.Address}, " +
$"{report.Company.City}, " +
$"{report.Company.Country}";
sheet.Cells["B4"].Value = "Sector:";
sheet.Cells["C4"].Value = report.Company.Sector;
sheet.Cells["B5"].Value = report.Company.Description;
sheet.Cells[8, 2, 8, 4].LoadFromArrays(new object[][]{ new []{"Capitalization", "SharePrice", "Date"} });
var row = 9;
var column = 2;
foreach (var item in report.History)
{
sheet.Cells[row, column].Value = item.Capitalization;
sheet.Cells[row, column + 1].Value = item.SharePrice;
sheet.Cells[row, column + 2].Value = item.Date;
row++;
}
sheet.Cells[1, 1, row, column + 2].AutoFitColumns();
sheet.Column(2).Width = 14;
sheet.Column(3).Width = 12;
sheet.Cells[9, 4, 9+ report.History.Length, 4].Style.Numberformat.Format = "yyyy";
sheet.Cells[9, 2, 9+ report.History.Length, 2].Style.Numberformat.Format = "### ### ### ##0";
sheet.Column(2).Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
sheet.Cells[8, 3, 8 + report.History.Length, 3].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
sheet.Column(4).Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
sheet.Cells[8, 2, 8, 4].Style.Font.Bold = true;
sheet.Cells["B2:C4"].Style.Font.Bold = true;
sheet.Cells[8, 2, 8 + report.History.Length, 4].Style.Border.BorderAround(ExcelBorderStyle.Double);
sheet.Cells[8, 2, 8, 4].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
var capitalizationChart = sheet.Drawings.AddChart("FindingsChart", OfficeOpenXml.Drawing.Chart.eChartType.Line);
capitalizationChart.Title.Text = "Capitalization";
capitalizationChart.SetPosition(7, 0, 5, 0);
capitalizationChart.SetSize(800, 400);
var capitalizationData = (ExcelChartSerie)(capitalizationChart.Series.Add(sheet.Cells["B9:B28"], sheet.Cells["D9:D28"]));
capitalizationData.Header = report.Company.Currency;
sheet.Protection.IsProtected = true;
return package.GetAsByteArray();
}Em primeiro lugar, em primeiro lugar, que conseguimos lidar com a tarefa com sucesso , ou seja, geramos nosso primeiro relatório em Excel, trabalhamos com estilos e até resolvemos alguns problemas relacionados.
Em segundo lugar, pode fazer sentido procurar um novo emprego, mas olhando para o futuro , eu não teria pressa com isso ... Se esta publicação obtiver 1+ visualizações, então na segunda parte falaremos sobre como você pode separar o estilo da lógica de preenchimento de dados , simplifica as manipulações de células e torna o código mais fácil de manter em geral.