reactjsnext.jszpltspl

Print Canvas with ZPL or TSPL command for zebra printer by WebUSB


If you need print your custom design or canvas design in react or next js you can do this


Solution

  • first you need Convert you canvas to Hex code

    const canvasRef = useRef<HTMLCanvasElement>(null);
    function convertCanvasToHex(canvas: any, threshold = 128) {
      const ctx = canvas.getContext("2d");
      const { width, height } = canvas;
      const imageData = ctx.getImageData(0, 0, width, height).data;
    
      const rowBytes = Math.ceil(width / 8);
      let hexData = "";
    
      // Process every row
      for (let y = 0; y < height; y++) {
        for (let bx = 0; bx < rowBytes; bx++) {
          let byte = 0;
          for (let bit = 0; bit < 8; bit++) {
            const x = bx * 8 + bit;
            let pixelOn = 0;
            if (x < width) {
              const index = (y * width + x) * 4;
              // Convert pixel to grayscale using average or luma formula.
              // Here, using a simple average.
              const r = imageData[index];
              const g = imageData[index + 1];
              const b = imageData[index + 2];
              const luma = 0.299 * r + 0.587 * g + 0.114 * b;
              if (luma < threshold) {
                pixelOn = 1;
              }
            }
            // Most printers consider the MSB as the left-most pixel.
            byte |= pixelOn << (7 - bit);
          }
          // Convert the byte to a two-character hex string.
          let hexByte = byte.toString(16).toUpperCase();
          if (hexByte.length === 1) {
            hexByte = "0" + hexByte;
          }
          hexData += hexByte;
        }
      }
    
      return { hexData };
    }
    

    and after you can do print by this command

    async function requestDevice() {
      //@ts-ignore because usb in navigator not fond in ts
      const devices = await navigator.usb.getDevices();
    
      const printer = devices.find(
        (item: any) => item.manufacturerName === "IDPrinter",
      );
      if (printer === undefined) {
        callToast("printer not connected");
      } else {
        //@ts-ignore because usb in navigator not fond in ts
        const device = await navigator.usb.requestDevice({
          filters: [
            { vendorId: printer?.vendorId, productId: printer?.productId },
          ],
        });
    
        const canvas = generateLabelCanvas();
    
        const { hexData } = convertCanvasToHex(canvas);
    
        const zplCommand = `
        ^XA
        ^FO50,0^GB0,0,0^FS
        ^GFA,${hexData.length},${hexData.length},100,${hexData}
        ^XZ
        `;
    
        const encoder = new TextEncoder();
    
        const rawData = encoder.encode(zplCommand);
        const buffer = new Uint8Array(rawData).buffer;
    
        await device.open();
        await device.selectConfiguration(1);
        await device.claimInterface(0);
    
        await device.transferOut(1, buffer);
    
        callToast("print command was send");
    
        await device.close();
        console.log("printer disconnected");
      }
    }