跪拜 Guibai
← Back to the summary

Pixel-Perfect Thermal Label Printing from the Browser with Vue 3 and QZ Tray

I. Architecture Design and Overall Flow

1.1 Comparison: Traditional vs. This Solution

In traditional thermal label printing, there are usually two routes:

Dimension TSPL/CPCL Raw Command Mode This Solution (Vue 3 + QZ Tray + Windows GDI / Bitmap Mode)
Development Cost Requires hand-writing low-level commands; complex positioning; difficult to preview Uses Vue 3 visual drag-and-drop components; What You See Is What You Get
Printer Compatibility Bound to specific brand command sets (e.g., TSC/Zebra) Driver-agnostic; prints as long as Windows can install a driver
Rich Text & Layout Complex tables, QR codes, adaptive font sizes are difficult to implement Perfectly supports arbitrary CSS layouts, multi-column tables, images, and QR codes
Maintainability Modifying templates requires rewriting logic commands Modify JSON templates; supports dynamic variable interpolation

1.2 System Architecture and Data Flow

flowchart TD
    A[Template JSON + Dynamic Asset Data] --> B[Vue 3 / JSX Virtual Canvas Component]
    B --> C{Print Mode Selection}
    C -->|Bitmap Mode QZ-Image| D[html2canvas 3x High-Res Rendering]
    C -->|HTML Mode QZ-Html| E[WebKit HTML/CSS Construction]
    D --> F[PNG Base64 Pixel Stream]
    E --> G[HTML Text Stream]
    F --> H[QZ Tray WebSocket Service]
    G --> H
    H --> I[Windows Print Spooler]
    I --> J[Yiwei A42 Thermal Printer]

II. Core Technical Implementation Details

2.1 Canvas Baseline and Adaptive Scaling Mechanism

To ensure precise alignment between the screen viewport (typically 96 DPI) and thermal printing hardware (typically 203 DPI or 300 DPI), the system establishes a unified physical conversion convention:

2.2 Bitmap Print Mode (qzImagePrint) Rendering Logic

Using html2canvas to convert the DOM into a lossless PNG image in browser memory avoids subtle differences in HTML font rendering across different operating systems and printer drivers:

// src/utils/printService.js
export async function pagesToPngBase64(pages) {
  const host = document.createElement('div');
  host.style.cssText = 'position:fixed;left:-99999px;top:0;background:#fff;pointer-events:none;';
  document.body.appendChild(host);

  const results = [];
  try {
    for (const page of pages) {
      const wrap = document.createElement('div');
      wrap.style.cssText = `width:${page.width}px;height:${page.height}px;background:#fff;overflow:hidden;position:relative;`;
      wrap.innerHTML = `<style>${PRINT_CSS}</style>${page.html}`;
      host.appendChild(wrap);

      await sleep(50);
      const canvas = await html2canvas(wrap, {
        backgroundColor: '#ffffff',
        scale: 3, // 300 DPI high-definition, high-density rendering
        useCORS: true,
        allowTaint: false,
        width: page.width,
        height: page.height,
        x: 0,
        y: 0,
        scrollX: 0,
        scrollY: 0,
        logging: false
      });

      const dataUrl = canvas.toDataURL('image/png');
      const base64 = dataUrl.replace(/^data:image\/png;base64,/, '');
      results.push({
        base64,
        width: page.width,
        height: page.height,
        widthMm: page.width / PX_PER_MM,
        heightMm: page.height / PX_PER_MM
      });
      wrap.remove();
    }
  } finally {
    host.remove();
  }
  return results;
}

III. Pitfall Avoidance Guide and Complete Troubleshooting Compendium

During the actual integration of the Yiwei A42 thermal printer with QZ Tray, we overcame 6 key issues, summarized below:

Pitfall 1: QZ Tray Auto-Flipping Width/Height Causes a Single Label to Span 2 Sheets


Pitfall 2: Windows Driver Default Media Size Mismatch Causes Cropping and Page Breaks


Pitfall 3: An Extra Blank Page Ejected After a Single-Page Print


Pitfall 4: Thin Font Lines Break, Ghost, or Appear Faint Like Low Ink


Pitfall 5: Table Bitmap Printing Produces Ghosting "Double Borders"


Pitfall 6: Pixel Misalignment Between Designer Editing Canvas and Print Preview


IV. Deployment and Production Environment Checklist

Before going live, please verify against the following checklist:


V. Conclusion

Through the Vue 3 + QZ Tray + Yiwei A42 adaptation solution provided in this article, we achieve high-precision, seamless, skip-free thermal label printing on the web without relying on specific hardware command sets (like TSPL/CPCL), by leveraging standard Windows print drivers and high-density bitmap rendering technology. This solution not only enhances the flexibility and visualization of frontend template design but also provides a standardized reference basis for industrial-grade web label printing.

VI. Git

https://github.com/kuma0605/label-designer-vue/tree/a42

The complete code is in the a42 branch. When printing, select Bitmap mode; HTML mode is still under improvement.

Comments

Top 1 of 4 from juejin.cn, machine-translated. The original thread is authoritative.

小趴菜_

Big bro, do you have the source code? I'd like to learn from it [thumbs up]

皮蛋小精灵

[grin] Yes

o卜善若水  → 皮蛋小精灵

[drool] Where can I see it?