c# 如何實現web打印插件

最近,客戶有個需求過來,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打印插件的資料請關註WalkonNet其它相關文章!

推薦閱讀: