.netcore TSC打印机打印

此文章给出两种打印案例,

第一种是单列打印,第二种是双列打印

需要注意打印机名称的设置,程序中使用的打印机名称为999,电脑中安装打印机时名称也要为999。

以下是我在使用过程中总结的一些问题:

一 TSC打印机使用使用过程中遇到的问题

1、打印机刚连上就报警。

一般是纸张或色带安装有问题,纸张要放到档杆的下方。

2、打印机显示正常,DiagTool工具无法连接到打印机,无论点什么都提示"Port Open Error"。

如果使用USB模式,需要用线把打印机和电脑连接起来,同时打印机需插上网线。工具中,通讯接口选择USB,点击"读取状态",正常显示待机中,点击"读取",会重置工具中的各参数。

点击"网络设定",指定IP地址,这里设置为192.168.50.222

如果用服务器连接打印机,这个时候已经添加了打印机,登录服务器,找到打印机,打开打印机属性-端口,打印机名称或ip地址设置为与打印机ip一致即可。

3、打印机打印完成后报警。

检查纸张,纸张安装过紧或档条没压住纸,都会导致此问题。

接下来上代码

二 打印方式

2.1 单列打印

这种打印方式示例中,打印的位置是可以配置的

cs 复制代码
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
            //打印机共享名999
            int 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();
            #endregion
            await 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到JObject
                JObject 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
    }
}
cs 复制代码
/// <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文件内容

cs 复制代码
{
  //批次号
  "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 双列打印

cs 复制代码
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
            //打印机共享名999
            int 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();
            #endregion
            await Task.CompletedTask;
        }
    }

    /// <summary>
    /// 打印枚举
    /// </summary>
    public enum PrintTypeEnum
    {
        QRCode = 0,//二维码
        BarCode = 1//条形码
    }
}
cs 复制代码
/// <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; }
}
cs 复制代码
/// <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 用到的公共类

cs 复制代码
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();
    }
}
相关推荐
时光追逐者19 小时前
C#/.NET/.NET Core学习路线集合,学习不迷路!
开发语言·学习·c#·asp.net·.net·.netcore·微软技术
Jeffrey侠客1 天前
.Net Core 6.0 WebApi在Centos中部署
linux·centos·.netcore
技术拾荒者2 天前
.net core mvc 控制器中页面跳转
后端·c#·asp.net·mvc·.netcore
时光追逐者2 天前
Visual Studio 2022:一个功能全面且强大的IDE
ide·c#·.net·.netcore·visual studio
.Net Core 爱好者4 天前
ASP .NET CORE 6 在项目中集成WatchDog开源项目
c#·.net·.netcore
想起你的日子5 天前
.net core 接口,动态接收各类型请求的参数
.netcore
qq_383139845 天前
Quartz实现定时调用接口(.net core2.0)
.netcore
时光追逐者5 天前
一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
开源·c#·asp.net·.net·.netcore·微软技术
小兜全糖(xdqt)6 天前
.net core NPOI以及NOPI mapper
.netcore
小兜全糖(xdqt)6 天前
.net Core 使用Panda.DynamicWebApi动态构造路由
.netcore