Create Excel (XLSX) or PDF file in ASP.NET Core
The following live demos and code examples show how to use GemBox.Spreadsheet to create ASP.NET Core web applications that generate and download Excel and PDF files to your browser. The following example shows how you can create an ASP.NET Core MVC application that: The following example shows how you can create an ASP.NET Core Razor Pages application that: GemBox.Spreadsheet is licensed per individual developer, and the licenses include a royalty-free deployment. You can feel free to build an unlimited number of applications and deploy or distribute them to an unlimited number of services, servers, or end-user machines with no extra cost. GemBox.Spreadsheet licenses are compatible with SaaS or PaaS solutions, as long as they don't offer similar or competing functionality to our component, or expose our features through an API for use by an unlicensed third party. For more information, please check the EULA. GemBox.Spreadsheet supports saving to XPS and image formats (like PNG and JPG) on applications that target .NET 6.0 or above. However, these features currently work only on Windows. In other words, besides .NET Core Runtime, you also need a .NET Windows Desktop Runtime installed on the server. To export an XPS or image file in an ASP.NET Core application, you need to use a Windows-specific TFM in the project file. Also, enable the following compatibility switch with the Or you can enable that compatibility switch by adding the following runtimeconfig.template.json file to your project. You can use the full functionality of GemBox.Spreadsheet on Unix systems, but with the following exceptions: These features currently have WPF dependencies which means they require a .NET Windows Desktop Runtime. However, we do have plans for providing cross-platform support for them in future releases.Create Excel or PDF files in ASP.NET Core MVC
FileStreamResult
.@model ReportModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GemBox.Spreadsheet in ASP.NET Core MVC application</title>
<link rel="icon" href="~/favicon.ico" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-controller="Home" asp-action="Index">Home</a>
</div>
</nav>
</header>
<div class="container">
<main class="pb-3 row">
<h1 class="display-4 p-3">Report generator [Razor View]</h1>
<div class="col-lg-6">
<form asp-action="Download">
<table class="table-sm table-bordered">
<thead class="text-center">
<tr>
<th>Id</th>
<th>Name</th>
<th>Salary [$]</th>
</tr>
</thead>
<tbody>
@for (int index = 0; index < Model.Items.Count; index++)
{
<tr>
<td><input asp-for="Items[index].Id" class="form-control" readonly /></td>
<td><input asp-for="Items[index].Name" class="form-control" /></td>
<td><input asp-for="Items[index].Salary" class="form-control" /></td>
</tr>
}
</tbody>
</table>
<div class="form-group">
Format:
<div class="row">
@foreach (string format in Model.FormatMappingDictionary.Select(item => item.Key))
{
<div class="col-3">
<div class="form-check form-check-inline">
<input asp-for="Format" class="form-check-input" type="radio" id="@format" value="@format">
<label for="@format" class="form-check-label">@format</label>
</div>
</div>
}
</div>
</div>
<div class="form-group"><input type="submit" value="Create" class="btn btn-primary" /></div>
</form>
</div>
</main>
</div>
<footer class="footer border-top text-muted">
<div class="container">© GemBox Ltd. — All rights reserved.</div>
</footer>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Microsoft.AspNetCore.Mvc;
using SpreadsheetCoreMvc.Models;
using GemBox.Spreadsheet;
namespace SpreadsheetCoreMvc.Controllers
{
public class HomeController : Controller
{
static HomeController()
{
// If using the Professional version, put your serial key below.
SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");
}
public IActionResult Index()
{
return View(new ReportModel());
}
public FileStreamResult Download(ReportModel model)
{
// Create new spreadsheet.
var workbook = new ExcelFile();
var worksheet = workbook.Worksheets.Add("Report");
// Set styles on rows and columns.
worksheet.Rows[0].Style.HorizontalAlignment = HorizontalAlignmentStyle.Center;
worksheet.Rows[0].Style.Font.Weight = ExcelFont.BoldWeight;
worksheet.Columns[0].SetWidth(40, LengthUnit.Pixel);
worksheet.Columns[1].SetWidth(100, LengthUnit.Pixel);
worksheet.Columns[2].SetWidth(100, LengthUnit.Pixel);
worksheet.Columns[2].Style.NumberFormat = @"\$\ #,##0";
// Create header row.
worksheet.Cells["A1"].Value = nameof(ReportItemModel.Id);
worksheet.Cells["B1"].Value = nameof(ReportItemModel.Name);
worksheet.Cells["C1"].Value = nameof(ReportItemModel.Salary);
// Create data rows.
for (int r = 1; r <= model.Items.Count; r++)
{
ReportItemModel item = model.Items[r - 1];
worksheet.Cells[r, 0].Value = item.Id;
worksheet.Cells[r, 1].Value = item.Name;
worksheet.Cells[r, 2].Value = item.Salary;
}
// Save spreadsheet in specified file format.
var stream = new MemoryStream();
workbook.Save(stream, model.Options);
// Download file.
return File(stream, model.Options.ContentType, $"OutputFromView.{model.Format.ToLower()}");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel() { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
namespace SpreadsheetCoreMvc.Models
{
public class ReportModel
{
public IList<ReportItemModel> Items { get; set; } = new List<ReportItemModel>()
{
new ReportItemModel() { Id = 100, Name = "John Doe", Salary = 3600 },
new ReportItemModel() { Id = 101, Name = "Jane Doe", Salary = 7200 },
new ReportItemModel() { Id = 102, Name = "Fred Nurk", Salary = 2580 },
new ReportItemModel() { Id = 103, Name = "Hans Meier", Salary = 3200 },
new ReportItemModel() { Id = 104, Name = "Ivan Horvat", Salary = 4100 },
new ReportItemModel() { Id = 105, Name = "Jean Dupont", Salary = 6850 },
new ReportItemModel() { Id = 106, Name = "Mario Rossi", Salary = 4400 }
};
public string Format { get; set; } = "XLSX";
public SaveOptions Options => this.FormatMappingDictionary[this.Format];
public IDictionary<string, SaveOptions> FormatMappingDictionary => new Dictionary<string, SaveOptions>()
{
["XLSX"] = new XlsxSaveOptions(),
["XLS"] = new XlsSaveOptions(),
["ODS"] = new OdsSaveOptions(),
["CSV"] = new CsvSaveOptions(CsvType.CommaDelimited),
["PDF"] = new PdfSaveOptions(),
["HTML"] = new HtmlSaveOptions() { EmbedImages = true },
["XPS"] = new XpsSaveOptions(),
["BMP"] = new ImageSaveOptions(ImageSaveFormat.Bmp),
["PNG"] = new ImageSaveOptions(ImageSaveFormat.Png),
["JPG"] = new ImageSaveOptions(ImageSaveFormat.Jpeg),
["GIF"] = new ImageSaveOptions(ImageSaveFormat.Gif),
["TIF"] = new ImageSaveOptions(ImageSaveFormat.Tiff)
};
}
public class ReportItemModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
}
}
Create Excel or PDF files in ASP.NET Core Razor Pages
FileContentResult
.@page
@model IndexModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GemBox.Spreadsheet in ASP.NET Core Razor Pages application</title>
<link rel="icon" href="~/favicon.ico" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-page="/Index">Home</a>
</div>
</nav>
</header>
<div class="container">
<main class="pb-3 row">
<h1 class="display-4 p-3">Report generator [Razor Page]</h1>
<div class="col-lg-6">
<form method="post">
<table class="table-sm table-bordered">
<thead class="text-center">
<tr>
<th>Id</th>
<th>Name</th>
<th>Salary [$]</th>
</tr>
</thead>
<tbody>
@for (int index = 0; index < Model.Report.Items.Count; index++)
{
<tr>
<td><input asp-for="Report.Items[index].Id" class="form-control" readonly /></td>
<td><input asp-for="Report.Items[index].Name" class="form-control" /></td>
<td><input asp-for="Report.Items[index].Salary" class="form-control" /></td>
</tr>
}
</tbody>
</table>
<div class="form-group">
Format:
<div class="row">
@foreach (string format in Model.Report.FormatMappingDictionary.Select(item => item.Key))
{
<div class="col-3">
<div class="form-check form-check-inline">
<input asp-for="Report.Format" class="form-check-input" type="radio" id="@format" value="@format">
<label for="@format" class="form-check-label">@format</label>
</div>
</div>
}
</div>
</div>
<div class="form-group"><input type="submit" value="Create" class="btn btn-primary" /></div>
</form>
</div>
</main>
</div>
<footer class="footer border-top text-muted">
<div class="container">© GemBox Ltd. — All rights reserved.</div>
</footer>
</body>
</html>
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using SpreadsheetCorePages.Models;
using GemBox.Spreadsheet;
namespace SpreadsheetCorePages.Pages
{
public class IndexModel : PageModel
{
[BindProperty]
public ReportModel Report { get; set; }
public IndexModel()
{
this.Report = new ReportModel();
// If using the Professional version, put your serial key below.
SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");
}
public void OnGet() { }
public FileContentResult OnPost()
{
// Create new spreadsheet.
var workbook = new ExcelFile();
var worksheet = workbook.Worksheets.Add("Report");
// Set styles on rows and columns.
worksheet.Rows[0].Style.HorizontalAlignment = HorizontalAlignmentStyle.Center;
worksheet.Rows[0].Style.Font.Weight = ExcelFont.BoldWeight;
worksheet.Columns[0].SetWidth(40, LengthUnit.Pixel);
worksheet.Columns[1].SetWidth(100, LengthUnit.Pixel);
worksheet.Columns[2].SetWidth(100, LengthUnit.Pixel);
worksheet.Columns[2].Style.NumberFormat = @"\$\ #,##0";
// Create header row.
worksheet.Cells["A1"].Value = nameof(ReportItemModel.Id);
worksheet.Cells["B1"].Value = nameof(ReportItemModel.Name);
worksheet.Cells["C1"].Value = nameof(ReportItemModel.Salary);
// Create data rows.
for (int r = 1; r <= this.Report.Items.Count; r++)
{
ReportItemModel item = this.Report.Items[r - 1];
worksheet.Cells[r, 0].Value = item.Id;
worksheet.Cells[r, 1].Value = item.Name;
worksheet.Cells[r, 2].Value = item.Salary;
}
// Save spreadsheet in specified file format.
var stream = new MemoryStream();
workbook.Save(stream, this.Report.Options);
// Download file.
return File(stream.ToArray(), this.Report.Options.ContentType, $"OutputFromPage.{this.Report.Format.ToLower()}");
}
}
}
namespace SpreadsheetCorePages.Models
{
public class ReportModel
{
public IList<ReportItemModel> Items { get; set; } = new List<ReportItemModel>()
{
new ReportItemModel() { Id = 100, Name = "John Doe", Salary = 3600 },
new ReportItemModel() { Id = 101, Name = "Jane Doe", Salary = 7200 },
new ReportItemModel() { Id = 102, Name = "Fred Nurk", Salary = 2580 },
new ReportItemModel() { Id = 103, Name = "Hans Meier", Salary = 3200 },
new ReportItemModel() { Id = 104, Name = "Ivan Horvat", Salary = 4100 },
new ReportItemModel() { Id = 105, Name = "Jean Dupont", Salary = 6850 },
new ReportItemModel() { Id = 106, Name = "Mario Rossi", Salary = 4400 }
};
public string Format { get; set; } = "PDF";
public SaveOptions Options => this.FormatMappingDictionary[this.Format];
public IDictionary<string, SaveOptions> FormatMappingDictionary => new Dictionary<string, SaveOptions>()
{
["XLSX"] = new XlsxSaveOptions(),
["XLS"] = new XlsSaveOptions(),
["ODS"] = new OdsSaveOptions(),
["CSV"] = new CsvSaveOptions(CsvType.CommaDelimited),
["PDF"] = new PdfSaveOptions(),
["HTML"] = new HtmlSaveOptions() { EmbedImages = true },
["XPS"] = new XpsSaveOptions(),
["BMP"] = new ImageSaveOptions(ImageSaveFormat.Bmp),
["PNG"] = new ImageSaveOptions(ImageSaveFormat.Png),
["JPG"] = new ImageSaveOptions(ImageSaveFormat.Jpeg),
["GIF"] = new ImageSaveOptions(ImageSaveFormat.Gif),
["TIF"] = new ImageSaveOptions(ImageSaveFormat.Tiff)
};
}
public class ReportItemModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
}
}
Host and deploy ASP.NET Core
Create PNG, JPG, or XPS files on Windows
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GemBox.Spreadsheet" Version="*" />
</ItemGroup>
</Project>
AppContext
class.public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
// Add compatibility switch.
AppContext.SetSwitch("Switch.System.Windows.Media.ShouldRenderEvenWhenNoDisplayDevicesAreAvailable", true);
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// ...
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
}
}
{
"configProperties": {
"Switch.System.Windows.Media.ShouldRenderEvenWhenNoDisplayDevicesAreAvailable": true
}
}
Limitations on Linux or macOS
ConvertToImageSource
and ConvertToXpsDocument
methods.