C# aspose word实现模板方式打印及打印速度慢解决方法
1.引用dll
nuget或者网上都有下载的方式。不过都要收费。下载地址:https://files.cnblogs.com/files/rolayblog/Tool.zip?t=1713322422&download=true
2.打印模板设计
新建一个doc文档,根据自己的需求画页面。
A、普通文本
在word中需要替换值的地方添加书签,插入>书签,书签名字最好是值的关键字。
B、图片,图片的方式和普通文本一样,使用书签占位。
C、表格,实际业务中,肯定会有拿到一个list动态把所有的数据渲染到表格上面,一组数据一行。这时候需要用到域。(office)插入>文档部件>域
找到MergeField,aspose中会用TableStart和TableEnd来确定table域的工作范围,开始和结束,其中数据集合的命名放在start和end之后,类似于:TableStart:userList,这个非常重要,然后表格中每个需要填充的数据都要加上域,
域名和书签类似,使用关键字即可。我这边的配置结果如下:
3、数据填充
A、模板文档加载
string tempFile = System.Windows.Forms.Application.StartupPath + "/temp/tempA4.docx"; Document doc = new Document(tempFile);
B、普通文本填充
Dictionary<string, string> dic = new Dictionary<string, string>(); dic.Add("address", item.address); dic.Add("age", patient.age); foreach (var key in dic.Keys) //循环键值对 { builder.MoveToBookmark(key); //将光标移入书签的位置 builder.Write(dic[key]); //填充值 }
C、图片填充
builder.InsertImage(imgData);
D、表格数据填充
DataTable userTable = new DataTable("list"); userTable.Columns.Add(new DataColumn("sortIndex", typeof(int))); userTable.Columns.Add("checkItemName"); userTable.Columns.Add("appointmentTime"); userTable.Columns.Add("address"); userTable.Columns.Add("itemNotice"); userTable.Rows.Add(1, "腹部超声检查", "2024年5月2日 11:00-12:00", "三楼骨科", "我是一个注意事项"); userTable.Rows.Add(2, "腹部超声检查2", "2024年5月2日 11:00-12:002", "三楼骨科2", "我是一个注意事项2"); userTable.Rows.Add(2, "腹部超声检查2", "2024年5月2日 11:00-12:002", "三楼骨科2", "我是一个注意事项2"); userTable.Rows.Add(2, "腹部超声检查2", "2024年5月2日 11:00-12:002", "三楼骨科2", @"1、病人先挂号、看病、医生开出CT和 MRI申请单,可以医生诊间预约。 2、请于申请当日到自助机缴费或收费窗口交费,到3号二楼检查集中预约中心预约。 3、检查当日持预约申请单提前10 - 15分钟到规定检查室前确认后进行检查。 6、检查完毕后,按规定时间持取片卡号,到CT MRI登记室取片及结果。 "); userTable.Rows.Add(2, "腹部超声检查2", "2024年5月2日 11:00-12:002", "三楼骨科2", @"1、病人先挂号、看病、医生开出CT和 MRI申请单,可以医生诊间预约。 2、请于申请当日到自助机缴费或收费窗口交费,到3号二楼检查集中预约中心预约。 3、检查当日持预约申请单提前10-15分钟到规定检查室前确认后进行检查。 6、检查完毕后,按规定时间持取片卡号,到CT MRI登记室取片及结果。 "); userTable.Rows.Add(2, "腹部超声检查2", "2024年5月2日 11:00-12:002", "三楼骨科2", "我是一个注意事项2"); DataSet dataSet = new DataSet(); dataSet.Tables.Add(userTable); doc.MailMerge.ExecuteWithRegions(dataSet);
以上就是模板处理的方式和代码。
3、aspose word Document 内置实现了print方法,调用windows的打印方法,用过这个的应该都知道每次第一次打印的时候都要等几秒,有时候长达五秒,因为我这里是浏览器打开exe打印,每次打印完成后关闭exe。等于是每次都是重新打开。每次都很慢。
4、我这边实现了一个socket服务端,这个服务端来负责打印,而浏览器打开的exe只负责拿到参数,把参数发送和socket服务端后就可以自己关闭了,socket服务端拿到数据就打印,这样只有第一次打开的时候需要五秒,后面基本1秒足左右都能打印出来。
5、sockt服务端代码
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace PrintService { public class TcpServer { private TcpListener tcpListener; private Thread listenThread; private TcpClient tcpClient; public TcpServer(int port) { IPAddress ipAddress = IPAddress.Any; tcpListener = new TcpListener(ipAddress, port); } public void Start() { tcpListener.Start(); Console.WriteLine("服务端已启动,等待客户端连接..."); listenThread = new Thread(new ThreadStart(ListenForClients)); listenThread.Start(); } public void sendMessage() { if (tcpClient.Connected) { string heartbeatMessage = "suncess"; byte[] heartbeatData = Encoding.ASCII.GetBytes(heartbeatMessage); // 发送消息给客户端 tcpClient.GetStream().Write(heartbeatData, 0, heartbeatData.Length); } } private void ListenForClients() { while (true) { TcpClient client = tcpListener.AcceptTcpClient(); Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCommunication)); clientThread.Start(client); } } private void HandleClientCommunication(object client) { tcpClient = (TcpClient)client; string clientEndPoint = tcpClient.Client.RemoteEndPoint.ToString(); Console.WriteLine("客户端 {0} 已连接。", clientEndPoint); NetworkStream clientStream = tcpClient.GetStream(); byte[] buffer = new byte[4096]; while (true) { try { int bytesRead = clientStream.Read(buffer, 0, buffer.Length); if (bytesRead == 0) { Console.WriteLine("客户端 {0} 已断开连接。", clientEndPoint); break; } string recvStr = Encoding.UTF8.GetString(buffer, 0, bytesRead); Task t = new Task(() => { PrintDataUtil.DoPrint(recvStr); }); t.Start(); } catch (Exception ex) { Console.WriteLine("与客户端 {0} 的连接发生异常: {1}", clientEndPoint, ex.Message); break; } } tcpClient.Close(); } } }
6、socket服务端使用
TcpServer tcpServer = new TcpServer(6879); tcpServer.Start();
7、sokcet客户端代码
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Windows.Forms; namespace AutoPrint { public class MyTcpClient { private TcpClient tcpClient; public MyTcpClient() { } public void Connect(string ipAddress, int port) { tcpClient = new TcpClient(); tcpClient.Connect(IPAddress.Parse(ipAddress), port); Console.WriteLine("与服务端连接成功!"); } public void SendMessage(string message) { if (tcpClient.Connected) { byte[] messageData = Encoding.ASCII.GetBytes(message); tcpClient.GetStream().Write(messageData, 0, messageData.Length); } } public void CloseConnect() { if (tcpClient.Connected) { tcpClient.Close(); } } } }
8、sokcet客户端使用
public Form1(string[] args) { InitializeComponent(); MyTcpClient myTcpClient = new MyTcpClient(); try { int startIndex = args[0].IndexOf("$"); string paramStr = ""; if (startIndex >= 0 && startIndex < args[0].Length) { paramStr = args[0].Substring(startIndex).Replace("$", "").Replace("/", ""); // 从"$"后面的位置开始截取到字符串结束 myTcpClient.Connect("127.0.0.1", 6879); myTcpClient.SendMessage(paramStr); } else { MessageBox.Show("无效参数!"); System.Environment.Exit(0); return; } } finally { Thread.Sleep(500); myTcpClient.CloseConnect(); this.Close(); System.Environment.Exit(0); } }
本文来自博客园,作者:Rolay,转载请注明原文链接:https://www.cnblogs.com/rolayblog/p/18140161