import os from io import BytesIO from reportlab.graphics.barcode import code128 from reportlab.lib.pagesizes import mm from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak from constants import APP_PATH class PDFGenerator: def __init__(self): ASSETS_FOLDER = os.path.join(APP_PATH, 'assets') FONTS_FOLDER = os.path.join(ASSETS_FOLDER, 'fonts') FONT_FILE_PATH = os.path.join(FONTS_FOLDER, 'DejaVuSans.ttf') self.page_width = 58 * mm self.page_height = 40 * mm pdfmetrics.registerFont(TTFont('DejaVuSans', FONT_FILE_PATH)) # Get standard styles and create a new style with a smaller font size styles = getSampleStyleSheet() self.small_style = ParagraphStyle( 'Small', parent=styles['Normal'], fontName='DejaVuSans', # Specify the new font fontSize=6, leading=7, spaceAfter=2, leftIndent=2, rightIndent=2 ) def generate(self, barcode_value, text, num_duplicates=1): buffer = BytesIO() # Create document with specified page size doc = SimpleDocTemplate(buffer, pagesize=(self.page_width, self.page_height), rightMargin=1 * mm, leftMargin=1 * mm, topMargin=1 * mm, bottomMargin=1 * mm) # Create paragraph with new style paragraph = Paragraph(text, self.small_style) # Create barcode barcode = code128.Code128(barcode_value, humanReadable=True) # Function to draw barcode on canvas def add_barcode(canvas, doc): barcode_width = barcode.width barcode_x = (self.page_width - barcode_width) / 2 # Center the barcode barcode.drawOn(canvas, barcode_x, self.page_height - barcode.height - 5) # Create list of elements to add to the document elements = [] for _ in range(num_duplicates): elements.append(Spacer(1, 8 * mm)) elements.append(paragraph) elements.append(PageBreak()) # Build document doc.build(elements[:-1], onFirstPage=add_barcode, onLaterPages=add_barcode) # Remove the last PageBreak buffer.seek(0) return buffer