效果展示:
需求描述:
具体实现
开发环境:
一 、 .net 4.7.1
二 、 vs2019
- 网页js测试代码(复制即可用)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<style>
button {
width: 350px;
height: 32px;
background: #00F7DE;
border: none;
outline: none;
color: #000;
font-size: 10pt;
font-weight: 600;
border-radius: 3px;
cursor: pointer;
}
button:hover {
background: #00cccc;
}
</style>
</head>
<body style="padding: 1.3rem">
<button>发送打印</button>
</body>
<script>
// ip: 'ws://127.0.0.1:7081',
let dataList = [];
dataList.push({name: "小辣椒", number: 12});
dataList.push({name: "西瓜", number: 10});
dataList.push({name: "粉皮", number: 14});
dataList.push({name: "薯片", number: 17});
dataList.push({name: "鸡枞菌", number: 20});
dataList.push({name: "牛肝菌", number: 38});
dataList.push({name: "虎皮鸡蛋", number: 22});
let printeData = {
address: "广东佛山xx街道zz号",
datas: dataList
};
var ws = new WebSocket("ws://127.0.0.1:7081");//创建一个实例
ws.onopen = function (evt) {//用于指定连接成功后的回调函数
console.log("Connection open ...");
};
ws.onclose = function (event) {//用于指定连接关闭后的回调函数
var code = event.code;
var reason = event.reason;
var wasClean = event.wasClean;
};
ws.onmessage = function (event) {//用于指定收到服务器数据后的回调函数
var data = event.data;
};
$('button').on('click', function () {
if (ws.readyState !== 1) {
console.log('链接未打开');
return false;
}
ws.send(JSON.stringify(printeData));
});
</script>
</html>
- c#本地服务端打印核心代码
namespace PrinterDemo.Utils
{
class PrinterUtils
{
public delegate void myPrintEventHandler(PrinterData printerData);
private static PrinterUtils printer;
private double widthCm = 56;
private int marginTop = 10;
private int right = 45;
private int lineHeight = 14;//行高
private Font printFont; //当前的打印字体
private SolidBrush myBrush;//刷子
private StringFormat stringFormat;
private PrintDocument pd;
private PrinterData printerData;
public static PrinterUtils getInstance()
{
if (printer == null)
printer = new PrinterUtils();
return printer;
}
public PrinterUtils()
{
initSetting();
}
public void setPrinterName(String name)
{
pd.DefaultPageSettings.PrinterSettings.PrinterName = name;
}
private void initSetting()
{
printFont = new Font("华文行楷", 9, FontStyle.Regular); //当前的打印字体
pd = new PrintDocument();
// pd.PrintController = new System.Drawing.Printing.StandardPrintController();
pd.DefaultPageSettings.Margins =
new Margins(0, 0, marginTop, 0); //设置边距;
pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
myBrush = new SolidBrush(Color.Black);//刷子
stringFormat = new StringFormat();
}
/// <summary>
/// 返回 mm单位数值
/// </summary>
/// <param name="cm"></param>
/// <returns></returns>
private int getYc(double cm)
{
return (int)(cm / 25.4) * 100;
}
public void Print(PrinterData data)
{
this.printerData = data;
var height = (printerData.getRows()+7) * (lineHeight)+80;
纸张设置
pd.DefaultPageSettings.PaperSize =
new PaperSize("自定义纸张", getYc(widthCm), height);
//打印预览
PrintPreviewDialog ppd = new PrintPreviewDialog();
//打印事件设置
ppd.Document = pd;
try
{
ppd.ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
//try
//{
// pd.Print();
//}
//catch (Exception ex)
//{
// MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
// pd.PrintController.OnEndPrint(pd, new PrintEventArgs());
//}
}
public void pd_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics; //获得绘图对象
float yPosition = marginTop; //绘制字符串的纵向位置e.MarginBounds.Top
float pageWidth = e.PageBounds.Width;
printFooter(g, pageWidth, printBody(g, pageWidth, printHead(g, pageWidth, yPosition)));
}
public float printHead(Graphics g, float pageWidth, float yPosition)
{
g.DrawString("小票标题", printFont, myBrush, (pageWidth - g.MeasureString("小票标题", printFont).Width) / 2, yPosition, stringFormat);
yPosition += lineHeight;
g.DrawString("------------------------------------------", printFont, myBrush, 0, yPosition, stringFormat);
yPosition += lineHeight;
g.DrawString("日期:" + DateTime.Now.ToShortDateString(), printFont, myBrush, 0, yPosition, stringFormat);
yPosition += lineHeight;
g.DrawString("地址:" + printerData.Address, printFont, myBrush, 0, yPosition, stringFormat);
yPosition += lineHeight;
g.DrawString("------------------------------------------", printFont, myBrush, 0, yPosition, stringFormat);
yPosition += lineHeight;
return yPosition;
}
public float printBody(Graphics g, float pageWidth, float yPosition)
{
g.DrawString("名称", printFont, myBrush, 0, yPosition, stringFormat);
g.DrawString("数量", printFont, myBrush, pageWidth - right, yPosition, stringFormat);
yPosition += lineHeight;
for (int i = 0; i < printerData.Datas.Count; i++)
{
Data data = printerData.Datas[i];
if (data.Name.Length > 10)
{
var start = data.Name.Substring(0, 10);
var end = data.Name.Substring(10);
g.DrawString(start, printFont, myBrush, 0, yPosition, stringFormat);
yPosition += lineHeight;
g.DrawString(end, printFont, myBrush, 0, yPosition, stringFormat);
g.DrawString("*" + data.Number, printFont, myBrush, pageWidth - right, yPosition - lineHeight / 2 - 5, stringFormat);
}
else
{
g.DrawString(data.Name, printFont, myBrush, 0, yPosition, stringFormat);
g.DrawString("*" + data.Number, printFont, myBrush, pageWidth - right, yPosition - lineHeight / 3, stringFormat);
}
yPosition += lineHeight ;
}
g.DrawString("------------------------------------------", printFont, myBrush, 0, yPosition, stringFormat);
yPosition += lineHeight ;
g.DrawString("总数量:" + printerData.getCount(), printFont, myBrush, 0, yPosition, stringFormat);
yPosition += lineHeight;
return yPosition;
}
public float printFooter(Graphics g, float pageWidth, float yPosition)
{
yPosition += 30;
g.DrawString("谢谢惠顾,\\(^o^)/", printFont, myBrush, (pageWidth - g.MeasureString("谢谢惠顾,\\(^o^)/", printFont).Width) / 2,
yPosition , stringFormat);
return yPosition;
}
}
}
//
别处调用:
private event myPrintEventHandler PrintEvent; //定义事件
this.PrintEvent += new myPrintEventHandler(PrinterUtils.getInstance().Print);//捆绑
PrintEvent(data); //调用
- C# Websocket服务端实现(Fleck)
namespace PrinterDemo.Utils
{
class OpenFleckPrinter
{
private static OpenFleckPrinter testFleck;
private WebSocketServer server;
private IDictionary<string, IWebSocketConnection> dic_Sockets;
private event myPrintEventHandler PrintEvent;
private StreamWriter resultMessage;
public OpenFleckPrinter()
{
Init();
}
public void WriteMsg(string msg)
{
resultMessage.WriteLine(msg);
}
public static OpenFleckPrinter GetInstance()
{
if (testFleck == null)
{
testFleck = new OpenFleckPrinter();
}
return testFleck;
}
public void Init()
{
dic_Sockets = new Dictionary<string, IWebSocketConnection>();//客户端url以及其对应的Socket对象字典
server = new WebSocketServer("ws://0.0.0.0:7081");//创建服务监听所有的的地址 //出错后进行重启
server.RestartAfterListenError = true;
this.PrintEvent += new myPrintEventHandler(PrinterUtils.getInstance().Print);
resultMessage = new StreamWriter("out.txt", true);
}
public void Start()
{
//开始监听
server.Start(socket =>
{
socket.OnOpen = () => //连接建立事件
{
//获取客户端网页的url
string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
dic_Sockets.Add(clientUrl, socket);
WriteMsg(DateTime.Now.ToString() + "|服务器:和客户端网页:" + clientUrl + " 建立WebSock连接!");
};
socket.OnClose = () => //连接关闭事件
{
string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
//如果存在这个客户端,那么对这个socket进行移除
if (dic_Sockets.ContainsKey(clientUrl))
{
//注:Fleck中有释放
//关闭对象连接
//if (dic_Sockets[clientUrl] != null)
//{
//dic_Sockets[clientUrl].Close();
//}
dic_Sockets.Remove(clientUrl);
}
WriteMsg(DateTime.Now.ToString() + "|服务器:和客户端网页:" + clientUrl + " 断开WebSock连接!");
};
socket.OnMessage = message => //接受客户端网页消息事件
{
string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
PrinterData data = JsonHelper.DeserializeJsonToObject<PrinterData>(message);
// WriteMsg(DateTime.Now.ToString() + "|服务器:【收到】来客户端网页:" + clientUrl + " 的信息:\n" + data.ToString());
//MessageBox.Show(data.ToString());
PrintEvent(data);
if (dic_Sockets.ContainsKey(clientUrl))
{
//注:Fleck中有释放
//关闭对象连接
if (dic_Sockets[clientUrl] != null)
{
dic_Sockets[clientUrl].Send("{\"code\":\"success\"}");
}
}
};
});
}
}
}