此文章给出两种打印案例,
第一种是单列打印,第二种是双列打印
需要注意打印机名称的设置,程序中使用的打印机名称为999,电脑中安装打印机时名称也要为999。
以下是我在使用过程中总结的一些问题:
一 TSC打印机使用使用过程中遇到的问题
1、打印机刚连上就报警。
一般是纸张或色带安装有问题,纸张要放到档杆的下方。
2、打印机显示正常,DiagTool工具无法连接到打印机,无论点什么都提示“Port Open Error”。
如果使用USB模式,需要用线把打印机和电脑连接起来,同时打印机需插上网线。工具中,通讯接口选择USB,点击“读取状态”,正常显示待机中,点击“读取”,会重置工具中的各参数。
点击“网络设定”,指定IP地址,这里设置为192.168.50.222
如果用服务器连接打印机,这个时候已经添加了打印机,登录服务器,找到打印机,打开打印机属性-端口,打印机名称或ip地址设置为与打印机ip一致即可。
3、打印机打印完成后报警。
检查纸张,纸张安装过紧或档条没压住纸,都会导致此问题。
接下来上代码
二 打印方式
2.1 单列打印
这种打印方式示例中,打印的位置是可以配置的
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Imagine.Mes.MesTrackV3.Application.CommonTool;
using Imagine.Mes.MesTrackV3.Application.Dtos;
using Volo.Abp.DependencyInjection;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;namespace Imagine.Mes.MesTrackV3.Application.Services
{/// <summary>/// 打印服务/// </summary>public interface IPrintService{/// <summary>/// 打印流程卡/// </summary>/// <param name="printType">打印枚举 0-二维码;1-条形码</param>/// <param name="body">流程卡集合</param>/// <returns></returns>Task PrintLotAsync(PrintEnum printType, List<PrintLotInDto> body);}public class PrintService : IPrintService,IScopedDependency{private readonly ILogger<PrintService> _logger;public PrintService(ILogger<PrintService> logger){_logger = logger;}#region 打印流程卡/// <summary>/// 打印流程卡/// </summary>/// <param name="printType">打印枚举 0-二维码;1-条形码</param>/// <param name="body">流程卡集合</param>/// <returns></returns>/// <exception cref="Exception"></exception>public async Task PrintLotAsync(PrintEnum printType, List<PrintLotInDto> body){try{List<PrintLotInDto> printOutboundOrderList = new List<PrintLotInDto>();var jsonObject=await GetJsonFileAsync("CommonTool\\PrintLot.json");for (int i = 0; i < body.Count; i++){await PrintLotAsync(printType,jsonObject, new PrintLotInDto{LotNo = body[i].LotNo,ProductCode = body[i].ProductCode,ProductName = body[i].ProductName,Quantity = body[i].Quantity,WorkOrderNo = body[i].WorkOrderNo,UnitName= body[i].UnitName});}}catch (Exception ex){_logger.LogError($"打印流程卡错误:{ex}");throw new Exception($"打印流程卡错误:{ex.Message}");}}/// <summary>/// 打印流程卡/// </summary>/// <param name="printType">打印类型:0-二维码;1-条形码</param>/// <param name="jsonObject"></param>/// <param name="param"></param>/// <returns></returns>private async Task PrintLotAsync(PrintEnum printType, JObject jsonObject, PrintLotInDto param){#region 模板string port = "999";string currentEncoding = "utf-16";string chineseFont = "宋体";byte[] lotNo = Encoding.GetEncoding(currentEncoding).GetBytes($"批 次 号:{param.LotNo}");byte[] productCode = Encoding.GetEncoding(currentEncoding).GetBytes($"产品编码:{param.ProductCode}");byte[] productName = Encoding.GetEncoding(currentEncoding).GetBytes($"产品名称:{param.ProductName}");byte[] quantity = Encoding.GetEncoding(currentEncoding).GetBytes($"数 量:{param.Quantity} {param.UnitName}");byte[] workOrderNo = Encoding.GetEncoding(currentEncoding).GetBytes($"工 单 号:{param.WorkOrderNo}");byte[] date = Encoding.GetEncoding(currentEncoding).GetBytes($"打印日期:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");byte status = TSCLIB_DLL.usbportqueryprinter();//0 = idle, 1 = head open, 16 = pause, following <ESC>!? command of TSPL manual//打印机共享名999int openport = TSCLIB_DLL.openport(@$"{port}");//M 纸张宽度 ,N 纸张高度TSCLIB_DLL.sendcommand("SIZE 100 mm, 80 mm");TSCLIB_DLL.sendcommand("SPEED 4");TSCLIB_DLL.sendcommand("DENSITY 12");TSCLIB_DLL.sendcommand("DIRECTION 1");TSCLIB_DLL.sendcommand("SET TEAR ON");TSCLIB_DLL.sendcommand("CODEPAGE UTF-8");TSCLIB_DLL.clearbuffer();if (printType == PrintEnum.QRCode)//打印二维码{//文字(x边距,y边距,字体高度,旋转,字体样式,下划线,字体,文字内容)TSCLIB_DLL.windowsfontUnicode(Convert.ToInt32(jsonObject["lotNo"]["x"]), Convert.ToInt32(jsonObject["lotNo"]["y"]), Convert.ToInt32(jsonObject["lotNo"]["size"]), 0, 0, 0, chineseFont, lotNo);TSCLIB_DLL.windowsfontUnicode(Convert.ToInt32(jsonObject["productCode"]["x"]), Convert.ToInt32(jsonObject["productCode"]["y"]), Convert.ToInt32(jsonObject["productCode"]["size"]), 0, 0, 0, chineseFont, productCode);TSCLIB_DLL.windowsfontUnicode(Convert.ToInt32(jsonObject["productName"]["x"]), Convert.ToInt32(jsonObject["productName"]["y"]), Convert.ToInt32(jsonObject["productName"]["size"]), 0, 0, 0, chineseFont, productName);TSCLIB_DLL.windowsfontUnicode(Convert.ToInt32(jsonObject["quantity"]["x"]), Convert.ToInt32(jsonObject["quantity"]["y"]), Convert.ToInt32(jsonObject["quantity"]["size"]), 0, 0, 0, chineseFont, quantity);TSCLIB_DLL.windowsfontUnicode(Convert.ToInt32(jsonObject["workOrderNo"]["x"]), Convert.ToInt32(jsonObject["workOrderNo"]["y"]), Convert.ToInt32(jsonObject["workOrderNo"]["size"]), 0, 0, 0, chineseFont, workOrderNo);TSCLIB_DLL.windowsfontUnicode(Convert.ToInt32(jsonObject["date"]["x"]), Convert.ToInt32(jsonObject["date"]["y"]), Convert.ToInt32(jsonObject["date"]["size"]), 0, 0, 0, chineseFont, date);//二维码//QRCODE x,y,ECC Level,cell width(二维码大小),mode,rotation(旋转),[model,mask,]"content"TSCLIB_DLL.sendcommand($"QRCODE {Convert.ToInt32(jsonObject["qRCode"]["x"])},{Convert.ToInt32(jsonObject["qRCode"]["y"])},H,{Convert.ToInt32(jsonObject["qRCode"]["size"])},A,0,M2,\"{param.LotNo}\"");}else// 打印条码.{// 在 (450, 200) 的坐标上// 以 Code128 的条码方式// 条码高度 300// 打印条码的同时,还打印条码的文本信息.// 旋转的角度为 0 度// 条码 宽 窄 比例因子为 7:7// 条码内容为:barCode//BARCODE X,Y,”code type”,height,human readable,rotation,narrow,wide,[alignment,]”content“TSCLIB_DLL.barcode("30", "30", "128", "180", "1", "0", "6", "6", $"{param.LotNo}");}//TSCLIB_DLL.sendcommand(String.Format("QRCODE 740,320,H,8,A,0,M2,\"{0}\"", trayCode));//DMATRIX码 。DMATRIX 命令,740,320,90,90 指定 X 坐标,指定 Y 坐标,条码区域宽度//TSCLIB_DLL.sendcommand($"DMATRIX 740,320,90,90,x18,30,30,\"{trayCode}\"");int printlabel = TSCLIB_DLL.printlabel("1", "1");TSCLIB_DLL.closeport();#endregionawait Task.CompletedTask;}#endregion 打印流程卡#region 获取json文件内容private async Task<JObject> GetJsonFileAsync(string path){try{// 获取文件的绝对路径string filePath = Path.Combine(AppContext.BaseDirectory, path);string jsonContent = string.Empty;//json内容var exists = System.IO.File.Exists(filePath);if (!exists) throw new Exception($"配置文件[{path.Split("\\")[path.Split("\\").Length - 1]}]不存在");// 读取文件的内容using (StreamReader file = File.OpenText(filePath)){jsonContent = await file.ReadToEndAsync();}// 解析JSON到JObjectJObject jsonObj = JObject.Parse(jsonContent);// 反序列化//var plcModel = JsonConvert.DeserializeObject<List<PLCModel>>(jsonContent);return jsonObj;}catch (Exception ex){_logger.LogError(ex.ToString(), ex);throw new Exception(ex.Message);}}#endregion}
}
/// <summary>
/// 打印流程卡
/// </summary>
public class PrintLotInDto
{/// <summary>/// 批次号/// </summary>public string LotNo { get; set; }/// <summary>/// 产品名称/// </summary>public string ProductName { get; set; }/// <summary>/// 产品编码/// </summary>public string ProductCode { get; set; }/// <summary>/// 数量/// </summary>public int Quantity { get; set; }/// <summary>/// 工单号/// </summary>public string WorkOrderNo { get; set; }/ <summary>/ 打印日期/ </summary>//public DateTime Date { get; set; }/// <summary>/// 单位名称/// </summary>public string UnitName { get; set; }
}/// <summary>
/// 打印枚举
/// </summary>
public enum PrintEnum
{QRCode = 0,//二维码BarCode = 1//条形码
}
PrintLot.json文件内容
{//批次号"lotNo": {"x": 430, //x坐标"y": 320, //y坐标"size": 50 //字体大小},//产品编码"productCode": {"x": 230,"y": 400,"size": 50},//产品名称"productName": {"x": 230,"y": 480,"size": 50},//数量"quantity": {"x": 230,"y": 560,"size": 50},//工单号"workOrderNo": {"x": 230,"y": 640,"size": 50},//打印日期"date": {"x": 230,"y": 720,"size": 50},//二维码"qRCode": {"x": 450,"y": 30,"size": 10 //二维码大小}
}
2.2 双列打印
using Imagine.Mes.MesBase.Application.CommonTool;
using Imagine.Mes.MesBase.Application.Dtos;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;namespace Imagine.Mes.MesBase.Application.Services
{public interface IPrintService{/// <summary>/// 打印库位信息/// </summary>/// <param name="printType"></param>/// <param name="body"></param>/// <returns></returns>Task PrintWarehouselocationsAsync(PrintTypeEnum printType, List<WarehouseLocationNoParam> body);}public class PrintService : IPrintService, ITransientDependency{private readonly ILogger<PrintService> _logger;public PrintService(ILogger<PrintService> logger){_logger = logger;}public async Task PrintWarehouselocationsAsync(PrintTypeEnum printType, List<WarehouseLocationNoParam> body){try{List<PrintWarehouseLocationParam> printQualityInspectionList = new List<PrintWarehouseLocationParam>();for (int i = 0; i < body.Count; i += 2){PrintWarehouseLocationParam printQualityInspection = new PrintWarehouseLocationParam();printQualityInspection.QRCodeContent = body[i].QRCodeContent;printQualityInspection.WarehouseLocationName = body[i].WarehouseLocationName;printQualityInspection.WarehouseLocationNo = body[i].WarehouseLocationNo;printQualityInspection.QRCodeContent2 = i + 1 < body.Count ? body[i + 1].QRCodeContent : null;printQualityInspection.WarehouseLocationName2 = i + 1 < body.Count ? body[i + 1].WarehouseLocationName : null;printQualityInspection.WarehouseLocationNo2 = i + 1 < body.Count ? body[i + 1].WarehouseLocationNo : null;printQualityInspectionList.Add(printQualityInspection);await PrintWarehouselocationAsync(printType, new PrintWarehouseLocationParam{QRCodeContent = printQualityInspection.QRCodeContent,WarehouseLocationName = printQualityInspection.WarehouseLocationName,WarehouseLocationNo = printQualityInspection.WarehouseLocationNo,QRCodeContent2 = printQualityInspection.QRCodeContent2,WarehouseLocationName2 = printQualityInspection.WarehouseLocationName2,WarehouseLocationNo2 = printQualityInspection.WarehouseLocationNo2});}}catch (Exception ex){_logger.LogError($"打印质检单/入库单错误:{ex}");}}/// <summary>/// 打印出库单/入库单/// </summary>/// <param name="printType">打印类型:0-二维码;1-条形码</param>/// <param name="param"></param>/// <returns></returns>private async Task PrintWarehouselocationAsync(PrintTypeEnum printType, PrintWarehouseLocationParam param){#region 模板string port = "999";string currentEncoding = "utf-16";string chineseFont = "宋体";byte[] warehouseLocationNo = null;byte[] warehouseLocationName = null;byte[] warehouseLocationNo2 = null;byte[] warehouseLocationName2 = null;warehouseLocationNo = Encoding.GetEncoding(currentEncoding).GetBytes($"{param.WarehouseLocationNo}");warehouseLocationName = Encoding.GetEncoding(currentEncoding).GetBytes($"{param.WarehouseLocationName}");warehouseLocationNo2 = Encoding.GetEncoding(currentEncoding).GetBytes($"{param.WarehouseLocationNo2}");warehouseLocationName2 = Encoding.GetEncoding(currentEncoding).GetBytes($"{param.WarehouseLocationName2}");byte status = TSCLIB_DLL.usbportqueryprinter();//0 = idle, 1 = head open, 16 = pause, following <ESC>!? command of TSPL manual//打印机共享名999int openport = TSCLIB_DLL.openport(@$"{port}");//M 纸张宽度 ,N 纸张高度TSCLIB_DLL.sendcommand("SIZE 100 mm, 30 mm");TSCLIB_DLL.sendcommand("SPEED 2");TSCLIB_DLL.sendcommand("DENSITY 15");TSCLIB_DLL.sendcommand("DIRECTION 1");TSCLIB_DLL.sendcommand("SET TEAR ON");TSCLIB_DLL.sendcommand("CODEPAGE UTF-8");TSCLIB_DLL.clearbuffer();if (printType == PrintTypeEnum.QRCode)//打印二维码{TSCLIB_DLL.windowsfontUnicode(150, 20, 26, 0, 0, 0, chineseFont, warehouseLocationName);TSCLIB_DLL.sendcommand($"QRCODE 180,55,H,5,A,0,M2,\"{param.QRCodeContent}\"");TSCLIB_DLL.windowsfontUnicode(150, 180, 26, 0, 0, 0, chineseFont, warehouseLocationNo);if (!string.IsNullOrWhiteSpace(param.QRCodeContent2)){TSCLIB_DLL.windowsfontUnicode(550, 20, 26, 0, 0, 0, chineseFont, warehouseLocationName2);TSCLIB_DLL.sendcommand($"QRCODE 580,55,H,5,A,0,M2,\"{param.QRCodeContent2}\"");TSCLIB_DLL.windowsfontUnicode(550, 180, 26, 0, 0, 0, chineseFont, warehouseLocationNo2);}}else// 打印条码.{// 在 (450, 200) 的坐标上// 以 Code128 的条码方式// 条码高度 300// 打印条码的同时,还打印条码的文本信息.// 旋转的角度为 0 度// 条码 宽 窄 比例因子为 7:7// 条码内容为:barCode//BARCODE X,Y,”code type”,height,human readable,rotation,narrow,wide,[alignment,]”content“TSCLIB_DLL.barcode("300", "340", "128", "180", "1", "0", "6", "6", $"{param.QRCodeContent2}");}//TSCLIB_DLL.sendcommand(String.Format("QRCODE 740,320,H,8,A,0,M2,\"{0}\"", trayCode));//DMATRIX码 。DMATRIX 命令,740,320,90,90 指定 X 坐标,指定 Y 坐标,条码区域宽度//TSCLIB_DLL.sendcommand($"DMATRIX 740,320,90,90,x18,30,30,\"{trayCode}\"");int printlabel = TSCLIB_DLL.printlabel("1", "1");TSCLIB_DLL.closeport();#endregionawait Task.CompletedTask;}}/// <summary>/// 打印枚举/// </summary>public enum PrintTypeEnum{QRCode = 0,//二维码BarCode = 1//条形码}
}
/// <summary>
/// 库位码打印参数
/// </summary>
public class WarehouseLocationNoParam
{/// <summary>/// 二维码内容/// </summary>public string QRCodeContent { get; set; }/// <summary>/// 库位名称/// </summary>public string WarehouseLocationName { get; set; }/// <summary>/// 库位编码/// </summary>public string WarehouseLocationNo { get; set; }
}
/// <summary>
/// 库位码打印参数
/// </summary>
public class PrintWarehouseLocationParam
{/// <summary>/// 二维码内容/// </summary>public string QRCodeContent { get; set; }/// <summary>/// 库位名称/// </summary>public string WarehouseLocationName { get; set; }/// <summary>/// 库位编码/// </summary>public string WarehouseLocationNo { get; set; }/// <summary>/// 二维码内容2/// </summary>public string QRCodeContent2 { get; set; }/// <summary>/// 库位名称2/// </summary>public string WarehouseLocationName2 { get; set; }/// <summary>/// 库位编码2/// </summary>public string WarehouseLocationNo2 { get; set; }
}
2.3 用到的公共类
using System.Runtime.InteropServices;namespace Imagine.Mes.MesBase.Application.CommonTool
{public class TSCLIB_DLL{[DllImport("TSCLIB.dll", EntryPoint = "about")]public static extern int about();[DllImport("TSCLIB.dll", EntryPoint = "openport")]public static extern int openport(string printername);[DllImport("TSCLIB.dll", EntryPoint = "barcode")]public static extern int barcode(string x, string y, string type,string height, string readable, string rotation,string narrow, string wide, string code);[DllImport("TSCLIB.dll", EntryPoint = "clearbuffer")]public static extern int clearbuffer();[DllImport("TSCLIB.dll", EntryPoint = "closeport")]public static extern int closeport();[DllImport("TSCLIB.dll", EntryPoint = "downloadpcx")]public static extern int downloadpcx(string filename, string image_name);[DllImport("TSCLIB.dll", EntryPoint = "formfeed")]public static extern int formfeed();[DllImport("TSCLIB.dll", EntryPoint = "nobackfeed")]public static extern int nobackfeed();[DllImport("TSCLIB.dll", EntryPoint = "printerfont")]public static extern int printerfont(string x, string y, string fonttype,string rotation, string xmul, string ymul,string text);[DllImport("TSCLIB.dll", EntryPoint = "printlabel")]public static extern int printlabel(string set, string copy);[DllImport("TSCLIB.dll", EntryPoint = "sendcommand")]public static extern int sendcommand(string printercommand);[DllImport("TSCLIB.dll", EntryPoint = "setup")]public static extern int setup(string width, string height,string speed, string density,string sensor, string vertical,string offset);[DllImport("TSCLIB.dll", EntryPoint = "windowsfont")]public static extern int windowsfont(int x, int y, int fontheight,int rotation, int fontstyle, int fontunderline,string szFaceName, string content);[DllImport("TSCLIB.dll", EntryPoint = "windowsfontUnicode")]public static extern int windowsfontUnicode(int x, int y, int fontheight,int rotation, int fontstyle, int fontunderline,string szFaceName, byte[] content);[DllImport("TSCLIB.dll", EntryPoint = "sendBinaryData")]public static extern int sendBinaryData(byte[] content, int length);[DllImport("TSCLIB.dll", EntryPoint = "usbportqueryprinter")]public static extern byte usbportqueryprinter();}
}