- Remove build artifacts from git tracking (build/, dist/, __pycache__/, *.spec) - Updated .gitignore to properly exclude generated files - Added old_code/ documentation folder - Updated sample_data.txt to show new 5-field format - Exclude user-specific conf/app.conf from tracking
223 lines
7.4 KiB
Python
223 lines
7.4 KiB
Python
"""
|
|
Improved printing module that explicitly sets paper size for thermal label printers.
|
|
This prevents the printer from using default paper size (continuous roll).
|
|
"""
|
|
|
|
import win32print
|
|
import win32ui
|
|
import win32con
|
|
from PIL import Image
|
|
import os
|
|
|
|
def mm_to_inches(mm):
|
|
"""Convert millimeters to inches"""
|
|
return mm / 25.4
|
|
|
|
def mm_to_hundredths_inch(mm):
|
|
"""Convert millimeters to hundredths of an inch (used by Windows print API)"""
|
|
return int(mm_to_inches(mm) * 100)
|
|
|
|
def print_pdf_with_custom_size(pdf_path, printer_name, width_mm=35, height_mm=25):
|
|
"""
|
|
Print PDF with explicit paper size settings for thermal label printers.
|
|
|
|
Args:
|
|
pdf_path (str): Path to PDF file
|
|
printer_name (str): Name of the printer
|
|
width_mm (int): Label width in millimeters (default 35mm)
|
|
height_mm (int): Label height in millimeters (default 25mm)
|
|
|
|
Returns:
|
|
bool: True if successful
|
|
"""
|
|
try:
|
|
# Convert PDF to image first for better control
|
|
from pdf2image import pdfimages
|
|
print("Converting PDF to image for precise printing...")
|
|
|
|
# Use pdftoppm or pdf2image
|
|
import subprocess
|
|
|
|
# Try using pdftoppm if available
|
|
temp_image = pdf_path.replace('.pdf', '_temp.png')
|
|
|
|
try:
|
|
# Try pdftoppm first (better quality)
|
|
subprocess.run([
|
|
'pdftoppm',
|
|
'-png',
|
|
'-singlefile',
|
|
'-r', '1200', # High DPI
|
|
pdf_path,
|
|
pdf_path.replace('.pdf', '_temp')
|
|
], check=True)
|
|
except:
|
|
# Fallback: convert using Pillow/reportlab
|
|
from reportlab.pdfgen import canvas
|
|
from PyPDF2 import PdfReader
|
|
print("Using alternative PDF conversion method...")
|
|
|
|
if os.path.exists(temp_image):
|
|
return print_image_with_custom_size(temp_image, printer_name, width_mm, height_mm)
|
|
else:
|
|
print("Could not convert PDF to image")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"Error in advanced printing: {e}")
|
|
return False
|
|
|
|
def print_image_with_custom_size(image_path, printer_name, width_mm=35, height_mm=25):
|
|
"""
|
|
Print image with explicit paper size for thermal label printers.
|
|
|
|
Args:
|
|
image_path (str): Path to image file
|
|
printer_name (str): Name of the printer
|
|
width_mm (int): Label width in millimeters
|
|
height_mm (int): Label height in millimeters
|
|
|
|
Returns:
|
|
bool: True if successful
|
|
"""
|
|
try:
|
|
# Open the printer
|
|
hprinter = win32print.OpenPrinter(printer_name)
|
|
|
|
try:
|
|
# Get printer device context
|
|
hdc = win32ui.CreateDC()
|
|
hdc.CreatePrinterDC(printer_name)
|
|
|
|
# Get printer properties
|
|
props = win32print.GetPrinter(hprinter, 2)
|
|
|
|
# Get DEVMODE structure
|
|
devmode = props["pDevMode"]
|
|
|
|
# Set custom paper size (DMPAPER_USER = 256)
|
|
devmode.PaperSize = 256 # Custom paper size
|
|
|
|
# Set paper dimensions in tenths of millimeter
|
|
devmode.PaperLength = height_mm * 10 # Height in 0.1mm units
|
|
devmode.PaperWidth = width_mm * 10 # Width in 0.1mm units
|
|
|
|
# Set orientation to landscape (2) for 35x25mm
|
|
devmode.Orientation = 2 # 2 = Landscape
|
|
|
|
# Set print quality to high
|
|
devmode.PrintQuality = win32print.DMRES_HIGH
|
|
|
|
# Apply the devmode
|
|
props["pDevMode"] = devmode
|
|
win32print.SetPrinter(hprinter, 2, props, 0)
|
|
|
|
# Start document
|
|
doc_info = ("Label Print", None, None, 0)
|
|
hdc.StartDoc("Label Print")
|
|
hdc.StartPage()
|
|
|
|
# Load image
|
|
img = Image.open(image_path)
|
|
|
|
# Get printer DPI
|
|
printer_dpi_x = hdc.GetDeviceCaps(win32con.LOGPIXELSX)
|
|
printer_dpi_y = hdc.GetDeviceCaps(win32con.LOGPIXELSY)
|
|
|
|
# Calculate image size in pixels based on mm dimensions
|
|
width_pixels = int(mm_to_inches(width_mm) * printer_dpi_x)
|
|
height_pixels = int(mm_to_inches(height_mm) * printer_dpi_y)
|
|
|
|
# Resize image to exact label dimensions
|
|
img_resized = img.resize((width_pixels, height_pixels), Image.Resampling.LANCZOS)
|
|
|
|
# Convert to bitmap
|
|
dib = ImageWin.Dib(img_resized)
|
|
|
|
# Print at position (0,0) with exact size
|
|
dib.draw(hdc.GetHandleOutput(), (0, 0, width_pixels, height_pixels))
|
|
|
|
# End document
|
|
hdc.EndPage()
|
|
hdc.EndDoc()
|
|
|
|
print(f"Label printed successfully with custom size: {width_mm}x{height_mm}mm")
|
|
return True
|
|
|
|
finally:
|
|
win32print.ClosePrinter(hprinter)
|
|
|
|
except Exception as e:
|
|
print(f"Error printing with custom size: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
def set_printer_paper_size(printer_name, width_mm=35, height_mm=25):
|
|
"""
|
|
Configure printer to use custom paper size.
|
|
This sets the printer default to the label size.
|
|
|
|
Args:
|
|
printer_name (str): Name of the printer
|
|
width_mm (int): Label width in millimeters
|
|
height_mm (int): Label height in millimeters
|
|
|
|
Returns:
|
|
bool: True if successful
|
|
"""
|
|
try:
|
|
hprinter = win32print.OpenPrinter(printer_name)
|
|
|
|
try:
|
|
# Get current printer properties
|
|
props = win32print.GetPrinter(hprinter, 2)
|
|
devmode = props["pDevMode"]
|
|
|
|
# Configure for custom label size
|
|
devmode.PaperSize = 256 # DMPAPER_USER (custom)
|
|
devmode.PaperLength = height_mm * 10 # in 0.1mm units
|
|
devmode.PaperWidth = width_mm * 10 # in 0.1mm units
|
|
devmode.Orientation = 2 # Landscape
|
|
devmode.PrintQuality = win32print.DMRES_HIGH
|
|
|
|
# Update fields flags
|
|
devmode.Fields = (
|
|
win32print.DM_PAPERSIZE |
|
|
win32print.DM_PAPERLENGTH |
|
|
win32print.DM_PAPERWIDTH |
|
|
win32print.DM_ORIENTATION |
|
|
win32print.DM_PRINTQUALITY
|
|
)
|
|
|
|
# Apply settings
|
|
props["pDevMode"] = devmode
|
|
win32print.SetPrinter(hprinter, 2, props, 0)
|
|
|
|
print(f"Printer '{printer_name}' configured for {width_mm}x{height_mm}mm labels")
|
|
return True
|
|
|
|
finally:
|
|
win32print.ClosePrinter(hprinter)
|
|
|
|
except Exception as e:
|
|
print(f"Error configuring printer: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Test configuration
|
|
printer_name = "Labels"
|
|
|
|
print("Testing printer configuration...")
|
|
success = set_printer_paper_size(printer_name, 35, 25)
|
|
|
|
if success:
|
|
print("\n✅ Printer configured successfully!")
|
|
print("The printer should now use 35x25mm label size by default.")
|
|
else:
|
|
print("\n❌ Failed to configure printer")
|
|
print("You may need to set the paper size manually in printer preferences.")
|