最近,客戶有個需求過來,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幾乎全是。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcugzMxgjNwUjN10SMzczNxcTM0ETNxYDMxIDMy0CN0gTOzUTMvwlNwEjMwIzLcRDN4kzM1EzLcd2bsJ2Lc12bj5ycn9Gbi52YuAjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
需求總是來得特别突然,下次再有新特别需求時再來和大家分享。
以上就是這篇文章的全部内容了,有幫助的點個贊,有錯誤的歡迎大家指出來,有更好的解決方案也希望大家不吝賜教。
無緒分享