blazor-405473-components-grid-export-pdf-export.md
Call the ExportToPdfAsync method to export Grid data to PDF. The output table reflects the current filter, sort order, and group settings. You can save the result to a stream or download it on the client. The method parameter allows you to configure export settings and customize document appearance.
You can also export Grid data to XLS, XLSX, or CSV formats.
Blazor WebAssembly AppsPDF export in WebAssembly applications has the following prerequisites:
wasm-tools.wasm-tools-netX (where X is the framework’s major version).Blazor Server Apps
For non-Windows environments (Linux, macOS, and Azure/AWS cloud platforms), install the DevExpress.Drawing.Skia NuGet package.
On Linux, you must also install the following font libraries:
false. Handle the CustomizeColumn event to add hidden columns to the output file.View Example: Export Detail Views
The export engine processes all data columns. Set a column’s ExportEnabled property to false to exclude that column from data export:
@inject WeatherForecastService ForecastService
<DxButton Text="Export to PDF" Click="ExportPdf_Click" />
<DxGrid @ref="Grid" Data="@Data">
<Columns>
<DxGridDataColumn FieldName="Date" DisplayFormat="D" />
<DxGridDataColumn FieldName="TemperatureC" Caption="@("Temp. (\x2103)")" />
<DxGridDataColumn FieldName="TemperatureF" Caption="@("Temp. (\x2109)")" ExportEnabled="false" />
<DxGridDataColumn FieldName="Forecast" ExportEnabled="false" />
<DxGridDataColumn FieldName="CloudCover" ExportEnabled="false" />
</Columns>
</DxGrid>
@code {
IGrid Grid { get; set; }
object Data { get; set; }
protected override void OnInitialized() {
Data = ForecastService.GetForecast();
}
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult");
}
}
using System;
public class WeatherForecast {
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public double TemperatureF => Math.Round((TemperatureC * 1.8 + 32), 2);
public string Forecast { get; set; }
public string CloudCover { get; set; }
public bool Precipitation { get; set; }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
public class WeatherForecastService {
private List<WeatherForecast> Forecast { get; set; }
private static string[] CloudCover = new[] {
"Sunny", "Partly cloudy", "Cloudy", "Stormy"
};
Tuple<int, string>[] ConditionsForForecast = new Tuple<int, string>[] {
Tuple.Create( 22 , "Hot"),
Tuple.Create( 13 , "Warm"),
Tuple.Create( 0 , "Cold"),
Tuple.Create( -10 , "Freezing")
};
public WeatherForecastService() {
Forecast = CreateForecast();
}
private List<WeatherForecast> CreateForecast() {
var rng = new Random();
DateTime startDate = DateTime.Now;
return Enumerable.Range(1, 15).Select(index => {
var temperatureC = rng.Next(-10, 30);
return new WeatherForecast {
Date = startDate.AddDays(index),
TemperatureC = temperatureC,
CloudCover = CloudCover[rng.Next(0, 4)],
Precipitation = Convert.ToBoolean(rng.Next(0, 2)),
Forecast = ConditionsForForecast.First(c => c.Item1 <= temperatureC).Item2
};
}).ToList();
}
public IEnumerable<WeatherForecast> GetForecast() {
return Forecast.ToArray();
}
// ...
}
// ...
builder.Services.AddSingleton<WeatherForecastService>();
The Grid component raises the CustomizeColumn event for all data columns whose ExportEnabled property is set to true (default). The IsHidden event argument specifies the processed column’s visibility in the exported document.
The Grid initially sets the IsHidden argument to the opposite of the processed column’s Visible property value. As a result, only visible columns are exported to PDF by default. Switch the argument value to display/hide columns in the output document:
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult", new GridPdfExportOptions() {
CustomizeColumn = CustomizeColumn,
});
}
void CustomizeColumn(GridDocumentExportCustomizeColumnEventArgs e) {
// Displays all grid columns in the output document
e.IsHidden = false;
}
The ExportWidth property specifies the column width in the exported document. When exporting to PDF, the Grid component recalculates column widths so that the output table occupies all available space. Disable the FitToPage export option to use the exact ExportWidth values for exported columns:
@inject WeatherForecastService ForecastService
<DxButton Text="Export to PDF" Click="ExportPdf_Click" />
<DxGrid @ref="Grid" Data="@Data">
<Columns>
<DxGridDataColumn FieldName="Date" DisplayFormat="D" ExportWidth="600" />
<DxGridDataColumn FieldName="TemperatureC" Caption="@("Temp. (\x2103)")" ExportWidth="250" />
<DxGridDataColumn FieldName="TemperatureF" Caption="@("Temp. (\x2109)")" ExportWidth="250" />
<DxGridDataColumn FieldName="Forecast" ExportWidth="300" />
<DxGridDataColumn FieldName="CloudCover" ExportWidth="300" />
</Columns>
</DxGrid>
@code {
IGrid Grid { get; set; }
object Data { get; set; }
protected override void OnInitialized() {
Data = ForecastService.GetForecast();
}
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult", new GridPdfExportOptions() {
FitToPage = false
});
}
}
You can also handle the CustomizeColumn event and specify the Width event argument to modify export widths:
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult", new GridPdfExportOptions() {
CustomizeColumn = CustomizeColumn,
FitToPage = false
});
}
void CustomizeColumn(GridDocumentExportCustomizeColumnEventArgs e) {
if (e.FieldName.Contains("Temperature"))
e.Width = 250;
}
Set the ExportSelectedRowsOnly property to true to export only selected rows:
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult", new GridPdfExportOptions() {
ExportSelectedRowsOnly = true,
});
}
Once enabled, the Grid ignores group settings and exports records as flat data. To preserve row hierarchy, set ExportSelectedRowsOnly to KeepGrouping:
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult", new GridPdfExportOptions() {
ExportSelectedRowsOnly = true,
SelectedRowsExportMode = GridSelectedRowsExportMode.KeepGrouping
});
}
Handle the CustomizeCell event and use its ElementStyle argument to format exported cells:
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult", new GridPdfExportOptions() {
CustomizeCell = CustomizeCell
});
}
void CustomizeCell(GridDocumentExportCustomizeCellEventArgs e) {
// Applies bold formatting to column headers
if (e.AreaType == DocumentExportAreaType.Header)
e.ElementStyle.Font = new DXFont(e.ElementStyle.Font, DXFontStyle.Bold);
if (e.AreaType == DocumentExportAreaType.DataArea) {
var forecast = (WeatherForecast)e.DataItem;
// Highlights rows with low/high TemperatureC values
if (forecast.TemperatureC < 10)
e.ElementStyle.BackColor = System.Drawing.Color.LightBlue;
if (forecast.TemperatureC > 20)
e.ElementStyle.BackColor = System.Drawing.Color.PaleVioletRed;
}
// Applies the specified settings
e.Handled = true;
}
An output PDF file contains only a table with exported data. Handle the following events to add additional elements to the document:
The following code snippet adds headers and footers to the output document:
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult", new GridPdfExportOptions() {
CustomizeDocumentHeader = OnCustomizeDocumentHeader, // Adds a document header
CustomizeDocumentFooter = OnCustomizeDocumentFooter, // Adds a document footer
CustomizePageHeader = OnCustomizePageHeader, // Adds page headers
CustomizePageFooter = OnCustomizePageFooter, // Adds page footers
});
}
void OnCustomizeDocumentHeader(GridDocumentExportCustomizeDocumentHeaderFooterEventArgs args) {
args.ElementStyle.Font = new DXFont("Arial", 16);
args.Text = "Weather Forecast";
}
void OnCustomizeDocumentFooter(GridDocumentExportCustomizeDocumentHeaderFooterEventArgs args) {
args.ElementStyle.Font = new DXFont(args.ElementStyle.Font, DXFontStyle.Bold);
args.ElementStyle.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleLeft;
args.Text = "The document data is intented for demonstration purposes only.";
}
void OnCustomizePageHeader(GridDocumentExportCustomizePageHeaderFooterEventArgs args) {
args.ElementStyle.Font = new DXFont(args.ElementStyle.Font, DXFontStyle.Italic);
args.Text = "Copyright © 1998-2025 Developer Express Inc.";
}
void OnCustomizePageFooter(GridDocumentExportCustomizePageHeaderFooterEventArgs args) {
args.ElementStyle.Font = new DXFont(args.ElementStyle.Font, DXFontStyle.Italic);
args.Text = "Page {0} of {1}"; // Displays the current page number and total page count
}
Handle the RowExporting event to filter exported data. The Grid raises this event for both data and group rows. Use the IsGroupRow event argument to determine the row type.
Note
If you exclude a group row from the exported document, you should also exclude all data rows that belong to this group. Otherwise, the data hierarchy in the resulting document breaks.
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("Cool Weather", new GridPdfExportOptions() {
RowExporting = RowExporting,
});
}
void RowExporting(GridRowExportingEventArgs e) {
var forecast = (WeatherForecast) e.DataItem;
if (forecast.TemperatureC < 10) {
e.Cancel = true;
}
}
Handle the CustomizeDocument event and use its arguments to customize page settings:
async Task ExportPdf_Click() {
await Grid.ExportToPdfAsync("ExportResult", new GridPdfExportOptions() {
CustomizeDocument = OnCustomizeDocument
});
}
void OnCustomizeDocument(GridDocumentExportCustomizeDocumentEventArgs args) {
// Switches the page orientation to landscape
args.Landscape = true;
// Sets page margins to 0.5 inches
args.Margins = new DXMargins(50, 50, 50, 50);
// Sets the page size to a custom value (width: 6 inches, height: 8 inches)
args.PaperKind = DevExpress.Drawing.Printing.DXPaperKind.Custom;
args.PageSize = new System.Drawing.Size(600, 800);
}
Use DevExpress Blazor Loading Panel to display a loading indicator during export operations:
@inject WeatherForecastService ForecastService
<DxLoadingPanel @bind-Visible="@PanelVisible"
IsContentBlocked="true"
ApplyBackgroundShading="true"
IndicatorAreaVisible="false"
Text="Exporting Document...">
<DxButton Text="Export to PDF" Click="ExportPdf_Click" />
<DxGrid @ref="Grid" Data="@Data">
<Columns>
<DxGridDataColumn FieldName="Date" DisplayFormat="D" />
<DxGridDataColumn FieldName="TemperatureC" Caption="@("Temp. (\x2103)")" />
<DxGridDataColumn FieldName="TemperatureF" Caption="@("Temp. (\x2109)")" />
<DxGridDataColumn FieldName="Forecast" />
<DxGridDataColumn FieldName="CloudCover" />
</Columns>
</DxGrid>
</DxLoadingPanel>
@code {
IGrid Grid { get; set; }
object Data { get; set; }
bool PanelVisible { get; set; } = false;
protected override void OnInitialized() {
Data = ForecastService.GetForecast();
}
async Task ExportPdf_Click() {
PanelVisible = true;
await Task.Yield();
await Grid.ExportToPdfAsync("ExportResult");
PanelVisible = false;
}
}