如何在Blazor WASM中导出MudBlazor表格为PDF?
MudBlazor表格导出PDF的两种可行方案
针对Blazor WASM + MudBlazor场景,以下是两种稳定的PDF导出方案,适配MudTable的使用场景:
方案一:基于数据源直接生成PDF(推荐,样式可控)
这种方式不依赖DOM,直接用表格绑定的数据源生成PDF,避免HTML转PDF的样式兼容问题,推荐使用QuestPDF库(轻量、API友好)。
步骤:
- 安装NuGet包:
Install-Package QuestPDF Install-Package QuestPDF.Fluent Install-Package QuestPDF.Helpers
- 编写导出逻辑(结合MudTable):
假设你的MudTable绑定的是List<Product>类型的数据源,在组件中添加导出方法:
@inject IJSRuntime JSRuntime @using QuestPDF.Fluent @using QuestPDF.Helpers @using QuestPDF.Infrastructure <MudTable Items="@Products" @ref="mudTable"> <HeaderContent> <MudTh>ID</MudTh> <MudTh>名称</MudTh> <MudTh>价格</MudTh> </HeaderContent> <RowTemplate> <MudTd>@context.Id</MudTd> <MudTd>@context.Name</MudTd> <MudTd>@context.Price.ToString("C")</MudTd> </RowTemplate> </MudTable> <MudButton OnClick="@ExportToPdf" Variant="Variant.Filled" Color="Color.Primary">导出PDF</MudButton> @code { private MudTable<Product> mudTable; private List<Product> Products = new() { new Product { Id = 1, Name = "商品A", Price = 99.99m }, new Product { Id = 2, Name = "商品B", Price = 199.99m } }; private async Task ExportToPdf() { // 生成PDF文档 var document = Document.Create(container => { container.Page(page => { page.Size(PageSizes.A4); page.Margin(2, Unit.Centimetre); page.Header().Text("商品列表").FontSize(16).Bold().AlignCenter(); page.Content().Table(table => { // 构建表头 table.Header(header => { header.Cell().Text("ID").Bold(); header.Cell().Text("名称").Bold(); header.Cell().Text("价格").Bold(); }); // 填充表格数据(直接用MudTable的数据源) foreach (var item in mudTable.Items) { table.Row(row => { row.Cell().Text(item.Id.ToString()); row.Cell().Text(item.Name); row.Cell().Text(item.Price.ToString("C")); }); } }); }); }); // 将PDF转为字节数组 byte[] pdfBytes = document.GeneratePdf(); // 通过JSInterop下载文件 await JSRuntime.InvokeVoidAsync("downloadFile", "商品列表.pdf", pdfBytes); } // 定义实体类 public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } }
- 添加JS辅助方法(在wwwroot/index.html中):
<script> function downloadFile(filename, bytesBase64) { var link = document.createElement('a'); link.href = 'data:application/pdf;base64,' + bytesBase64; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); } </script>
方案二:HTML转PDF(保留MudTable样式)
如果需要完全保留MudTable的UI样式(比如颜色、边框),可以用jsPDF + html2canvas通过JSInterop实现DOM转PDF。
步骤:
- 在wwwroot/index.html中引入依赖:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
- 组件中编写导出逻辑:
@inject IJSRuntime JSRuntime <MudTable Items="@Products" Id="export-table"> <HeaderContent> <MudTh>ID</MudTh> <MudTh>名称</MudTh> <MudTh>价格</MudTh> </HeaderContent> <RowTemplate> <MudTd>@context.Id</MudTd> <MudTd>@context.Name</MudTd> <MudTd>@context.Price.ToString("C")</MudTd> </RowTemplate> </MudTable> <MudButton OnClick="@ExportTableToPdf" Variant="Variant.Filled" Color="Color.Secondary">导出PDF(保留样式)</MudButton> @code { private List<Product> Products = new() { new Product { Id = 1, Name = "商品A", Price = 99.99m }, new Product { Id = 2, Name = "商品B", Price = 199.99m } }; private async Task ExportTableToPdf() { await JSRuntime.InvokeVoidAsync("exportTableToPdf", "export-table", "商品列表.pdf"); } public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } }
- 添加JS导出方法(在wwwroot/index.html中):
<script> async function exportTableToPdf(tableId, filename) { const table = document.getElementById(tableId); const canvas = await html2canvas(table, { scale: 2, // 提高清晰度 useCORS: true }); const imgData = canvas.toDataURL('image/png'); const pdf = new jspdf.jsPDF('p', 'mm', 'a4'); const imgWidth = 210; // A4宽度(mm) const pageHeight = 297; // A4高度(mm) const imgHeight = canvas.height * imgWidth / canvas.width; let heightLeft = imgHeight; let position = 0; pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; // 处理分页(如果表格过长) while (heightLeft >= 0) { position = heightLeft - imgHeight; pdf.addPage(); pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; } pdf.save(filename); } </script>
注意事项:
- 方案一适合数据量大、样式定制需求高的场景,无需依赖前端样式;
- 方案二适合需要完全复用MudTable现有样式的场景,但大表格分页需额外处理;
- 若之前的方案报错,大概率是依赖库版本不兼容或JSInterop调用错误,可对比上述示例排查问题。
内容的提问来源于stack exchange,提问作者hanushi-thana
相关产品推荐
相关产品推荐

