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 ListallSockets = 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 }