import streamlit as st
import io
from reportlab.lib.pagesizes import inch
from reportlab.pdfgen import canvas
from reportlab.lib.colors import black
# Page dimensions
page_width = 6 * inch
page_height = 4 * inch
def draw_label(c, sku, notes, y_position, label_number=None, total_labels=None, show_counter=True):
# Draw horizontal line through the middle
middle_y = y_position + page_height / 2
c.setStrokeColor(black)
c.setLineWidth(1)
c.line(0, middle_y, page_width, middle_y)
# Top half - normal orientation
c.saveState()
font_size = 72
font_offset = font_size * 0.35
c.setFont("Helvetica", font_size)
center_x = page_width / 2
top_half_center_y = y_position + page_height * 3 / 4
sku_y = top_half_center_y - font_offset
c.drawCentredString(center_x, sku_y, sku)
c.setFont("Helvetica", 14)
notes_y = sku_y - 20
c.drawCentredString(center_x, notes_y, notes)
if show_counter and label_number and total_labels:
c.setFont("Helvetica", 10)
counter_text = f"{label_number}/{total_labels}"
counter_x = page_width - 0.3 * inch
counter_y = y_position + page_height / 2 + 0.2 * inch
c.drawRightString(counter_x, counter_y, counter_text)
c.restoreState()
# Bottom half - rotated 180 degrees
c.saveState()
center_x = page_width / 2
bottom_half_center_y = y_position + page_height / 4
c.translate(center_x, bottom_half_center_y)
c.rotate(180)
c.setFont("Helvetica", font_size)
c.drawCentredString(0, -font_offset, sku)
c.setFont("Helvetica", 14)
c.drawCentredString(0, -font_offset - 20, notes)
if show_counter and label_number and total_labels:
c.setFont("Helvetica", 10)
counter_text = f"{label_number}/{total_labels}"
counter_x = page_width / 2 - 0.3 * inch
counter_y = -page_height / 4 + 0.2 * inch
c.drawRightString(counter_x, counter_y, counter_text)
c.restoreState()
def generate_pdf(products, show_counter=True):
buffer = io.BytesIO()
c = canvas.Canvas(buffer, pagesize=(page_width, page_height))
total_labels = sum(count for _, _, count in products)
current_y = 0
label_number = 0
for sku, notes, count in products:
for _ in range(count):
label_number += 1
if current_y > 0:
c.showPage()
current_y = 0
draw_label(c, sku, notes, current_y, label_number, total_labels, show_counter)
current_y += page_height
c.save()
buffer.seek(0)
return buffer.getvalue()
# Streamlit App
st.set_page_config(page_title="Knife Label Generator", page_icon="🔪", layout="wide")
st.title("🔪 Knife Label Generator")
st.markdown("Generate foldable knife labels with SKU and notes on both sides.")
st.sidebar.header("Configuration")
show_counter = st.sidebar.checkbox("Show label counter", value=True)
if 'products' not in st.session_state:
st.session_state.products = [
{"sku": "KF1234", "notes": "Sample note 1", "count": 1},
{"sku": "", "notes": "", "count": 1},
{"sku": "", "notes": "", "count": 1},
]
st.header("Products")
if st.button("➕ Add Product"):
st.session_state.products.append({"sku": "", "notes": "", "count": 1})
products_to_remove = []
for idx, product in enumerate(st.session_state.products):
col1, col2, col3, col4 = st.columns([3, 4, 2, 1])
with col1:
product["sku"] = st.text_input("SKU", value=product["sku"], key=f"sku_{idx}",
label_visibility="collapsed", placeholder="SKU (e.g., KF1234)")
with col2:
product["notes"] = st.text_input("Notes", value=product["notes"], key=f"notes_{idx}",
label_visibility="collapsed", placeholder="Notes")
with col3:
product["count"] = st.number_input("Count", value=product["count"], min_value=1,
key=f"count_{idx}", label_visibility="collapsed")
with col4:
if st.button("🗑️", key=f"remove_{idx}"):
products_to_remove.append(idx)
for idx in reversed(products_to_remove):
st.session_state.products.pop(idx)
st.markdown("---")
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
if st.button("📄 Generate PDF", type="primary", use_container_width=True):
valid_products = [(p["sku"], p["notes"], p["count"])
for p in st.session_state.products if p["sku"].strip()]
if not valid_products:
st.error("Please add at least one product with a SKU.")
else:
with st.spinner("Generating PDF..."):
pdf_bytes = generate_pdf(valid_products, show_counter)
st.success(f"✅ PDF generated with {sum(c for _, _, c in valid_products)} labels!")
import time
st.download_button(
label="⬇️ Download PDF",
data=pdf_bytes,
file_name="knife_labels.pdf",
mime="application/pdf",
use_container_width=True,
key=f"download_{int(time.time() * 1000)}"
)
reportlab