Как загрузить отчет в формате PDF используя FastReport Core

18.09.2017

В этой статье мы продолжим тему “FastReport Core + .Net Core”. В предыдущей статье мы рассмотрели, как отображать отчет с помощью экспорта в формат html. Теперь я покажу, как организовать загрузку отчета из браузера на локальный компьютер с помощью кнопки. В качестве конечного файла мы будет использовать экспорт в PDF (можно и любой другой). На этот раз мы будем использовать базу данных SQLite.

Создаем проект ASP .Net Core Web Application. Подключаем библиотеки:

FastReport Core, Microsoft.EntitiyFrameworkCore.Sqlite, Microsoft.EntitiyFrameworkCore.Sqlite.Design. В итоге вы должны иметь следующие установленные пакеты:

Давайте предварительно поработаем с данными. Нам потребуется база данных SQLite – fastreport.db. Ее можно взять в демонстрационном проекте «С:\Program Files (x86)\FastReports\FastReport.Net\Demos\Core\FastReportCore.MVC». Добавляем базу данных прямо в корень проекта. Также, добавим в проект шаблон отчета “Simple List.frx” из папки «С:\Program Files (x86)\FastReports\FastReport.Net\Demos\Reports»

Теперь, в папку Models добавим новый класс. Назовем его ApplicationDbContext.cs. Как вы поняли из названия – это контекст данных. Вот его содержание:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using Microsoft.EntityFrameworkCore;
using System;
using System.Data;
using System.Reflection;
 
namespace FRCore
{
 public class ApplicationDbContext : DbContext
 {
 public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
 : base(options)
 { }
 
 public ApplicationDbContext()
 {
 
 }
 
 public DbSet<Employees> Employees { get; set; }
 
//Получаем набор данных
 public DataSet GetDataSet(string name)
 {
 DataSet set = new DataSet(name);
 set.Tables.Add(GetTable(Employees, "Employees"));
 return set;
 }
 
//Задаем первичный ключ
 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
 modelBuilder.Entity<Employees>(entity =>
 {
 entity.HasKey(e => e.EmployeeId)
 .HasName("sqlite_autoindex_employees_1");
 });
 }
 
//Задаем источник данных
 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
 optionsBuilder.UseSqlite(@"data source= fastreport.db");
 }
 
//Получаем таблицу нужную для формироания отчета. По сути метод преобразования IQuerable в DataTable
 static DataTable GetTable<TEntity>(DbSet<TEntity> table, string name) where TEntity : class
 {
 DataTable result = new DataTable(name);
 PropertyInfo[] infos = typeof(TEntity).GetProperties();
 foreach (PropertyInfo info in infos)
 {
 if (info.PropertyType.IsGenericType
 && info.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
 result.Columns.Add(new DataColumn(info.Name, Nullable.GetUnderlyingType(info.PropertyType)));
 else
 result.Columns.Add(new DataColumn(info.Name, info.PropertyType));
 }
 foreach (var el in table)
 {
 DataRow row = result.NewRow();
 foreach (PropertyInfo info in infos)
 if (info.PropertyType.IsGenericType
 && info.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
 {
 object t = info.GetValue(el);
 if (t == null)
 t = Activator.CreateInstance(Nullable.GetUnderlyingType(info.PropertyType));
 row[info.Name] = t;
 }
 else
 row[info.Name] = info.GetValue(el);
 result.Rows.Add(row);
 }
 return result;
 }
 }
 
//Модель таблицы Employees
 public class Employees
 {
 public int EmployeeID { get; set; }
 public int EmployeeId { get; set; }
 public string LastName { get; set; }
 public string FirstName { get; set; }
 public string Title { get; set; }
 public string TitleOfCourtesy { get; set; }
 public System.DateTime? BirthDate { get; set; }
 public System.DateTime? HireDate { get; set; }
 public string Address { get; set; }
 public string City { get; set; }
 public string Region { get; set; }
 public string PostalCode { get; set; }
 public string Country { get; set; }
 public string HomePhone { get; set; }
 public string Extension { get; set; }
 public byte[] Photo { get; set; }
 public string Notes { get; set; }
 public int? ReportsTo { get; set; }
 }
}

В этом классе мы соединяемся с базой данных, получаем набор данных и преобразовываем его в DataTable, которая нужна для FastReport чтобы сгенерировать отчет. Модель таблицы Employees, которая будет использована в отчете, представлена отдельным классом.

Переходим к редактированию HomeController.cs. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using FRCore.Models;
using FastReport;
using FastReport.Export.Html;
using System.IO;
using System.Text;
using FastReport.Export.Pdf;
using System.Data;
 
namespace FRCore.Controllers
{
 public class HomeController : Controller
 {
 public Report report = new Report();
 
 private ApplicationDbContext _context = new ApplicationDbContext();
 
 public ApplicationDbContext GetContext()
 {
 return _context;
 }
 
 public IActionResult Index()
 {
 DataSet dataSet = new DataSet();
 dataSet = GetContext().GetDataSet("NorthWind");
 report.Report.RegisterData(dataSet, "NorthWind");
 report.Report.Load("Simple List.frx");
 report.Prepare();
 
 HTMLExport export = new HTMLExport();
 export.Layers = true;
 using (MemoryStream ms = new MemoryStream())
 {
 export.EmbedPictures = true;
 export.Export(report, ms);
 ms.Flush();
 ViewData["Report"] = Encoding.UTF8.GetString(ms.ToArray());
 ViewData["ReportName"] = "Simple List.frx";
 }
 return View();
 }
 
 public IActionResult Pdf()
 {
 System.Data.DataSet dataSet = new System.Data.DataSet();
 dataSet = GetContext().GetDataSet("NorthWind");
 report.Report.RegisterData(dataSet, "NorthWind");
 report.Report.Load("Simple List.frx");
 report.Prepare();
 
 PDFExport export = new PDFExport();
 using (MemoryStream ms = new MemoryStream())
 {
 export.Export(report, ms);
 ms.Flush();
 return File(ms.ToArray(), "application/pdf", Path.GetFileNameWithoutExtension("Simple List") + ".pdf");
 }
 }
 }
}

Метод Index просто отображает отчет в формате html, а метод PDF – формирует PDF файл для загрузки. Оба метода используют контекст данных для отчета.

Теперь изменим представление Index.cshtml:

1
2
3
4
5
6
7
8
9
10
11
@{
 ViewData["Title"] = "Home Page";
}
@if (ViewData.ContainsKey("ReportName"))
{
 <a class="btn btn-danger" asp-controller="Home" asp-action="Pdf" asp-route-report="@ViewData["ReportName"]">Download PDF</a>
}
@if (ViewData.ContainsKey("Report"))
{
 @Html.Raw(ViewData["Report"])
}

Мы добавили кнопку загрузки PDF сначала. Затем – отображаем отчет.

Запустим наше приложение:

Нажимаем кнопку «Download PDF». И скачиваем файл отчета в формате PDF. Реализация довольно проста, не сложнее чем отобразить отчет.

.NET FastReport Core .NET FastReport Core
10 июля 2026

Как настроить Content Security Policy для отчетов FastReport .NET WEB

Узнайте, как настроить Content Security Policy для отчётов FastReport .NET WEB: обзор директив и значений CSP, изменения в архитектуре FastReport, типичные сценарии обхода и способы защиты.
22 июня 2026

Как настроить отчет с Business Objects из кода и дизайнера в FastReport .NET

В этой статье рассматривается реальный пример создания и использования шаблона отчета .frx для подключения к иерархическим бизнес-объектам в FastReport .NET.
21 апреля 2026

Использование водяных знаков в FastReport VCL

В статье подробно рассмотрели функционал добавления водяных знаков в FastReport VCL — как через визуальный интерфейс, так и программно, с помощью кода на Delphi и в скриптах отчётов.

Не является публичной офертой
© 1998-2026 ООО «Быстрые отчеты»