我正在开发 Blazor 服务器项目。要求之一是在弹出窗口中显示记录,然后将其打印为 PDF 文档。如果记录太多而无法容纳在一页上,PDF 将仅保存为单页。我的意思是只有几条记录适合显示在 PDF 的第一页上。如何让PDF显示所有记录? 是CSS的原因吗?
这里是模态:
@page "/dialogcard/{Order}" @using IMS.CoreBusiness @using IMS.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"); } }
这是模式的屏幕截图:
这是打印预览:
这是相关的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; } }
编辑 1
我研究了一下,像这样改变了CSS,但仍然是一页:(
.rz-data-grid { height: auto !important; overflow: visible !important; page-break-after: always; }
浏览器默认使用A4作为页面尺寸选项来打印页面,为了适应页面尺寸,浏览器打印预览会自动隐藏溢出的内容。因此,具有大量列的数据网格将被剪掉以适应打印页面的大小。
要打印大量列,请根据内容大小调整打印选项面板中的缩放选项。
当数据网格包含大量数据时,考虑到浏览器性能,一次打印所有数据并不是最佳选择。因为在单个页面中渲染所有 DOM 元素会在浏览器中产生性能问题。这会导致浏览器速度变慢或无响应。 DataGrid 可以选择通过虚拟化处理大量数据。但是,在打印时,无法对行和列使用虚拟化。
如果仍然需要打印所有数据,我们建议您将数据网格导出到 Excel 或 CSV 或 Pdf 文件,然后从另一个非基于 Web 的应用程序进行打印。
生成PDF的方法和库有很多,比如syncfusion等