# Barcodes Reference Comprehensive guide to creating barcodes and QR codes in ReportLab. ## Available Barcode Types ReportLab supports a wide range of 1D and 2D barcode formats. ### 1D Barcodes (Linear) - **Code128** - Compact, encodes full ASCII - **Code39** (Standard39) - Alphanumeric, widely supported - **Code93** (Standard93) - Compressed Code39 - **EAN-13** - European Article Number (retail) - **EAN-8** - Short form of EAN - **EAN-5** - 5-digit add-on (pricing) - **UPC-A** - Universal Product Code (North America) - **ISBN** - International Standard Book Number - **Code11** - Telecommunications - **Codabar** - Blood banks, FedEx, libraries - **I2of5** (Interleaved 2 of 5) - Warehouse/distribution - **MSI** - Inventory control - **POSTNET** - US Postal Service - **USPS_4State** - US Postal Service - **FIM** (A, B, C, D) - Facing Identification Mark (mail sorting) ### 2D Barcodes - **QR** - QR Code (widely used for URLs, contact info) - **ECC200DataMatrix** - Data Matrix format ## Using Barcodes with Canvas ### Code128 (Recommended for General Use) Code128 is versatile and compact - encodes full ASCII character set with mandatory checksum. ```python from reportlab.pdfgen import canvas from reportlab.graphics.barcode import code128 from reportlab.lib.units import inch c = canvas.Canvas("barcode.pdf") # Create barcode barcode = code128.Code128("HELLO123") # Draw on canvas barcode.drawOn(c, 1*inch, 5*inch) c.save() ``` ### Code128 Options ```python barcode = code128.Code128( value="ABC123", # Required: data to encode barWidth=0.01*inch, # Width of narrowest bar barHeight=0.5*inch, # Height of bars quiet=1, # Add quiet zones (margins) lquiet=None, # Left quiet zone width rquiet=None, # Right quiet zone width stop=1, # Show stop symbol ) # Draw with specific size barcode.drawOn(canvas, x, y) # Get dimensions width = barcode.width height = barcode.height ``` ### Code39 (Standard39) Supports: 0-9, A-Z (uppercase), space, and special chars (-.$/+%*). ```python from reportlab.graphics.barcode import code39 barcode = code39.Standard39( value="HELLO", barWidth=0.01*inch, barHeight=0.5*inch, quiet=1, checksum=0, # 0 or 1 ) barcode.drawOn(canvas, x, y) ``` ### Extended Code39 Encodes full ASCII (pairs of Code39 characters). ```python from reportlab.graphics.barcode import code39 barcode = code39.Extended39( value="Hello World!", # Can include lowercase and symbols barWidth=0.01*inch, barHeight=0.5*inch, ) barcode.drawOn(canvas, x, y) ``` ### Code93 ```python from reportlab.graphics.barcode import code93 # Standard93 - uppercase, digits, some symbols barcode = code93.Standard93( value="HELLO93", barWidth=0.01*inch, barHeight=0.5*inch, ) # Extended93 - full ASCII barcode = code93.Extended93( value="Hello 93!", barWidth=0.01*inch, barHeight=0.5*inch, ) barcode.drawOn(canvas, x, y) ``` ### EAN-13 (European Article Number) 13-digit barcode for retail products. ```python from reportlab.graphics.barcode import eanbc # Must be exactly 12 digits (13th is calculated checksum) barcode = eanbc.Ean13BarcodeWidget( value="123456789012" ) # Draw from reportlab.graphics import renderPDF from reportlab.graphics.shapes import Drawing d = Drawing() d.add(barcode) renderPDF.draw(d, canvas, x, y) ``` ### EAN-8 Short form, 8 digits. ```python from reportlab.graphics.barcode import eanbc # Must be exactly 7 digits (8th is calculated) barcode = eanbc.Ean8BarcodeWidget( value="1234567" ) ``` ### UPC-A 12-digit barcode used in North America. ```python from reportlab.graphics.barcode import usps # 11 digits (12th is checksum) barcode = usps.UPCA( value="01234567890" ) barcode.drawOn(canvas, x, y) ``` ### ISBN (Books) ```python from reportlab.graphics.barcode.widgets import ISBNBarcodeWidget # 10 or 13 digit ISBN barcode = ISBNBarcodeWidget( value="978-0-123456-78-9" ) # With pricing (EAN-5 add-on) barcode = ISBNBarcodeWidget( value="978-0-123456-78-9", price=True, ) ``` ### QR Codes Most versatile 2D barcode - can encode URLs, text, contact info, etc. ```python from reportlab.graphics.barcode.qr import QrCodeWidget from reportlab.graphics.shapes import Drawing from reportlab.graphics import renderPDF # Create QR code qr = QrCodeWidget("https://example.com") # Size in pixels (QR codes are square) qr.barWidth = 100 # Width in points qr.barHeight = 100 # Height in points # Error correction level # L = 7% recovery, M = 15%, Q = 25%, H = 30% qr.qrVersion = 1 # Auto-size (1-40, or None for auto) qr.errorLevel = 'M' # L, M, Q, H # Draw d = Drawing() d.add(qr) renderPDF.draw(d, canvas, x, y) ``` ### QR Code - More Options ```python # URL QR Code qr = QrCodeWidget("https://example.com") # Contact information (vCard) vcard_data = """BEGIN:VCARD VERSION:3.0 FN:John Doe TEL:+1-555-1234 EMAIL:john@example.com END:VCARD""" qr = QrCodeWidget(vcard_data) # WiFi credentials wifi_data = "WIFI:T:WPA;S:NetworkName;P:Password;;" qr = QrCodeWidget(wifi_data) # Plain text qr = QrCodeWidget("Any text here") ``` ### Data Matrix (ECC200) Compact 2D barcode for small items. ```python from reportlab.graphics.barcode.datamatrix import DataMatrixWidget barcode = DataMatrixWidget( value="DATA123" ) d = Drawing() d.add(barcode) renderPDF.draw(d, canvas, x, y) ``` ### Postal Barcodes ```python from reportlab.graphics.barcode import usps # POSTNET (older format) barcode = usps.POSTNET( value="55555-1234", # ZIP or ZIP+4 ) # USPS 4-State (newer) barcode = usps.USPS_4State( value="12345678901234567890", # 20-digit routing code routing="12345678901" ) barcode.drawOn(canvas, x, y) ``` ### FIM (Facing Identification Mark) Used for mail sorting. ```python from reportlab.graphics.barcode import usps # FIM-A, FIM-B, FIM-C, or FIM-D barcode = usps.FIM( value="A" # A, B, C, or D ) barcode.drawOn(canvas, x, y) ``` ## Using Barcodes with Platypus For flowing documents, wrap barcodes in Flowables. ### Simple Approach - Drawing Flowable ```python from reportlab.graphics.shapes import Drawing from reportlab.graphics.barcode.qr import QrCodeWidget from reportlab.lib.units import inch # Create drawing d = Drawing(2*inch, 2*inch) # Create barcode qr = QrCodeWidget("https://example.com") qr.barWidth = 2*inch qr.barHeight = 2*inch qr.x = 0 qr.y = 0 d.add(qr) # Add to story story.append(d) ``` ### Custom Flowable Wrapper ```python from reportlab.platypus import Flowable from reportlab.graphics.barcode import code128 from reportlab.lib.units import inch class BarcodeFlowable(Flowable): def __init__(self, code, barcode_type='code128', width=2*inch, height=0.5*inch): Flowable.__init__(self) self.code = code self.barcode_type = barcode_type self.width_val = width self.height_val = height # Create barcode if barcode_type == 'code128': self.barcode = code128.Code128(code, barWidth=width/100, barHeight=height) # Add other types as needed def draw(self): self.barcode.drawOn(self.canv, 0, 0) def wrap(self, availWidth, availHeight): return (self.barcode.width, self.barcode.height) # Use in story story.append(BarcodeFlowable("PRODUCT123")) ``` ## Complete Examples ### Product Label with Barcode ```python from reportlab.pdfgen import canvas from reportlab.graphics.barcode import code128 from reportlab.lib.pagesizes import letter from reportlab.lib.units import inch def create_product_label(filename, product_code, product_name): c = canvas.Canvas(filename, pagesize=(4*inch, 2*inch)) # Product name c.setFont("Helvetica-Bold", 14) c.drawCentredString(2*inch, 1.5*inch, product_name) # Barcode barcode = code128.Code128(product_code) barcode_width = barcode.width barcode_height = barcode.height # Center barcode x = (4*inch - barcode_width) / 2 y = 0.5*inch barcode.drawOn(c, x, y) # Code text c.setFont("Courier", 10) c.drawCentredString(2*inch, 0.3*inch, product_code) c.save() create_product_label("label.pdf", "ABC123456789", "Premium Widget") ``` ### QR Code Contact Card ```python from reportlab.pdfgen import canvas from reportlab.graphics.barcode.qr import QrCodeWidget from reportlab.graphics.shapes import Drawing from reportlab.graphics import renderPDF from reportlab.lib.units import inch def create_contact_card(filename, name, phone, email): c = canvas.Canvas(filename, pagesize=(3.5*inch, 2*inch)) # Contact info c.setFont("Helvetica-Bold", 12) c.drawString(0.5*inch, 1.5*inch, name) c.setFont("Helvetica", 10) c.drawString(0.5*inch, 1.3*inch, phone) c.drawString(0.5*inch, 1.1*inch, email) # Create vCard data vcard = f"""BEGIN:VCARD VERSION:3.0 FN:{name} TEL:{phone} EMAIL:{email} END:VCARD""" # QR code qr = QrCodeWidget(vcard) qr.barWidth = 1.5*inch qr.barHeight = 1.5*inch d = Drawing() d.add(qr) renderPDF.draw(d, c, 1.8*inch, 0.2*inch) c.save() create_contact_card("contact.pdf", "John Doe", "+1-555-1234", "john@example.com") ``` ### Shipping Label with Multiple Barcodes ```python from reportlab.pdfgen import canvas from reportlab.graphics.barcode import code128 from reportlab.lib.units import inch def create_shipping_label(filename, tracking_code, zip_code): c = canvas.Canvas(filename, pagesize=(6*inch, 4*inch)) # Title c.setFont("Helvetica-Bold", 16) c.drawString(0.5*inch, 3.5*inch, "SHIPPING LABEL") # Tracking barcode c.setFont("Helvetica", 10) c.drawString(0.5*inch, 2.8*inch, "Tracking Number:") tracking_barcode = code128.Code128(tracking_code, barHeight=0.5*inch) tracking_barcode.drawOn(c, 0.5*inch, 2*inch) c.setFont("Courier", 9) c.drawString(0.5*inch, 1.8*inch, tracking_code) # Additional info can be added c.save() create_shipping_label("shipping.pdf", "1Z999AA10123456784", "12345") ``` ## Barcode Selection Guide **Choose Code128 when:** - General purpose encoding - Need to encode numbers and letters - Want compact size - Widely supported **Choose Code39 when:** - Older systems require it - Don't need lowercase letters - Want maximum compatibility **Choose QR Code when:** - Need to encode URLs - Want mobile device scanning - Need high data capacity - Want error correction **Choose EAN/UPC when:** - Retail product identification - Need industry-standard format - Global distribution **Choose Data Matrix when:** - Very limited space - Small items (PCB, electronics) - Need 2D compact format ## Best Practices 1. **Test scanning** early with actual barcode scanners/readers 2. **Add quiet zones** (white space) around barcodes - set `quiet=1` 3. **Choose appropriate height** - taller barcodes are easier to scan 4. **Include human-readable text** below barcode for manual entry 5. **Use Code128** as default for general purpose - it's compact and versatile 6. **For URLs, use QR codes** - much easier for mobile users 7. **Check barcode standards** for your industry (retail uses EAN/UPC) 8. **Test print quality** - low DPI can make barcodes unscannable 9. **Validate data** before encoding - wrong check digits cause issues 10. **Consider error correction** for QR codes - use 'M' or 'H' for important data