天天看點

Web列印插件實作思路(C#/Winform)

最近,客戶有個需求過來,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,開箱即用,非常友善。

1         /// <summary>
 2         /// ConnAndListen
 3         /// </summary>
 4         public static void ConnAndListen()
 5         { 7             // 監聽本地 45000端口
 8             var server = new WebSocketServer($"ws://127.0.0.1:45000");
 9             server.Start(socket =>
10             {
11                 socket.OnOpen = () =>
12                 {
13                     // 連接配接成功
14                     socket.Send("socket通訊已連接配接");
15                 };
16                 socket.OnClose = () =>
17                 {
18                     // 關閉連接配接
19                     socket.Send("socket通訊已關閉連接配接");
20                     socket.Close();
21                 };
22                 socket.OnMessage = message =>
23                 {
24                     // TODO...
25                 };
26             });
27         }      

2、處理Html,将Html轉換為圖檔:

1         /// <summary>
 2         /// GetBitmap
 3         /// </summary>
 4         /// <returns></returns>
 5         public Bitmap GetBitmap()
 6         {
 7             WebPageBitmap Shot = new WebPageBitmap("html", "頁面寬度", "頁面高度");
 8             Shot.GetIt();
 9             Bitmap Pic = Shot.DrawBitmap("圖檔高度", "圖檔寬度");
10             // 設定圖檔分辨率
11             Pic.SetResolution(203.0F, 203.0F);
12             return Pic;
13         }         

3、列印圖檔

1     /// <summary>
  2     /// 圖檔列印
  3     /// </summary>
  4     public class PrintDirectClass
  5     {
  6         private PaperSize paperSize = null;
  7         // 多頁列印
  8         private int printNum = 0;
  9         // 單個圖檔檔案
 10         private string imageFile = ".....";
 11         // 多個圖檔檔案
 12         private ArrayList imageList = new ArrayList();
 13 
 14         /// <summary>
 15         /// 列印預覽
 16         /// </summary>
 17         public void PrintPreview()
 18         {
 19             // 列印機對象
 20             PrintDocument imgToPrint = new PrintDocument();
 21 
 22             #region 列印機相關設定
 23             var pageSize = imgToPrint.PrinterSettings.PaperSizes;
 24             paperSize = pageSize[pageSize.Count - 1];
 25 
 26             // 列印方向設定
 27             //imgToPrint.DefaultPageSettings.Landscape = false;
 28             // 列印紙張大小設定
 29             //imgToPrint.DefaultPageSettings.PaperSize = paperSize;
 30             // 列印分辨率設定
 31             //imgToPrint.DefaultPageSettings.PrinterResolution.Kind = PrinterResolutionKind.High;
 32             // 列印邊距設定
 33             //imgToPrint.DefaultPageSettings.Margins = new Margins(40, 40, 40, 40);
 34 
 35             // 列印開始事件
 36             imgToPrint.BeginPrint += new PrintEventHandler(this.imgToPrint_BeginPrint);
 37             // 列印結束事件
 38             imgToPrint.EndPrint += new PrintEventHandler(this.imgToPrint_EndPrint);
 39             // 列印内容設定
 40             imgToPrint.PrintPage += new PrintPageEventHandler(this.imgToPrint_PrintPage);
 41             #endregion
 42 
 43             // 直接列印
 44             //imgToPrint.Print();
 45 
 46             // 列印彈框确認
 47             //PrintDialog printDialog = new PrintDialog();
 48             //printDialog.AllowSomePages = true;
 49             //printDialog.ShowHelp = true;
 50             //printDialog.Document = imgToPrint;
 51             //if (printDialog.ShowDialog() == DialogResult.OK)
 52             //{
 53             //    imgToPrint.Print();
 54             //}
 55 
 56             // 預覽列印
 57             //PrintPreviewDialog pvDialog = new PrintPreviewDialog();
 58             //pvDialog.Document = imgToPrint;
 59             //pvDialog.ShowDialog();
 60         }
 61 
 62         /// <summary>
 63         /// 列印開始事件
 64         /// </summary>
 65         /// <param name="sender"></param>
 66         /// <param name="e"></param>
 67         private void imgToPrint_BeginPrint(object sender, PrintEventArgs e)
 68         {
 69             if (imageList.Count == 0)
 70                 imageList.Add(imageFile);
 71         }
 72 
 73         /// <summary>
 74         /// 列印結束事件
 75         /// </summary>
 76         /// <param name="sender"></param>
 77         /// <param name="e"></param>
 78         private void imgToPrint_EndPrint(object sender, PrintEventArgs e)
 79         {
 80 
 81         }
 82 
 83         /// <summary>
 84         /// 設定列印内容
 85         /// </summary>
 86         /// <param name="sender"></param>
 87         /// <param name="e"></param>
 88         private void imgToPrint_PrintPage(object sender, PrintPageEventArgs e)
 89         {
 90             // 圖檔文本品質
 91             e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
 92             // 圖檔插值品質
 93             e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
 94             // 圖檔合成品質
 95             e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
 96             // 圖檔抗鋸齒
 97             e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
 98             // 設定縮放比例
 99             e.Graphics.PageScale = 0.3F;
100             using (Stream fs = new FileStream(imageList[printNum].ToString().Trim(), FileMode.Open, FileAccess.Read))
101             {
102                 System.Drawing.Image image = System.Drawing.Image.FromStream(fs);
103                 int w = image.Width;
104                 int h = image.Height;
105                 // 繪制Image
106                 e.Graphics.DrawImage(image, 40, 40, 410, 600);
107                 if (printNum < imageList.Count - 1)
108                 {
109                     printNum++;
110                     // HasMorePages為true則再次運作PrintPage事件
111                     e.HasMorePages = true;
112                     return;
113                 }
114                 e.HasMorePages = false;
115             }
116             // 設定列印内容的邊距
117             //e.PageSettings.Margins = new Margins(40, 40, 40, 40);
118             // 設定是否橫向列印
119             e.PageSettings.Landscape = false;
120             // 設定紙張大小
121             e.PageSettings.PaperSize = paperSize;
122             // 設定列印分辨率
123             e.PageSettings.PrinterResolution.Kind = PrinterResolutionKind.High;
124         }
125     }      

以上就是 Html轉圖檔,然後通過PrintDocument列印圖檔 的實作代碼了。其它兩種方式大家有興趣可以去試試。

WebBrowser 比較簡單,但是對列印機控制不是特别友好(也可能是我沒有發現,研究不深)

1             WebBrowser wb = new WebBrowser();
2             // 直接列印
3             wb.Print();
4             // 确認列印
5             wb.ShowPrintDialog();
6             // 預覽列印
7             wb.ShowPrintPreviewDialog();      

Html轉PDF,然後列印PDF原理于Html轉圖檔,然後通過PrintDocument列印圖檔一樣,不同的是轉PDF可能需要用到第三方的包,目前這友善的包還是比較齊全的,NUGET搜尋pdf幾乎全是。

Web列印插件實作思路(C#/Winform)

需求總是來得特别突然,下次再有新特别需求時再來和大家分享。

以上就是這篇文章的全部内容了,有幫助的點個贊,有錯誤的歡迎大家指出來,有更好的解決方案也希望大家不吝賜教。

無緒分享