I'm working on a Blazor server project. One of the requirements is to display the records in a popup window and then print it as a PDF document. If there are too many records to fit on one page, the PDF will only be saved as a single page . What I mean is that there are only a few records that fit on the first page of the PDF. How to make PDF show all records? Is it because of CSS?
Here is the modal:
@page "/dialogcard/{Order}" @usingIMS.CoreBusiness @usingIMS.UseCases.Interfaces.OrderDetail @using System.Globalization @inject IViewOrderDetailsByOrderIdUseCase ViewOrderDetailsByOrderIdUseCase @inject DialogService DialogService @inject IJSRuntime JsRuntime <style> .rz-dialog-wrapper { left:0; } /*.rz-card{ margin-top: -1.9rem !important; }*/ .rz-dialog-content { margin-top: -55px; } </style> @if (orderDetails != null) { <div id="printarea1"> <div class="row my-4"> <div class="col-md-12"> <RadzenCard> <h3 class="h5"> Order Date: @Order.OrderDateTime </h3> <RadzenTabs> <Tabs> @{ var detailVendorId = 0; } @foreach (var detail in orderDetails) { @if (detailVendorId != detail.VendorId) { <RadzenTabsItem Text="@detail.Vendor.Name"> <div class="row"> <div class="col-lg-6 d-flex"> <RadzenCard Style="width: 100%; overflow: hidden;"> <h3 class="h5">Contact</h3> <div class="d-flex flex-row"> <div> <div>Company</div> <b>Vorlance</b> <div class="mt-3">Responsible</div> <b>@detail.Order.DoneBy</b> <div class="mt-3">Vendor</div> <b>@detail?.Vendor.Name</b> </div> </div> </RadzenCard> </div> <div class="col-lg-6 d-flex"> <RadzenCard Style="width: 100%; overflow: hidden;"> <h3 class="h5">Delivery Information</h3> <div class="row"> <div class="col"> <div>Company Name</div> @switch (detail.Warehouse) { case "Shenzhen Warehouse": <b>@string.Format(new CultureInfo("en-US"), "test")</b> <div>Address</div> <b>@string.Format(new CultureInfo("en-US"), "test")</b> <div>Contact Name</div> <b>@string.Format(new CultureInfo("en-US"), "test")</b> <div>Email</div> <b>@string.Format(new CultureInfo("en-US"), "test")</b> <div>Phone</div> <b>@string.Format(new CultureInfo("en-US"), " 1233455")</b> break; case "USA Warehouse": <b>@string.Format(new CultureInfo("en-US"), "Company Name: TRADING LLC")</b> <div>Address</div> <b>@string.Format(new CultureInfo("en-US"), "1243445,Coconut Creek, FL, ZIP Code: 33073")</b> <div>Contact Name</div> <b>@string.Format(new CultureInfo("en-US"), "Test")</b> <div>Email</div> <b>@string.Format(new CultureInfo("en-US"), "[email protected]")</b> <div>Phone</div> <b>@string.Format(new CultureInfo("en-US"), " 123242422")</b> break; case "Private Shipping": <b>@string.Format(new CultureInfo("en-US"), "ELEKTRONIK SANAYI VE TICARET LTD. STI.")</b> <div>Address</div> <b>@string.Format(new CultureInfo("en-US"), "test")</b> <div>Contact Name</div> <b>@string.Format(new CultureInfo("en-US"), "Test")</b> <div>Email</div> <b>@string.Format(new CultureInfo("en-US"), "[email protected]")</b> <div>Phone</div> <b>@string.Format(new CultureInfo("en-US"), "111122")</b> break; } @* <div>Address</div> <b>@(detail?.Warehouse)</b> *@ </div> </div> </RadzenCard> </div> </div> <RadzenDataGrid AllowFiltering="false" AllowPaging="false" AllowSorting="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" Data="@orderDetails.Where(x => x.VendorId == detail.VendorId)" TItem="OrderDetail" Class="mt-3" Style="height:190px"> <Columns> <RadzenDataGridColumn TItem="OrderDetail" Property="OrderId" Title="Order ID" Width="100px"/> <RadzenDataGridColumn TItem="OrderDetail" Property="Id" Title="Product ID" Width="100px"/> <RadzenDataGridColumn TItem="OrderDetail" Property="ProductCode" Title="Product Code" Width="150px"/> <RadzenDataGridColumn TItem="OrderDetail" Property="Currency" Title="Currency" Width="95px"/> <RadzenDataGridColumn TItem="OrderDetail" Property="Quantity" Title="Quantity" Width="95px"> <FooterTemplate> <b>@string.Format(new CultureInfo("tr-TR"), "{0:G}", orderDetails?.Where(x => x.VendorId == detail.VendorId).Sum(o => o.Quantity))</b> </FooterTemplate> </RadzenDataGridColumn> <RadzenDataGridColumn TItem="OrderDetail" Property="BuyUnitPrice" Title="Unit Price" Width="100px"> <Template Context="detail"> @switch (detail.Currency) { case "USD": @string.Format(new CultureInfo("en-US"), "{0}{1:0.#####}",new CultureInfo("en-US").NumberFormat.CurrencySymbol, detail.BuyUnitPrice) break; case "EURO": @string.Format(new CultureInfo("en-FR"), "{0}{1:0.#####}",new CultureInfo("en-FR").NumberFormat.CurrencySymbol, detail.BuyUnitPrice) break; default: @string.Format(new CultureInfo("tr-TR"), "{0}{1:0.#####}",new CultureInfo("tr-TR").NumberFormat.CurrencySymbol, detail.BuyUnitPrice) break; } </Template> </RadzenDataGridColumn> <RadzenDataGridColumn TItem="OrderDetail" Property="TotalBuyPrice" Title="Total Price" Width="100px"> <Template Context="detail"> @switch (detail.Currency) { case "USD": @string.Format(new CultureInfo("en-US"), "{0}{1:0.#####}",new CultureInfo("en-US").NumberFormat.CurrencySymbol, detail.TotalBuyPrice) break; case "EURO": @string.Format(new CultureInfo("en-FR"), "{0}{1:0.#####}",new CultureInfo("en-FR").NumberFormat.CurrencySymbol, detail.TotalBuyPrice) break; default: @string.Format(new CultureInfo("tr-TR"), "{0}{1:0.#####}",new CultureInfo("tr-TR").NumberFormat.CurrencySymbol, detail.TotalBuyPrice) break; } </Template> <FooterTemplate> @switch (detail.Currency) { case "USD": <b>@string.Format(new CultureInfo("en-US"), "{0:N2}", orderDetails?.Where(x => x.VendorId == detail.VendorId).Sum(o => o.TotalBuyPrice))</b> break; case "EURO": <b>@string.Format(new CultureInfo("en-FR"), "{0:N2}", orderDetails?.Where(x => x.VendorId == detail.VendorId).Sum(o => o.TotalBuyPrice))</b> break; default: <b>@string.Format(new CultureInfo("tr-TR"), "{0:N2}", orderDetails?.Where(x => x.VendorId == detail.VendorId).Sum(o => o.TotalBuyPrice))</b> break; } </FooterTemplate> </RadzenDataGridColumn> </Columns> </RadzenDataGrid> </RadzenTabsItem> } detailVendorId = detail.VendorId; } </Tabs> </RadzenTabs> </RadzenCard> </div> </div> </div> } <div class="row"> <div class="col-md-12 text-right"> <RadzenButton Click="@((args) => DialogService.Close(false))" ButtonStyle="ButtonStyle.Secondary" Text="Close" Style="width: 120px" Class="mr-1"/> <RadzenButton Click="PrintDocument" Text="Print" Style="width: 120px" /> @*<button type="button" class="btn btn-primary btns" @onclick="PrintDocument">Print</button>*@ </div> </div> @code { [Parameter] public ReportViewModel Order { get; set; } IEnumerable<OrderDetail> orderDetails; protected override async Task OnInitializedAsync() { orderDetails = await ViewOrderDetailsByOrderIdUseCase.ExecuteAsync(Order.OrderId); } private void PrintDocument() { JsRuntime.InvokeVoidAsync("print"); } }
This is a screenshot of the pattern:
This is the print preview:
This is the relevant CSS:
@media print { body * { visibility: hidden; } #printarea1, #printarea1 *{ visibility: visible; } #printarea, #printarea * { visibility: visible; } .rz-tabview-nav li:not(.rz-tabview-selected) { display: none; } #printarea1 { position: fixed; left: 0; top: 170px; } #printarea { position: fixed; left: 15px; top: 0; } button[type=button], input[type=text] { display: none; } .rz-data-grid { height: unset!important; } }
Edit 1
I researched a bit and changed the CSS like this, but it's still one page :(
.rz-data-grid { height: auto !important; overflow: visible !important; page-break-after: always; }
The browser uses A4 as the page size option by default to print pages. In order to adapt to the page size, the browser print preview will automatically hide overflowing content. Therefore, a data grid with a large number of columns will be clipped to fit the size of the printed page.
To print a large number of columns, adjust the scaling options in the Print Options panel based on the content size.
When the data grid contains a large amount of data, printing all the data at once is not the best option considering browser performance. Because rendering all DOM elements in a single page creates performance issues in the browser. This can cause the browser to become slow or unresponsive. DataGrid has the option to handle large amounts of data through virtualization. However, when printing, you cannot use virtualization for rows and columns.
If you still need to print all the data, we recommend that you export the data grid to Excel or a CSV or Pdf file and then print from another non-web-based application.
There are many methods and libraries for generating PDF, such as syncfusion etc.