2012-06-10 104 views
27

Estamos tratando de imprimir códigos de barras desde una página web a nuestra impresora Zebra.Imprimir códigos de barras desde la página web a la impresora Zebra

Me pregunto si hay una manera de imprimirlos utilizando la propia fuente de la impresora, quizás usando fuentes web o si conozco el nombre de la fuente utilizada?

He estado tratando de usar generadores de códigos de barras php, que básicamente genera imágenes que contienen el código de barras. De hecho, he estado probando este enfoque durante algunos días, sin éxito.

El problema es que cuando los imprimo no es legible por los escáneres. Intenté cambiar la resolución de la imagen para que coincidiera con la de la impresora (203 ppp), también intenté jugar con el tamaño y los formatos de la imagen, pero los códigos de barras después de imprimir aún no se pueden escanear.

¿Alguien tiene experiencia con esto?

Impresora: Zebra TLP 2844

códigos de barras requiere por página:

  • 01 Code39 horizontal (scanable sólo si imprime en tamaño muy específico y navegador)
  • 01 Código128 vertical (todavía no puede conseguir que funcione, la impresión es siempre muy borrosa y no conseguirá escaneada)

===========

He progresado un poco, descubrí que esta impresora es compatible con el lenguaje EPL2, así que estoy tratando de usarlo para imprimir los códigos de barras.

Primero necesitaba habilitar el modo de paso, lo hice en Opciones de impresora> Configuración avanzada> Varios.

Ahora soy capaz de imprimir códigos de barras impecablemente utilizando la fuente incorporada de la impresora: D usando este comando:

ZPL: B10,10,0,1,2,2,60, N" TEXT-VA-HERE" : ZPL

Pero sólo puede imprimir desde Bloc de notas, sigo siendo incapaz de imprimir esto desde un navegador ... es probablemente un problema con LF siendo reemplazado con CR + LF ..

¿Cómo superar este problema?

===========

La etiqueta Estoy tratando de imprimir en realidad tiene un poco de texto antes de que el código de barras, con algunas mesas de formato HTML muy bien. Así que necesito imprimir esto primero, y en el medio necesito colocar una etiqueta bonita y luego agregar un poco más de texto.

Así que no puedo usar EPL2 puro para imprimir todo, me pregunto si puedo usar algo de html + EPL2 + html para lograr mi objetivo o ¿no está permitido? =/

+0

Parece que tiene algunas respuestas prometedoras a continuación. Solo quiero agregar que no puede combinar el formato HTML con ZPL. Tendrá que hacer todo el formato de la etiqueta con ZPL. Hay muchas opciones para cuadros y texto y cosas, por lo que es factible. – EdHayes3

Respuesta

18

Está ejecutando en unos pocos obstáculos:

1) Cuando se imprime a través del controlador de impresora instalado OS, el controlador de la impresora está tratando de tomar los datos que se envía a la misma y (re) rasterizar o escalarlo para el dispositivo de salida (la impresora Zebra).Dado que la impresora tiene una resolución relativamente baja a 203 ppp, no es necesario demasiado para que el controlador de la impresora escale y pierda integridad en la calidad del código de barras. Esta es la razón por la cual los códigos de barra generados usando los comandos directos de ZPL son mucho más más confiables.

2) Debido a la seguridad que proporcionan los exploradores web al permitir el acceso a la computadora cliente, no se puede comunicar directamente con la impresora conectada del cliente. Este entorno de pruebas es lo que ayuda a proteger a los usuarios del malware para que los sitios web nefastos no puedan hacer cosas como escribir archivos en la máquina del cliente o enviar los resultados directamente a dispositivos como impresoras. Por lo tanto, no puede enviar directamente los comandos ZPL a través del navegador a la impresora conectada al cliente.

Sin embargo, hay una manera de hacer lo que describes. Los pasos necesarios normalmente solo serán útiles si tiene cierto grado de control sobre la computadora cliente que accede al sitio que intenta imprimir en las impresoras Zebra. Por ejemplo, esto solo lo utilizarán las máquinas de la red de su empresa o los clientes que deseen instalar una pequeña aplicación que necesite escribir. Para ello, deberá seguir los siguientes pasos:

A) Debe crear su propio tipo MIME personalizado. Básicamente, se trata de cualquier nombre que desee utilizar que no colisione con registered MIME types.

B) A continuación, definirá una extensión de nombre de archivo que se correlacionará con su tipo MIME personalizado. Para hacer esto, normalmente necesitará configurar su servidor web (los pasos para esto dependen de qué servidor web esté utilizando) para permitir el nuevo tipo MIME que desea definir y qué extensión de archivo se usa para estos tipos de archivos.

C) Luego, en su aplicación web, cuando desea generar los datos de ZPL, los escribe en un archivo con una extensión de nombre de archivo asignada a su nuevo tipo MIME. Luego, una vez que se genera el archivo, puede proporcionarle un enlace HTML o redirigir el navegador del cliente al archivo. Puede comprobar si su archivo funciona correctamente en este momento copiando manualmente el archivo que creó directamente en el puerto de impresora sin formato.

D) A continuación, debe escribir una pequeña aplicación que se puede instalar en el cliente. Cuando la aplicación está instalada, necesita que se registre como una aplicación de consumo válida para su tipo MIME personalizado. Si un navegador detecta que hay una aplicación instalada para un archivo del tipo MIME especificado, simplemente escribe el archivo en un directorio temporal en el equipo cliente y luego intenta iniciar la aplicación del mismo tipo MIME registrado con el archivo temporal como un parámetro para la aplicación. Por lo tanto, su aplicación ahora solo lee el archivo que el navegador le pasó y luego intenta volcarlo directamente a la impresora.

Esta es una descripción general de lo que debe hacer para lograr lo que está describiendo. Algunos de los pasos específicos dependerán del tipo de servidor web que esté utilizando y del sistema operativo de las máquinas de sus clientes. Pero esta es la descripción general de alto nivel que le permitirá lograr lo que está intentando.

+0

¿Qué pasa con el modo de paso que se puede habilitar en las opciones de la impresora? Según el manual de Zebra, uno debe poder acceder al pase desde cualquier aplicación de Windows, siempre que el modo esté habilitado en la configuración que es. – user1447134

+0

Incluso si el controlador de impresión instalado lo permitió, usted todavía está limitado por lo que el navegador le permitirá hacer en el n. ° 1 de mi respuesta anterior. Si eso funciona, su usuario final recibirá un cuadro de diálogo de impresión al que deben responder y seleccionará la impresora correcta. No es una mala compensación, pero potencialmente un pequeño error propenso debido a los pasos adicionales que el usuario final necesita hacer. – dmarietta

+0

Tuvimos que hacer esto para imprimir códigos de barras una vez. Es una pesadilla, en realidad es una aplicación, la mayoría de las impresoras tienen API para esto, algunos tienen aplicaciones web, pero no siempre son bien compatibles. – nycynik

3

Estoy desarrollando algo similar aquí. Necesito imprimir en un LP2844 desde mi aplicación web. El problema es que mi aplicación web está en un servidor remoto en la nube (Amazon EC2) y la impresora va a estar en un escritorio de depósito.

Mi solución: La aplicación web genera el EPL2 code para la etiqueta con los códigos de barras, y luego publica un PubNub message. Escribí un pequeño programa de C# que se ejecuta en la computadora donde está conectada la impresora. El programa recibe el mensaje y luego envía el código a la impresora.

+0

¿Estaría dispuesto a compartir la fuente de su solución?Estoy buscando desarrollar lo mismo (y desarrollar un cliente Mac también) y me gustaría abrir el código fuente, si es posible. –

+0

Lo siento, abandoné ese proyecto y no cometí esa paz de código. –

2

También puede enviar los comandos de ZPL en un archivo de texto (puede empaquetar varias etiquetas en un solo archivo) y hacer que el usuario abra e imprima el archivo a través del bloc de notas de Windows. La única advertencia es que tienen que eliminar el encabezado y el pie de página predeterminados (Archivo -> Configuración de página).

Es un poco de capacitación del usuario, pero puede ser aceptable si no tiene control sobre las máquinas del cliente.

7

Si considera cargar un applet de Java, qz-print (anteriormente jzebra) puede hacer exactamente lo que está describiendo y funciona muy bien con el LP2844 mencionado en los comentarios.

https://code.google.com/p/jzebra/

+2

Solo para que otras personas lo sepan .. Java applet ya no es compatible con Chrome. – batwadi

+0

@batwadi gracias. Editado – tresf

2

que siguieron la idea propuesta por "Tres Finocchiaro" en mi solicitud sobre la base de:

  1. ASP.NET 4.0
  2. IIS
  3. Chrome, IExplorer, Firefox
  4. Zebra TLP 2844
  5. EPL protocolo

Desafortunadamente, el jzebra necesita algunas mejoras para funcionar corectly debido a los problemas de seguridad del navegador actual.

Instalación jzebra

Downlod jzebdra y desde el directorio dist copio en su directorio (por ejemplo mydir.):

  • web
    • midirectorio
      • js
        • ..
        • deployJava.js
      • lib
        • ..
      • QZ-print.jar
      • QZ-print_jnlp.jnlp

Crea tu print.html

<html> 
<script type="text/javascript" src="js/deployJava.js"></script> 
<script type="text/javascript"> 
    /** 
    * Optionally used to deploy multiple versions of the applet for mixed 
    * environments. Oracle uses document.write(), which puts the applet at the 
    * top of the page, bumping all HTML content down. 
    */ 
    deployQZ(); 

    /** NEW FUNCTION **/ 
    function initPrinter() { 
     findPrinters(); 
     useDefaultPrinter(); 
    } 

    /** NEW FUNCTION **/  
    function myalert(txt) { 
     alert(txt); 
    } 


    /** 
    * Deploys different versions of the applet depending on Java version. 
    * Useful for removing warning dialogs for Java 6. This function is optional 
    * however, if used, should replace the <applet> method. Needed to address 
    * MANIFEST.MF TrustedLibrary=true discrepency between JRE6 and JRE7. 
    */ 
    function deployQZ() { 
     var attributes = {id: "qz", code:'qz.PrintApplet.class', 
      archive:'qz-print.jar', width:1, height:1}; 
     var parameters = {jnlp_href: 'qz-print_jnlp.jnlp', 
      cache_option:'plugin', disable_logging:'false', 
      initial_focus:'false'}; 
     if (deployJava.versionCheck("1.7+") == true) {} 
     else if (deployJava.versionCheck("1.6+") == true) { 
      delete parameters['jnlp_href']; 
     } 
     deployJava.runApplet(attributes, parameters, '1.5'); 
    } 

    /** 
    * Automatically gets called when applet has loaded. 
    */ 
    function qzReady() { 
     // Setup our global qz object 
     window["qz"] = document.getElementById('qz'); 
     var title = document.getElementById("title"); 
     if (qz) { 
      try { 
       title.innerHTML = title.innerHTML + " " + qz.getVersion(); 
       document.getElementById("content").style.background = "#F0F0F0"; 
      } catch(err) { // LiveConnect error, display a detailed meesage 
       document.getElementById("content").style.background = "#F5A9A9"; 
       alert("ERROR: \nThe applet did not load correctly. Communication to the " + 
        "applet has failed, likely caused by Java Security Settings. \n\n" + 
        "CAUSE: \nJava 7 update 25 and higher block LiveConnect calls " + 
        "once Oracle has marked that version as outdated, which " + 
        "is likely the cause. \n\nSOLUTION: \n 1. Update Java to the latest " + 
        "Java version \n   (or)\n 2. Lower the security " + 
        "settings from the Java Control Panel."); 
      } 
     } 
    } 

    /** 
    * Returns whether or not the applet is not ready to print. 
    * Displays an alert if not ready. 
    */ 
    function notReady() { 
     // If applet is not loaded, display an error 
     if (!isLoaded()) { 
      return true; 
     } 
     // If a printer hasn't been selected, display a message. 
     else if (!qz.getPrinter()) { 
      /** CALL TO NEW FUNCTION **/ 
      initPrinter(); 
      return false; 
     } 
     return false; 
    } 

    /** 
    * Returns is the applet is not loaded properly 
    */ 
    function isLoaded() { 
     if (!qz) { 
      alert('Error:\n\n\tPrint plugin is NOT loaded!'); 
      return false; 
     } else { 
      try { 
       if (!qz.isActive()) { 
        alert('Error:\n\n\tPrint plugin is loaded but NOT active!'); 
        return false; 
       } 
      } catch (err) { 
       alert('Error:\n\n\tPrint plugin is NOT loaded properly!'); 
       return false; 
      } 
     } 
     return true; 
    } 

    /** 
    * Automatically gets called when "qz.print()" is finished. 
    */ 
    function qzDonePrinting() { 
     // Alert error, if any 
     if (qz.getException()) { 
      alert('Error printing:\n\n\t' + qz.getException().getLocalizedMessage()); 
      qz.clearException(); 
      return; 
     } 

     // Alert success message 
     alert('Successfully sent print data to "' + qz.getPrinter() + '" queue.'); 
    } 

    /*************************************************************************** 
    * Prototype function for finding the "default printer" on the system 
    * Usage: 
    * qz.findPrinter(); 
    * window['qzDoneFinding'] = function() { alert(qz.getPrinter()); }; 
    ***************************************************************************/ 
    function useDefaultPrinter() { 
     if (isLoaded()) { 
      // Searches for default printer 
      qz.findPrinter(); 

      // Automatically gets called when "qz.findPrinter()" is finished. 
      window['qzDoneFinding'] = function() { 
       // Alert the printer name to user 
       var printer = qz.getPrinter(); 
       myalert(printer !== null ? 'Default printer found: "' + printer + '"': 
        'Default printer ' + 'not found'); 

       // Remove reference to this function 
       window['qzDoneFinding'] = null; 
      }; 
     } 
    } 

    /*************************************************************************** 
    * Prototype function for finding the closest match to a printer name. 
    * Usage: 
    * qz.findPrinter('zebra'); 
    * window['qzDoneFinding'] = function() { alert(qz.getPrinter()); }; 
    ***************************************************************************/ 
    function findPrinter(name) { 
     // Get printer name from input box 
     var p = document.getElementById('printer'); 
     if (name) { 
      p.value = name; 
     } 

     if (isLoaded()) { 
      // Searches for locally installed printer with specified name 
      qz.findPrinter(p.value); 

      // Automatically gets called when "qz.findPrinter()" is finished. 
      window['qzDoneFinding'] = function() { 
       var p = document.getElementById('printer'); 
       var printer = qz.getPrinter(); 

       // Alert the printer name to user 
       alert(printer !== null ? 'Printer found: "' + printer + 
        '" after searching for "' + p.value + '"' : 'Printer "' + 
        p.value + '" not found.'); 

       // Remove reference to this function 
       window['qzDoneFinding'] = null; 
      }; 
     } 
    } 

    /*************************************************************************** 
    * Prototype function for listing all printers attached to the system 
    * Usage: 
    * qz.findPrinter('\\{dummy_text\\}'); 
    * window['qzDoneFinding'] = function() { alert(qz.getPrinters()); }; 
    ***************************************************************************/ 
    function findPrinters() { 
     if (isLoaded()) { 
      // Searches for a locally installed printer with a bogus name 
      qz.findPrinter('\\{bogus_printer\\}'); 

      // Automatically gets called when "qz.findPrinter()" is finished. 
      window['qzDoneFinding'] = function() { 
       // Get the CSV listing of attached printers 
       var printers = qz.getPrinters().split(','); 
       for (i in printers) { 
        myalert(printers[i] ? printers[i] : 'Unknown');  
       } 

       // Remove reference to this function 
       window['qzDoneFinding'] = null; 
      }; 
     } 
    } 

    /*************************************************************************** 
    * Prototype function for printing raw EPL commands 
    * Usage: 
    * qz.append('\nN\nA50,50,0,5,1,1,N,"Hello World!"\n'); 
    * qz.print(); 
    ***************************************************************************/ 
    function print() { 
     if (notReady()) { return; } 

     // Send characters/raw commands to qz using "append" 
     // This example is for EPL. Please adapt to your printer language 
     // Hint: Carriage Return = \r, New Line = \n, Escape Double Quotes= \" 
     qz.append('\nN\n');    
     qz.append('q609\n'); 
     qz.append('Q203,26\n'); 
     qz.append('B5,26,0,1A,3,7,152,B,"1234"\n'); 
     qz.append('A310,26,0,3,1,1,N,"SKU 00000 MFG 0000"\n'); 
     qz.append('A310,56,0,3,1,1,N,"QZ PRINT APPLET"\n'); 
     qz.append('A310,86,0,3,1,1,N,"TEST PRINT SUCCESSFUL"\n'); 
     qz.append('A310,116,0,3,1,1,N,"FROM SAMPLE.HTML"\n'); 
     qz.append('A310,146,0,3,1,1,N,"QZINDUSTRIES.COM"'); 

     // Append the rest of our commands 
     qz.append('\nP1,1\n'); 

     // Tell the applet to print. 
     qz.print(); 
    } 

    /*************************************************************************** 
    * Prototype function for logging a PostScript printer's capabilites to the 
    * java console to expose potentially new applet features/enhancements. 
    * Warning, this has been known to trigger some PC firewalls 
    * when it scans ports for certain printer capabilities. 
    * Usage: (identical to appendImage(), but uses html2canvas for png rendering) 
    * qz.setLogPostScriptFeatures(true); 
    * qz.appendHTML("<h1>Hello world!</h1>"); 
    * qz.printPS(); 
    ***************************************************************************/ 
    function logFeatures() { 
     if (isLoaded()) { 
      var logging = qz.getLogPostScriptFeatures(); 
      qz.setLogPostScriptFeatures(!logging); 
      alert('Logging of PostScript printer capabilities to console set to "' + !logging + '"'); 
     } 
    } 

    /*************************************************************************** 
    **************************************************************************** 
    * *       HELPER FUNCTIONS        ** 
    **************************************************************************** 
    ***************************************************************************/ 

    function getPath() { 
     var path = window.location.href; 
     return path.substring(0, path.lastIndexOf("/")) + "/"; 
    } 

    /** 
    * Fixes some html formatting for printing. Only use on text, not on tags! 
    * Very important! 
    * 1. HTML ignores white spaces, this fixes that 
    * 2. The right quotation mark breaks PostScript print formatting 
    * 3. The hyphen/dash autoflows and breaks formatting 
    */ 
    function fixHTML(html) { 
     return html.replace(/ /g, "&nbsp;").replace(/’/g, "'").replace(/-/g,"&#8209;"); 
    } 

    /** 
    * Equivelant of VisualBasic CHR() function 
    */ 
    function chr(i) { 
     return String.fromCharCode(i); 
    } 

    /*************************************************************************** 
    * Prototype function for allowing the applet to run multiple instances. 
    * IE and Firefox may benefit from this setting if using heavy AJAX to 
    * rewrite the page. Use with care; 
    * Usage: 
    * qz.allowMultipleInstances(true); 
    ***************************************************************************/ 
    function allowMultiple() { 
     if (isLoaded()) { 
     var multiple = qz.getAllowMultipleInstances(); 
     qz.allowMultipleInstances(!multiple); 
     alert('Allowing of multiple applet instances set to "' + !multiple + '"'); 
     } 
    } 
</script> 

    <input type="button" onClick="print()" /> 
    </body> 
</html> 

El código proporcionado se basa en "jzebra_installation/dist/sample.html".

+2

La última versión del complemento que menciona evita todos los problemas del "Complemento de Java" (NPAPI, etc.) y se ejecuta como una aplicación de escritorio https://github.com/qzind/tray/. También emplea .NET 'PageMethods' para un mejor ASYNC durante el nuevo proceso de firma obligatorio. – tresf

4

Lo que hicimos para nuestra aplicación web:

1) Descarga la aplicación gratuita printfile http://www.lerup.com/printfile/

"PrintFile es un programa gratuito utilidad de MS Windows que le permitirá imprimir archivos de forma rápida y fácil.El programa reconoce texto sin formato, PostScript, PostScript encapsulado (EPS) y formatos binarios. Usando este programa usted puede ahorrar una gran cantidad de papel y con ello también el ahorro de valiosos recursos naturales."

Cuando se ejecuta por primera vez PrintFile, entrar en las opciones avanzadas y permitir que 'enviar a la impresora directamente'.

2) Configuración la impresora Zebra en las ventanas como una impresora de texto genérico.

2) Generar un archivo file.prt en la aplicación web que está a un archivo de texto sin formato EPL.

3) al hacer doble clic en el archivo descargado al instante imprime el código de barras. Funciona como un amuleto. Incluso puedes configurar PrintFile para que ni siquiera veas una guía.

0

intente crear un websocket que controle la impresión en el lado del cliente y envíe datos con ajax desde la página a localhost.

/// websocket 
using System; 
using System.Net; 
using System.Net.WebSockets; 
using System.Text; 
using System.Threading; 

namespace Server 
{ 
    class Program 
    { 
     public static WebsocketServer ws; 
     static void Main(string[] args) 
     { 
      ws = new Server.WebsocketServer(); 
      ws.LogMessage += Ws_LogMessage; 
      ws.Start("http://localhost:2645/service/"); 
      Console.WriteLine("Press any key to exit..."); 
      Console.ReadKey(); 
     } 

     private static void Ws_LogMessage(object sender, WebsocketServer.LogMessageEventArgs e) 
     { 
      Console.WriteLine(e.Message); 
     } 
    } 

    public class WebsocketServer 
    { 
     public event OnLogMessage LogMessage; 
     public delegate void OnLogMessage(Object sender, LogMessageEventArgs e); 
     public class LogMessageEventArgs : EventArgs 
     { 
      public string Message { get; set; } 
      public LogMessageEventArgs(string Message) 
      { 
       this.Message = Message; 
      } 
     } 

     public bool started = false; 
     public async void Start(string httpListenerPrefix) 
     { 
      HttpListener httpListener = new HttpListener(); 
      httpListener.Prefixes.Add(httpListenerPrefix); 
      httpListener.Start(); 
      LogMessage(this, new LogMessageEventArgs("Listening...")); 
      started = true; 

      while (started) 
      { 
       HttpListenerContext httpListenerContext = await httpListener.GetContextAsync(); 
       if (httpListenerContext.Request.IsWebSocketRequest) 
       { 
        ProcessRequest(httpListenerContext); 
       } 
       else 
       { 
        httpListenerContext.Response.StatusCode = 400; 
        httpListenerContext.Response.Close(); 
        LogMessage(this, new LogMessageEventArgs("Closed...")); 
       } 
      } 
     } 

     public void Stop() 
     { 
      started = false; 
     } 
     private async void ProcessRequest(HttpListenerContext httpListenerContext) 
     { 
      WebSocketContext webSocketContext = null; 

      try 
      { 
       webSocketContext = await httpListenerContext.AcceptWebSocketAsync(subProtocol: null); 
       LogMessage(this, new LogMessageEventArgs("Connected")); 
      } 
      catch (Exception e) 
      { 
       httpListenerContext.Response.StatusCode = 500; 
       httpListenerContext.Response.Close(); 
       LogMessage(this, new LogMessageEventArgs(String.Format("Exception: {0}", e))); 
       return; 
      } 

      WebSocket webSocket = webSocketContext.WebSocket; 
      try 
      { 


       while (webSocket.State == WebSocketState.Open) 
       { 

        ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[8192]); 

        WebSocketReceiveResult result = null; 

        using (var ms = new System.IO.MemoryStream()) 
        { 
         do 
         { 
          result = await webSocket.ReceiveAsync(buffer, CancellationToken.None); 
          ms.Write(buffer.Array, buffer.Offset, result.Count); 
         } 
         while (!result.EndOfMessage); 

         ms.Seek(0, System.IO.SeekOrigin.Begin); 

         if (result.MessageType == WebSocketMessageType.Text) 
         { 
          using (var reader = new System.IO.StreamReader(ms, Encoding.UTF8)) 
          { 
           var r = System.Text.Encoding.UTF8.GetString(ms.ToArray()); 
           var t = Newtonsoft.Json.JsonConvert.DeserializeObject<Datos>(r); 
           bool valid = true; 
           byte[] toBytes = Encoding.UTF8.GetBytes(""); ; 

           if (t != null) 
           { 
            if (t.printer.Trim() == string.Empty) 
            { 
             var printers = ""; 
             foreach (var imp in System.Drawing.Printing.PrinterSettings.InstalledPrinters) 
             { 
              printers += imp + "\n"; 
             } 

             toBytes = Encoding.UTF8.GetBytes("No se Indicó la Impresora\nLas Impresoras disponibles son: " + printers); 
             valid = false; 
            } 
            if (t.name.Trim() == string.Empty) 
            { 
             toBytes = Encoding.UTF8.GetBytes("No se Indicó el nombre del Documento"); 
             valid = false; 
            } 
            if (t.code == null) 
            { 
             toBytes = Encoding.UTF8.GetBytes("No hay datos para enviar a la Impresora"); 
             valid = false; 
            } 


            if (valid) 
            { 
             print.RawPrinter.SendStringToPrinter(t.printer, t.code, t.name); 
             toBytes = Encoding.UTF8.GetBytes("Correcto..."); 
            } 

            await webSocket.SendAsync(new ArraySegment<byte>(toBytes, 0, int.Parse(toBytes.Length.ToString())), WebSocketMessageType.Binary, result.EndOfMessage, CancellationToken.None); 
           } 
           else 
           { 
            toBytes = Encoding.UTF8.GetBytes("Error..."); 
            await webSocket.SendAsync(new ArraySegment<byte>(toBytes, 0, int.Parse(toBytes.Length.ToString())), WebSocketMessageType.Binary, result.EndOfMessage, CancellationToken.None); 
           } 
          } 
         } 
        } 
       } 
      } 
      catch (Exception e) 
      { 
       LogMessage(this, new LogMessageEventArgs(String.Format("Exception: {0} \nLinea:{1}", e, e.StackTrace))); 
      } 
      finally 
      { 
       if (webSocket != null) 
        webSocket.Dispose(); 
      } 
     } 
    } 

    public class Datos 
    { 
     public string name { get; set; } 
     public string code { get; set; } 
     public string printer { get; set; } = ""; 
    } 
} 

impresión cruda:

using Microsoft.VisualBasic; 
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.IO; 

namespace print 
{ 
    public class RawPrinter 
    { 
     // Structure and API declarions: 
     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
     public class DOCINFOA 
     { 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pDocName; 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pOutputFile; 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pDataType; 
     } 
     [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] 
string szPrinter, ref IntPtr hPriknter, IntPtr pd); 

     [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool ClosePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In(), MarshalAs(UnmanagedType.LPStruct)] 
DOCINFOA di); 

     [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool EndDocPrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool StartPagePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool EndPagePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, ref Int32 dwWritten); 

     // SendBytesToPrinter() 
     // When the function is given a printer name and an unmanaged array 
     // of bytes, the function sends those bytes to the print queue. 
     // Returns true on success, false on failure. 
     public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount, string DocName = "") 
     { 
      Int32 dwError = 0; 
      Int32 dwWritten = 0; 
      IntPtr hPrinter = new IntPtr(0); 
      DOCINFOA di = new DOCINFOA(); 
      bool bSuccess = false; 
      // Assume failure unless you specifically succeed. 
      di.pDocName = string.IsNullOrEmpty(DocName) ? "My C#.NET RAW Document" : DocName; 
      di.pDataType = "RAW"; 

      // Open the printer. 
      if (OpenPrinter(szPrinterName.Normalize(), ref hPrinter, IntPtr.Zero)) 
      { 
       // Start a document. 
       if (StartDocPrinter(hPrinter, 1, di)) 
       { 
        // Start a page. 
        if (StartPagePrinter(hPrinter)) 
        { 
         // Write your bytes. 
         bSuccess = WritePrinter(hPrinter, pBytes, dwCount, ref dwWritten); 
         EndPagePrinter(hPrinter); 
        } 
        EndDocPrinter(hPrinter); 
       } 
       ClosePrinter(hPrinter); 
      } 
      // If you did not succeed, GetLastError may give more information 
      // about why not. 
      if (bSuccess == false) 
      { 
       dwError = Marshal.GetLastWin32Error(); 
      } 
      return bSuccess; 
     } 

     public static bool SendFileToPrinter(string szPrinterName, string szFileName) 
     { 
      // Open the file. 
      FileStream fs = new FileStream(szFileName, FileMode.Open); 
      // Create a BinaryReader on the file. 
      BinaryReader br = new BinaryReader(fs); 
      // Dim an array of bytes big enough to hold the file's contents. 
      Byte[] bytes = new Byte[fs.Length]; 
      bool bSuccess = false; 
      // Your unmanaged pointer. 
      IntPtr pUnmanagedBytes = new IntPtr(0); 
      int nLength = 0; 

      nLength = Convert.ToInt32(fs.Length); 
      // Read the contents of the file into the array. 
      bytes = br.ReadBytes(nLength); 
      // Allocate some unmanaged memory for those bytes. 
      pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength); 
      // Copy the managed byte array into the unmanaged array. 
      Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength); 
      // Send the unmanaged bytes to the printer. 
      bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength); 
      // Free the unmanaged memory that you allocated earlier. 
      Marshal.FreeCoTaskMem(pUnmanagedBytes); 
      return bSuccess; 
     } 
     public static bool SendStringToPrinter(string szPrinterName, string szString, string DocName = "") 
     { 
      IntPtr pBytes = default(IntPtr); 
      Int32 dwCount = default(Int32); 
      // How many characters are in the string? 
      dwCount = szString.Length; 
      // Assume that the printer is expecting ANSI text, and then convert 
      // the string to ANSI text. 
      pBytes = Marshal.StringToCoTaskMemAnsi(szString); 
      // Send the converted ANSI string to the printer. 
      SendBytesToPrinter(szPrinterName, pBytes, dwCount, DocName); 
      Marshal.FreeCoTaskMem(pBytes); 
      return true; 
     } 
    } 
} 

página HTML:

<!DOCTYPE html> 
<html> 

<head> 
</head> 

<body ng-app="myapp"> 

    <div ng-controller="try as ctl"> 
     <input ng-model="ctl.ticket.nombre"> 

     <textarea ng-model="ctl.ticket.code"></textarea> 

     <button ng-click="ctl.send()">Enviar</button> 
    </div> 


    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> 
    <script> 
     var ws = new WebSocket("ws://localhost:2645/service"); 
     ws.binaryType = "arraybuffer"; 
     ws.onopen = function() { 
      console.log('connection is opened!!!'); 
     }; 

     ws.onmessage = function (evt) { 
      console.log(arrayBufferToString(evt.data)) 

     }; 

     ws.onclose = function() { 
      console.log("Connection is Closed...") 
     }; 

     function arrayBufferToString(buffer) { 
      var arr = new Uint8Array(buffer); 
      var str = String.fromCharCode.apply(String, arr); 

      return decodeURIComponent(escape(str)); 
     } 
     var app = angular.module('myapp', []); 
     app.controller('try', function() { 
      this.ticket= {nombre:'', estado:''} 

      this.send =() => { 
       var toSend= JSON.stringify(this.ticket); 
       ws.send(toSend); 
      } 
     }); 
    </script> 
</body> 

</html> 

continuación, enviar un código html de ZPL (escribe esto en código de área de texto);

^XA 
^FO200,50^BY2^B3N,N,80,Y,N^FD^FS 
^PQ1^XZ 
0

estoy usando QZ Tray para imprimir etiquetas desde una página Web para impresora térmica Zebra.

En la carpeta Bandeja de demo/js QZ hay tres archivos JavaScript que se requieren para comunicarse con la aplicación de la bandeja QZ - dependencies/rsvp-3.1.0.min.js, dependencies/sha-256.min.js y qz-tray.js.

incluir estos archivos JavaScript en su proyecto de la siguiente manera:

<script type="text/javascript" src="/lib/qz-tray/rsvp-3.1.0.min.js"></script> 
<script type="text/javascript" src="/lib/qz-tray/sha-256.min.js"></script> 
<script type="text/javascript" src="/lib/qz-tray/qz-tray.js"></script> 

La forma más sencilla de imprimir una etiqueta para impresora térmica Zebra se muestra a continuación.

<script type="text/javascript"> 
qz.websocket.connect().then(function() { 
    // Pass the printer name into the next Promise 
    return qz.printers.find("zebra"); 
}).then(function(printer) { 
    // Create a default config for the found printer 
    var config = qz.configs.create(printer); 

    // Raw ZPL 
    var data = ['^XA^FO50,50^ADN,36,20^FDRAW ZPL EXAMPLE^FS^XZ']; 

    return qz.print(config, data); 
}).catch(function(e) { console.error(e); }); 
</script> 

Consulte How to print labels from a web page to Zebra thermal printer para obtener más información.

Cuestiones relacionadas