最近,客户有个需求过来,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;
                // 绘制Image
                e.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几乎全是。

需求总是来得特别突然,下次再有新特别需求时再来和大家分享。

其他的实现思路

第一种

安装一个打印客户端 用grid++实现打印模板

本地起一个 WebSocketServer 客户端接收信息然后 组装模板打印即可。

第二种

通过webBrowser实现打印功能,只适用于文本

//转到某个网址
webBrowser.Navigate("");
//直接打印
 webBrowser.Print();
 //预览
 webBrowser.ShowPrintPreviewDialog();
 //打印
 webBrowser.ShowPrintDialog();

以上就是c# 如何实现web打印插件的详细内容,更多关于c# 实现web打印插件的资料请关注悠悠之家其它相关文章!

点赞(331)

评论列表共有 0 条评论

立即
投稿
返回
顶部