Blazor Server应用中客户端打印用户登录码的问题求助
Blazor Server 客户端打印服务器生成登录条码的可行方案
现有代码核心问题
你当前的PrintCodeUser方法是在服务器端执行的,调用Process.Start会在服务器机器上打开Edge浏览器,客户端浏览器完全感知不到,这就是客户端无反应的根本原因。另外,代码直接拼接SQL参数存在严重的SQL注入风险,必须修正。
成熟解决方案
方案1:将条码转为Base64,客户端渲染后调用浏览器打印API
这是最直接的方案,无需生成服务器本地文件,直接在客户端渲染图片并触发打印。
服务器端修改(生成Base64字符串)
public string GenerateBarcodeBase64(int id) { string imie = ""; string nazwisko = ""; string kod = ""; // 参数化查询防SQL注入 using (SqlConnection con1 = new SqlConnection(connectionToSql)) { string sqll = "SELECT Imie, Nazwisko, Kod FROM CompositeApps.dbo.Kamino WHERE id = @Id"; try { var cmdd = new SqlCommand(sqll, con1); cmdd.Parameters.AddWithValue("@Id", id); con1.Open(); SqlDataReader rdrr = cmdd.ExecuteReader(); while (rdrr.Read()) { imie = rdrr.IsDBNull(0) ? "0" : rdrr[0].ToString(); nazwisko = rdrr.IsDBNull(1) ? "" : rdrr[1].ToString(); kod = rdrr.IsDBNull(2) ? "" : rdrr[2].ToString(); } con1.Close(); } catch { } } // 使用freeSpire.Barcode生成条码图片 BarcodeSettings settings = new BarcodeSettings(); settings.Type = BarCodeType.Code128; // 根据实际条码类型调整 settings.Data = kod; settings.ShowText = true; BarCodeGenerator generator = new BarCodeGenerator(settings); Image barcodeImage = generator.GenerateImage(); // 添加用户名称到图片 using (Graphics graphics = Graphics.FromImage(barcodeImage)) { using (Font arialFont = new Font("Arial", 14)) { string napis = $"{imie} {nazwisko}"; graphics.DrawString(napis, arialFont, Brushes.Black, new PointF(10f, 10f)); } } // 转为Base64字符串返回 using (MemoryStream ms = new MemoryStream()) { barcodeImage.Save(ms, ImageFormat.Png); byte[] imageBytes = ms.ToArray(); return $"data:image/png;base64,{Convert.ToBase64String(imageBytes)}"; } }
Blazor客户端组件实现
@page "/print-barcode/{Id:int}" @inject IJSRuntime JSRuntime <div id="print-content"> @if (!string.IsNullOrEmpty(_barcodeBase64)) { <img src="@_barcodeBase64" alt="用户登录条码" /> } </div> <button @onclick="TriggerPrint">打印条码</button> @code { [Parameter] public int Id { get; set; } private string _barcodeBase64; protected override void OnInitialized() { // 调用服务器方法获取Base64字符串 _barcodeBase64 = GenerateBarcodeBase64(Id); } private async Task TriggerPrint() { await JSRuntime.InvokeVoidAsync("printTargetArea", "print-content"); } } <script> function printTargetArea(elementId) { const target = document.getElementById(elementId); const originalBody = document.body.innerHTML; // 仅保留打印内容 document.body.innerHTML = target.outerHTML; window.print(); // 恢复页面原内容 document.body.innerHTML = originalBody; } </script>
方案2:返回服务器文件流,客户端下载后打印
如果必须在服务器生成本地文件,可将文件以流的形式返回给客户端,让用户下载或直接打开后打印。
服务器端API
[HttpGet("api/barcode-file/{id}")] public IActionResult GetBarcodeFile(int id) { string filePath = @"C:\CompositeApps\tempkod22.png"; if (!System.IO.File.Exists(filePath)) { return NotFound(); } // 返回文件流给客户端 var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); var result = File(fileStream, "image/png", $"用户{id}登录条码.png"); // 可选:返回后删除临时文件 System.IO.File.Delete(filePath); return result; }
Blazor客户端调用
<button @onclick="DownloadBarcode">下载并打印条码</button> @code { [Parameter] public int Id { get; set; } [Inject] private IJSRuntime JSRuntime { get; set; } private async Task DownloadBarcode() { // 打开新窗口加载文件,用户可手动打印 await JSRuntime.InvokeVoidAsync("open", $"/api/barcode-file/{Id}", "_blank"); } }
方案3:使用Blazor专用打印组件
使用封装好的Blazor打印组件简化开发,比如BlazorPrint:
- 安装NuGet包:
Install-Package BlazorPrint - 组件中使用:
@using BlazorPrint @inject IJSRuntime JSRuntime <BlazorPrint> <PrintContent> <img src="@_barcodeBase64" alt="用户登录条码" /> <p>@imie @nazwisko</p> </PrintContent> <PrintButton>打印条码</PrintButton> </BlazorPrint> @code { private string _barcodeBase64; private string imie, nazwisko; // 初始化时获取条码Base64和用户信息 }
注意事项
- 必须使用参数化查询替代SQL字符串拼接,彻底避免注入风险。
- Blazor Server中所有客户端操作(打印、打开窗口等)都需要通过JS互操作实现,不能直接在服务器端调用本地进程。
- 服务器生成的临时文件需定时清理,避免磁盘空间被占用。
内容的提问来源于stack exchange,提问作者Przemo
相关产品推荐
相关产品推荐

