You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor WebAssembly无需新建Razor页实现动态表单打印需求

Blazor WebAssembly 跨页面数据无显式页面打印方案

核心思路

通过后端API生成包含所有需要整合数据的打印用HTML字符串,前端通过JS互操作动态创建隐藏DOM元素加载该HTML,直接触发打印后自动清理元素,无需新建Razor页。


1. 后端实现(生成打印HTML)

创建API接口,从各数据源拉取数据并构建结构化的打印HTML(可硬拼字符串或用Razor视图渲染):

using Microsoft.AspNetCore.Mvc;
using YourProject.Services;

namespace YourProject.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class PrintController : ControllerBase
    {
        private readonly IDataService1 _dataService1;
        private readonly IDataService2 _dataService2;

        public PrintController(IDataService1 dataService1, IDataService2 dataService2)
        {
            _dataService1 = dataService1;
            _dataService2 = dataService2;
        }

        [HttpGet("integrated-form")]
        public async Task<IActionResult> GetIntegratedPrintForm()
        {
            // 从不同模块获取需要整合的数据
            var module1Data = await _dataService1.GetAsync();
            var module2Data = await _dataService2.GetAsync();

            // 构建打印专属HTML(含打印样式)
            var printHtml = $@"
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset='UTF-8'>
                <title>整合数据打印单</title>
                <style>
                    /* 基础打印样式 */
                    body {{ font-family: Arial, sans-serif; margin: 0; padding: 20px; }}
                    .section {{ margin-bottom: 30px; border-bottom: 1px solid #ddd; padding-bottom: 15px; }}
                    h1 {{ text-align: center; color: #333; }}
                    /* 适配打印媒体 */
                    @media print {{
                        body {{ padding: 0; }}
                        .section {{ page-break-inside: avoid; }}
                    }}
                </style>
            </head>
            <body>
                <h1>整合业务数据打印单</h1>
                <div class='section'>
                    <h2>模块1信息</h2>
                    <p>名称: {module1Data.Name}</p>
                    <p>创建时间: {module1Data.CreatedTime:yyyy-MM-dd HH:mm}</p>
                    <p>详情: {module1Data.Description}</p>
                </div>
                <div class='section'>
                    <h2>模块2信息</h2>
                    <p>编号: {module2Data.Id}</p>
                    <p>状态: {module2Data.Status}</p>
                    <p>备注: {module2Data.Remarks}</p>
                </div>
            </body>
            </html>";

            return Ok(printHtml);
        }
    }
}

注:如果HTML布局复杂,推荐用Razor视图渲染:创建.cshtml视图,使用IRazorViewEngine将视图渲染为字符串返回,避免硬拼字符串的维护问题。


2. 前端JS互操作实现(无显示打印)

在wwwroot/js/print-utils.js中添加打印专用JS函数:

window.printHiddenHtml = function(htmlContent) {
    // 创建隐藏的iframe容器
    const printIframe = document.createElement('iframe');
    printIframe.style.position = 'absolute';
    printIframe.style.width = '0';
    printIframe.style.height = '0';
    printIframe.style.border = '0';
    printIframe.style.display = 'none';
    document.body.appendChild(printIframe);

    // 加载HTML内容
    const iframeDoc = printIframe.contentDocument || printIframe.contentWindow.document;
    iframeDoc.open();
    iframeDoc.write(htmlContent);
    iframeDoc.close();

    // 内容加载完成后触发打印,打印后清理元素
    printIframe.onload = function() {
        printIframe.contentWindow.print();
        // 延迟移除避免打印中断
        setTimeout(() => document.body.removeChild(printIframe), 1500);
    };
};

3. Blazor组件调用(打印按钮逻辑)

在你的打印按钮所在组件中,注入HttpClient和IJSRuntime,实现点击触发逻辑:

@inject HttpClient Http
@inject IJSRuntime JSRuntime

<MudButton OnClick="TriggerIntegratedPrint" 
           Variant="Variant.Filled" 
           Color="Color.Primary"
           Icon="@Icons.Material.Filled.Print">
    打印整合表单
</MudButton>

@code {
    private async Task TriggerIntegratedPrint()
    {
        try
        {
            // 调用后端API获取打印HTML
            var printHtml = await Http.GetStringAsync("api/print/integrated-form");
            
            // 调用JS执行无显示打印
            await JSRuntime.InvokeVoidAsync("window.printHiddenHtml", printHtml);
        }
        catch (Exception ex)
        {
            // 这里可以用MudBlazor的Snackbar提示错误
            // await Snackbar.Add($"打印失败: {ex.Message}", Severity.Error);
        }
    }
}

关键注意事项

  • 打印样式必须适配打印媒体:使用@media print规则调整打印时的布局、边距等,避免屏幕样式干扰。
  • 后端生成HTML时要确保字符编码正确(UTF-8),避免乱码。
  • 动态创建的iframe要在打印完成后及时清理,避免DOM冗余。

内容的提问来源于stack exchange,提问作者Gagandeep Singh Bagga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:50:48