作者:南塘所有的经筒 | 来源:互联网 | 2023-06-03 09:25
已知浏览器打印方式1.windows.print()对样式支持不好,一次只能打印整个页面,实现多页打印需要自己再封装2.后台生成pdf或excel,客户端使用相应程序打开文件后
已知浏览器打印方式
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 }
原文链接:https://www.cnblogs.com/sunwayj/p/15580223.html