简体   繁体   English

将打印作业从PuTTY发送到Zebra ZXP 3 SDK(非zpl打印机)

[英]Send Print job from PuTTY to Zebra ZXP 3 SDK (non.zpl printer)

What I have is a medical record database that is accessed via PuTTY (SSH client). 我拥有的是一个通过PuTTY(SSH客户端)访问的病历数据库。 The cards themselves will only have Client name, record number in a barcode format (still determining the barcode type to be used), and client registration date. 卡本身仅具有客户名称,条形码格式的记录号(仍确定要使用的条形码类型)以及客户注册日期。

1) We can get the data output as .zpl for Zebra Barcode label printers or formats compatible with laser printers like HP or Brother in a RAW format. 1)对于Zebra条形码标签打印机,或者与RAW格式的HP或Brother等激光打印机兼容的格式,我们可以将数据输出为.zpl。 2) What output WILL the ZXP 3 SDK accept? 2)ZXP 3 SDK将接受什么输出? 3) Can the SDK be set up to wait for and accept data coming at it using a command line from something like RedMon? 3)是否可以将SDK设置为使用RedMon之类的命令行来等待并接受来自其的数据?

The cards themselves will only have the printed data, no mag stripe, smart chips, laminates or anything like that. 卡本身仅具有打印的数据,没有磁条,智能芯片,层压板或类似的东西。

Mahalo in advance. 玛哈洛提前。

I would not recommend using either RedMon nor the SDK, as neither are required for what you are trying to do, and they both are time-vampires. 我不建议您使用RedMon或SDK,因为您要尝试做的都不是必需的,而且它们都是时间吸血鬼。 Instead, I would write a small Windows Forms application which listens on a TCP port to receive the print job and send it to the standard printer which uses the Zebra driver. 相反,我将编写一个小的Windows窗体应用程序,该应用程序侦听TCP端口以接收打印作业,并将其发送到使用Zebra驱动程序的标准打印机。

Have the MUMPS application send an XML document via the Remote Print support in VT100. 让MUMPS应用程序通过VT100中的“远程打印”支持发送XML文档。 The example I have been using is below: 我一直在使用的示例如下:

^[[5i
<patient>
    <name first="John" last="Smith" />
    <mrn>A04390503</mrn>
    <dob>1991-03-12</dob>
</patient>
^[[4i

Configure a printer on the windows client to redirect to TCP/IP: 在Windows客户端上配置打印机以重定向到TCP / IP:

  1. Add Printer 添加打印机
  2. Local printer 本地打印机
  3. Create a new port 创建一个新端口
    • Standard TCP/IP Port 标准TCP / IP端口
    • Hostname: 127.0.0.1 主机名:127.0.0.1
    • Port name: CardFormatter 端口名称:CardFormatter
    • Uncheck "Query the printer and automatically select the driver to use" 取消选中“查询打印机并自动选择要使用的驱动程序”
    • Device type: Custom 设备类型:自定义
      • Protocol: Raw 协议:原始
      • Port: 9101 端口:9101
  4. Driver: Generic / Text Only 驱动程序:通用/纯文本

Start the application at logon, and print from the server. 登录时启动应用程序,然后从服务器进行打印。 The MUMPS application will send back the XML, which Putty prints to the Text printer, which gets sent to the C# application on localhost. MUMPS应用程序将发回XML,Putty将其打印到XML文本打印机,该XML将被发送到本地主机上的C#应用​​程序。 The C# application interprets the XML and prints to the actual printer via the Zebra driver or SDK. C#应用程序解释XML并通过Zebra驱动程序或SDK将其打印到实际打印机。

Note: This only assumes one interactive session per workstation. 注意:这仅假设每个工作站一个交互式会话。 If you are using fast-user-switching or terminal services, further care must be taken to ensure things work properly. 如果您使用的是快速用户切换或终端服务,则必须格外小心,以确保一切正常。

Example App: 示例应用程序:

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PassThroughPrinterTest
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new TrayApplicationContext());
        }
    }
}

TrayApplicationContext.cs

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PassThroughPrinterTest
{
    class TrayApplicationContext : ApplicationContext
    {
        private NotifyIcon trayIcon;
        private PrintListener listener;
        private PrintHandler handler;

        public TrayApplicationContext()
        {
            this.trayIcon = new NotifyIcon()
            {
                Text = "Card Formatter",
                Icon = Properties.Resources.AppIcon,
                ContextMenu = new ContextMenu()
                {
                    MenuItems =
                    {
                        new MenuItem("Print Options...", miPrintOptions_Click),
                        new MenuItem("Exit", miExit_Click)
                    }
                },
                Visible = true
            };

            this.handler = new PrintHandler();

            this.listener = new PrintListener(9101);
            this.listener.PrintDataReceived += this.handler.HandlePrintData;
        }

        private void miPrintOptions_Click(object sender, EventArgs args)
        {
            // TODO: add configuration and options to avoid having to hard code
            // the printer name in PrintHandler.cs
            MessageBox.Show("Options");
        }

        private void miExit_Click(object sender, EventArgs args)
        {
            Application.Exit();
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing)
            {
                trayIcon.Dispose();
            }
        }
    }
}

PrintHandler.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;

namespace PassThroughPrinterTest
{
    partial class PrintHandler : Form
    {
        public PrintHandler()
        {
            InitializeComponent();
        }

        public void HandlePrintData(object sender, PrintDataReceivedEventArgs args)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new EventHandler<PrintDataReceivedEventArgs>(HandlePrintData), sender, args);
                return;
            }

            this.Show();

            var sXml = Encoding.UTF8.GetString(args.PrintData);
            this.PrintCard(XDocument.Parse(sXml));

            this.Hide();
        }

        private void PrintCard(XDocument xDocument)
        {
            var nameElement = xDocument.Root.Element("name");
            var lastName = nameElement.Attribute("last").Value;
            var firstName = nameElement.Attribute("first").Value;
            var mrn = xDocument.Root.Element("mrn").Value;

            var printDoc = new PrintDocument()
            {
                PrinterSettings = new PrinterSettings()
                {
                    PrinterName = "Adobe PDF"
                },
                DocumentName = "Patient ID Card"
            };
            var cardPaperSize = new PaperSize("Card", 337, 213) { RawKind = (int)PaperKind.Custom };
            printDoc.DefaultPageSettings.PaperSize = cardPaperSize;
            printDoc.PrinterSettings.DefaultPageSettings.PaperSize = cardPaperSize;
            printDoc.PrintPage += (s, e) =>
            {
                var gfx = e.Graphics;

                // print the text information
                var fArial12 = new Font("Arial", 12);
                gfx.DrawString(lastName, fArial12, Brushes.Black, new RectangleF(25, 25, 200, 75));
                gfx.DrawString(firstName, fArial12, Brushes.Black, new RectangleF(25, 100, 200, 75));

                // add a code39 barcode using a barcode font
                // http://www.idautomation.com/free-barcode-products/code39-font/
                // var fCode39 = new Font("IDAutomationHC39M", 12);
                // gfx.DrawString("(" + mrn + ")", fArial12, Brushes.Black, new RectangleF(25, 200, 200, 75));

                // or by using a barcode library
                // https://barcoderender.codeplex.com/
                // var barcode = BarcodeDrawFactory.Code128WithChecksum.Draw(mrn, 20, 2);
                // gfx.DrawImage(barcode, 50, 200);

                e.HasMorePages = false;
            };
            printDoc.Print();
        }
    }
}

PrintListener.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace PassThroughPrinterTest
{
    sealed class PrintListener : IDisposable
    {
        private TcpListener listener;

        public event EventHandler<PrintDataReceivedEventArgs> PrintDataReceived;

        public PrintListener(int port)
        {
            this.listener = new TcpListener(IPAddress.Loopback, port);
            this.listener.Start();

            this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
        }

        public void Dispose()
        {
            this.listener.Stop();
        }

        private void listener_AcceptClient(IAsyncResult iar)
        {
            TcpClient client = null;
            bool isStopped = false;
            try
            {
                client = this.listener.EndAcceptTcpClient(iar);
            }
            catch (ObjectDisposedException)
            {
                // this will occur in graceful shutdown
                isStopped = true;
                return;
            }
            finally
            {
                if (!isStopped)
                {
                    this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
                }
            }
            Debug.Assert(client != null);

            try
            {
                byte[] printData;
                using (var clientStream = client.GetStream())
                using (var buffer = new MemoryStream())
                {
                    clientStream.CopyTo(buffer);

                    printData = buffer.ToArray();
                }

                OnPrintDataReceived(printData);
            }
            catch
            {
                // TODO: add logging and error handling for network issues or processing issues
                throw;
            }
            finally
            {
                client.Close();
            }
        }

        private void OnPrintDataReceived(byte[] printData)
        {
            var handler = PrintDataReceived;
            if (handler != null)
            {
                handler(this, new PrintDataReceivedEventArgs(printData));
            }
        }
    }
}

TrayApplicationContext.cs

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PassThroughPrinterTest
{
    class TrayApplicationContext : ApplicationContext
    {
        private NotifyIcon trayIcon;
        private PrintListener listener;
        private PrintHandler handler;

        public TrayApplicationContext()
        {
            this.trayIcon = new NotifyIcon()
            {
                Text = "Card Formatter",
                Icon = Properties.Resources.AppIcon,
                ContextMenu = new ContextMenu()
                {
                    MenuItems =
                    {
                        new MenuItem("Print Options...", miPrintOptions_Click),
                        new MenuItem("Exit", miExit_Click)
                    }
                },
                Visible = true
            };

            this.handler = new PrintHandler();

            this.listener = new PrintListener(9101);
            this.listener.PrintDataReceived += this.handler.HandlePrintData;
        }

        private void miPrintOptions_Click(object sender, EventArgs args)
        {
            // TODO: add configuration and options to avoid having to hard code
            // the printer name in PrintHandler.cs
            MessageBox.Show("Options");
        }

        private void miExit_Click(object sender, EventArgs args)
        {
            Application.Exit();
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing)
            {
                listener.Dispose();
                trayIcon.Dispose();
            }
        }
    }
}

PrintDataReceivedEventArgs.cs

using System;

namespace PassThroughPrinterTest
{
    class PrintDataReceivedEventArgs : EventArgs
    {
        public byte[] PrintData { get; set; }

        public PrintDataReceivedEventArgs(byte[] data)
        {
            if (data == null)
                throw new ArgumentNullException("data");

            this.PrintData = data;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM