Skip to content

Commit

Permalink
add avery barcode generator script
Browse files Browse the repository at this point in the history
  • Loading branch information
jantman committed Aug 18, 2022
1 parent dba5680 commit 8d9baa8
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ file.
* __apache_log_verify_site_move.py__ - Python script that parses Apache HTTPD access logs, finds all unique URLs, and compares the current HTTP response code to that of another server. Useful when moving a site.
* __artifactory_support_bundle.py__ - Python script using ``requests`` to generate, list, and download JFrog Artifactory support bundles via the ReST API, from one or more instances/nodes.
* __asg_instances.py__ - Script to list instances in an ASG and their IP addresses, given an ASG name.
* __avery5160_code128_numeric.py__ - Script to generate PDFs of numeric-series Code128 barcodes (with optional prefixes) to fit Avery 5160-size labels.
* __avery5160_code128_numeric-example.pdf__ - Example output of the above script.
* __aws_api_gateway_lint.py__ - Script using boto3 to attempt to identify unused or idle API Gateways.
* __aws-count-tag-names.py__ - Using boto3, scan all AWS resources in the current account, and produce a report detailing all of the distinct tag names and the number of resources having each one.
* __aws_creds_report_csv_filter.py__ - Filter the AWS IAM Credentials Report (CSV) by credential age and/or last used time.
Expand Down
Binary file added avery5160_code128_numeric-example.pdf
Binary file not shown.
115 changes: 115 additions & 0 deletions avery5160_code128_numeric.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"""
Script to generate PDFs for numerically sequenced Code128 barcode labels on
Avery 5160 / 18260 label sheets.
When printing, force rasterization and fit to full page.
Tested with Python 3.10.5 and the following dependencies:
autopep8==1.7.0
Pillow==9.2.0
pycodestyle==2.9.1
reportlab==3.6.11
toml==0.10.2
"""
import sys
import argparse
from typing import Tuple, Optional

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import LETTER
from reportlab.lib.units import inch, mm
from reportlab.graphics.barcode import code128


class Avery5160Code128Numeric():

def __init__(
self, output_filename: str, padlen: int = 6,
prefix: Optional[str] = None
):
self.output_filename: str = output_filename
self.padlen: int = padlen
self.prefix: Optional[str] = prefix
self.canv: canvas.Canvas = canvas.Canvas(self.output_filename, pagesize=LETTER)
self.canv.setPageCompression(0)
self.bottom_margin: float = 0.5 * inch
self.left_margin: float = (3/16) * inch
self.row_spacing: float = 0.0
self.col_spacing: float = (1/8) * inch
self.cell_height: float = 1 * inch
self.cell_width: float = (2 + (5/8)) * inch
self.num_cols: int = 3
self.num_rows: int = 10

def _xy_for_cell(self, colnum: int, rownum: int) -> Tuple[float, float]:
"""
Given a cell number, return the (x, y) coords for its bottom left corner
:param rownum: zero-base row number, left to right
:param colnum: zero-base colnum number, top down. NOTE this is the opposite of reportlab PDF coordinates, which have zero on the bottom of the page.
"""
x: float = self.left_margin + (rownum * (self.cell_width + self.col_spacing))
y: float = self.bottom_margin + ((self.num_rows - (colnum + 1)) * (self.cell_height + self.row_spacing))
return x, y

def _generate_cell(self, col: int, row: int, value: int):
s: str = f'{value:0{self.padlen}}'
if self.prefix is not None:
s = f'{self.prefix}{value:0{self.padlen}}'
x: float
y: float
x, y = self._xy_for_cell(row, col)
# temporary outline for label cell, for testing
# self.canv.rect(x, y, self.cell_width, self.cell_height, stroke=1, fill=0)
self.canv.drawCentredString(
x + (self.cell_width / 2),
y + (0.20 * inch),
s
)
barcode = code128.Code128(s, barHeight=10*mm, barWidth=1)
barcode.drawOn(
self.canv,
x + ((self.cell_width - barcode.width) / 2),
y + 34
)

def run(self, start_num: int, num_pages: int):
count: int = start_num
for pagenum in range(0, num_pages):
for colnum in range(0, 3):
for rownum in range(0, 10):
self._generate_cell(colnum, rownum, count)
count += 1
self.canv.showPage()
self.canv.save()


if __name__ == "__main__":
p = argparse.ArgumentParser(
description='Script to generate PDFs for numerically sequenced Code128 '
'barcode labels on Avery 5160 / 18260 label sheets.'
)
p.add_argument(
'-p', '--pad-length', action='store', type=int, dest='padlen',
default=6, help='Padding length for barcode; default: 6'
)
p.add_argument(
'-P', '--prefix', action='store', type=str, dest='prefix',
default=None, help='Prefix to add to barcodes; default None'
)
p.add_argument(
'START_NUMBER', action='store', type=int,
help='Starting number for first barcode label'
)
p.add_argument(
'NUM_PAGES', action='store', type=int,
help='Number of pages of barcodes to generate'
)
args = p.parse_args(sys.argv[1:])
Avery5160Code128Numeric(
'labels.pdf', padlen=args.padlen, prefix=args.prefix
).run(
start_num=args.START_NUMBER, num_pages=args.NUM_PAGES
)

0 comments on commit 8d9baa8

Please sign in to comment.