最近,客户有个需求过来,Web端无预览打印,美其名曰:快捷打印。
当时第一反应就是找插件,拿来主义永远不过时。找了一圈发现,免费的有限制,没限制的需要收费(LODOP真的好用)。说来就是一个简单的无预览打印,收费的诸多功能都无用武之地,总的来说性价比很低,所以就打算自己琢磨着写一个算了。刚开始总是纠结在Web端去实现直接打印,打印是实现了,结果是服务端的,客户端只能一脸懵。
后来(准备妥协了),安装了一些收费的插件发现,都需要先安装一个客户端程序,灵光乍现,解决方案这不就出来了。
思路:Web端调用客户端程序,让客户端程序去实现打印。
实现:Web端通过WebSocket将Html发送给客户端,客户端(Winform)监听消息,接收处理后再打印。
客户端(Winform)打印实现方式:
1、Html转PDF,然后打印PDF(暂时需要用到三方包)
2、Html转图片,然后通过PrintDocument打印图片
3、通过WebBrowser实现打印
按照上面的思路再去写代码,就会简单很多。
Web端的代码就不多说了,一个简单的WebSocket通信。
客户端程序(Winform)
1、监听Web端的WebSocket消息,这里有用到三方包:Fleck,开箱即用,非常方便。
/// <summary>/// ConnAndListen/// </summary>public static void ConnAndListen(){ // 监听本地 45000端口var server = new WebSocketServer($\"ws://127.0.0.1:45000\");server.Start(socket =>{socket.OnOpen = () =>{// 连接成功socket.Send(\"socket通讯已连接\");};socket.OnClose = () =>{// 关闭连接socket.Send(\"socket通讯已关闭连接\");socket.Close();};socket.OnMessage = message =>{// TODO...};});}
2、处理Html,将Html转换为图片:
/// <summary>/// GetBitmap/// </summary>/// <returns></returns>public Bitmap GetBitmap(){WebPageBitmap Shot = new WebPageBitmap(\"html\", \"页面宽度\", \"页面高度\");Shot.GetIt();Bitmap Pic = Shot.DrawBitmap(\"图片高度\", \"图片宽度\");// 设置图片分辨率Pic.SetResolution(203.0F, 203.0F);return Pic;}
3、打印图片
/// <summary>/// 图片打印/// </summary>public class PrintDirectClass{private PaperSize paperSize = null;// 多页打印private int printNum = 0;// 单个图片文件private string imageFile = \".....\";// 多个图片文件private ArrayList imageList = new ArrayList();/// <summary>/// 打印预览/// </summary>public void PrintPreview(){// 打印机对象PrintDocument imgToPrint = new PrintDocument();#region 打印机相关设置var pageSize = imgToPrint.PrinterSettings.PaperSizes;paperSize = pageSize[pageSize.Count - 1];// 打印方向设置//imgToPrint.DefaultPageSettings.Landscape = false;// 打印纸张大小设置//imgToPrint.DefaultPageSettings.PaperSize = paperSize;// 打印分辨率设置//imgToPrint.DefaultPageSettings.PrinterResolution.Kind = PrinterResolutionKind.High;// 打印边距设置//imgToPrint.DefaultPageSettings.Margins = new Margins(40, 40, 40, 40);// 打印开始事件imgToPrint.BeginPrint += new PrintEventHandler(this.imgToPrint_BeginPrint);// 打印结束事件imgToPrint.EndPrint += new PrintEventHandler(this.imgToPrint_EndPrint);// 打印内容设置imgToPrint.PrintPage += new PrintPageEventHandler(this.imgToPrint_PrintPage);#endregion// 直接打印//imgToPrint.Print();// 打印弹框确认//PrintDialog printDialog = new PrintDialog();//printDialog.AllowSomePages = true;//printDialog.ShowHelp = true;//printDialog.Document = imgToPrint;//if (printDialog.ShowDialog() == DialogResult.OK)//{// imgToPrint.Print();//}// 预览打印//PrintPreviewDialog pvDialog = new PrintPreviewDialog();//pvDialog.Document = imgToPrint;//pvDialog.ShowDialog();}/// <summary>/// 打印开始事件/// </summary>/// <param name=\"sender\"></param>/// <param name=\"e\"></param>private void imgToPrint_BeginPrint(object sender, PrintEventArgs e){if (imageList.Count == 0)imageList.Add(imageFile);}/// <summary>/// 打印结束事件/// </summary>/// <param name=\"sender\"></param>/// <param name=\"e\"></param>private void imgToPrint_EndPrint(object sender, PrintEventArgs e){}/// <summary>/// 设置打印内容/// </summary>/// <param name=\"sender\"></param>/// <param name=\"e\"></param>private void imgToPrint_PrintPage(object sender, PrintPageEventArgs e){// 图片文本质量e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;// 图片插值质量e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;// 图片合成质量e.Graphics.CompositingQuality = CompositingQuality.HighQuality;// 图片抗锯齿e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;// 设置缩放比例e.Graphics.PageScale = 0.3F;using (Stream fs = new FileStream(imageList[printNum].ToString().Trim(), FileMode.Open, FileAccess.Read)){System.Drawing.Image image = System.Drawing.Image.FromStream(fs);int w = image.Width;int h = image.Height;// 绘制Imagee.Graphics.DrawImage(image, 40, 40, 410, 600);if (printNum < imageList.Count - 1){printNum++;// HasMorePages为true则再次运行PrintPage事件e.HasMorePages = true;return;}e.HasMorePages = false;}// 设置打印内容的边距//e.PageSettings.Margins = new Margins(40, 40, 40, 40);// 设置是否横向打印e.PageSettings.Landscape = false;// 设置纸张大小e.PageSettings.PaperSize = paperSize;// 设置打印分辨率e.PageSettings.PrinterResolution.Kind = PrinterResolutionKind.High;}}
以上就是 Html转图片,然后通过PrintDocument打印图片 的实现代码了。其它两种方式大家有兴趣可以去试试。
WebBrowser 比较简单,但是对打印机控制不是特别友好(也可能是我没有发现,研究不深)
WebBrowser wb = new WebBrowser();// 直接打印wb.Print();// 确认打印wb.ShowPrintDialog();// 预览打印wb.ShowPrintPreviewDialog();
Html转PDF,然后打印PDF原理于Html转图片,然后通过PrintDocument打印图片一样,不同的是转PDF可能需要用到第三方的包,目前这方便的包还是比较齐全的,NUGET搜索pdf几乎全是。
需求总是来得特别突然,下次再有新特别需求时再来和大家分享。
以上就是这篇文章的全部内容了,有帮助的点个赞,有错误的欢迎大家指出来,有更好的解决方案也希望大家不吝赐教。