FastReport+WebSocket实现浏览器打印


已知浏览器打印方式

1.windows.print()

  对样式支持不好,一次只能打印整个页面,实现多页打印需要自己再封装

2.后台生成pdf或excel,客户端使用相应程序打开文件后打印

  操作麻烦,用户体验不好

3.ActiveX

  浏览器兼容性不好

4.封装浏览器

  不松耦合

5.浏览器通过websocket发送数据给本地打印程序,实现打印

  可以利用已有的FastReport的报告单文件,对于浏览器的兼容性也还可以

功能实现

  websocket的实现网上可以找到很多,就不详细说。因为FastReport支持SaveToString方法将报告单文件保存为字符串,这样我们可以将报表文件以字符串的格式存储再数据库中,同时FastReport支持RegisterData(IEnumerable data, string name)方法,可以很方便的实现数据源注册。我们要做的就是将报表文件以及数据以一定格式传递给打印程序,打印程序加以解析,再完成报表加载及注册数据源就可以了

  核心代码

 1     public class DDReport
 2     {
 3         public DDReport(string src)
 4         {
 5             var strs = src.Split('@');
 6             if (strs.Length != 2)
 7             {
 8                 throw new ArgumentException("消息格式错误");
 9             }
10             
11             var report = strs[0];
12             var strSources = strs[1];
13             _report = new Report();
14             _report.LoadFromString(report);
15 
16             _source = JsonUtil.DeserializeStringToDictionary<string, List<dynamic>>(strSources);
17 
18             foreach (var item in _source)
19             {
20                 _report.RegisterData(item.Value, item.Key);
21             }
22         }
23        
24         private Report _report { get; set; }
25         private Dictionary<string,List<dynamic>> _source { get; set; }
26 
27         public void Print()
28         {
29             _report.Show();
30             _report.Dispose();
31             _report = null;
32         }
33     }
DDReport对FastReport进行了简单的封装,通过构造函数实现了加载报告单,以及注册数据源。

 1         public delegate void Print(string crc);
 2         
 3         WebSocketServer server;
 4         List allSockets = new List();
 5         private void StartHub()
 6         {
 7             FleckLog.Level = LogLevel.Debug;
 8             Print print = new Print(PrintR);
 9             server = new WebSocketServer("ws://0.0.0.0:7181");
10             server.Start(socket =>
11             {
12                 socket.OnOpen = () =>
13                 {
14                     Console.WriteLine("Open!");
15                     allSockets.Add(socket);
16                 };
17                 socket.OnClose = () =>
18                 {
19                     Console.WriteLine("Close!");
20                     allSockets.Remove(socket);
21                 };
22                 socket.OnMessage = message =>
23                 {
24                     Console.WriteLine(message);
25                     try
26                     {
27                         DDMsg m = new DDMsg(message);
28                         switch (m.Type)
29                         {
30                             case Start:
31 
32                                 break;
33                             case PrintReport:
34 
35                                 Thread thread = new Thread(new ParameterizedThreadStart(PrintR));
36                                 thread.SetApartmentState(ApartmentState.STA); 
37                                 thread.Start(m.Content);
38 
39                                 break;
40                             default:
41                                 break;
42                         }
43                     }
44                     catch (Exception ex)
45                     {
46                         Console.WriteLine(ex.Message);
47                     }
48                 };
49             });
50 
51         }
52 
53         private void PrintR(object content)
54         {
55             lock (this)
56             {
57                 DDReport dDReport = new DDReport((string)content);
58                 dDReport.Print();
59             }
60         }