forked from aborelis/ASN-Label-Generator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAveryLabels.py
More file actions
138 lines (122 loc) · 4.52 KB
/
AveryLabels.py
File metadata and controls
138 lines (122 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from collections.abc import Iterator
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm, cm
# Usage:
# label = AveryLabels.AveryLabel(5160)
# label.open( "labels5160.pdf" )
# label.render( RenderAddress, 30 )
# label.close()
#
# 'render' can either pass a callable, which receives the canvas object
# (with X,Y=0,0 at the lower right) or a string "form" name of a form
# previously created with canv.beginForm().
# labels across
# labels down
# label size w/h
# label gutter across/down
# page margins left/top
# page size w/h or name from reportlab.lib.pagesizes
labelInfo = {
5027: (5, 13, (38.1 * mm, 21.2 * mm), (0, 0), (10.95 * mm, 10.9 * mm), A4),
# 22x 32mm x 10mm mini labels
3044: (2, 11, (32, 10), (2, 2), (1, 1), (66.5 * mm, 120.5 * mm)),
# 189x 25.4mm x 10mm mini labels
4731: (7, 27, (25.4 * mm, 10 * mm), (2.5 * mm, 0), (9 * mm, 13.5 * mm), A4),
# 2.6 x 1 address labels
5160: (3, 10, (187, 72), (11, 0), (14, 36), A4),
5161: (2, 10, (288, 72), (0, 0), (18, 36), A4),
# 4 x 2 address labels
5163: (2, 5, (288, 144), (0, 0), (18, 36), A4),
# 1.75 x 0.5 return address labels
5167: (4, 20, (126, 36), (0, 0), (54, 36), A4),
# 3.5 x 2 business cards
5371: (2, 5, (252, 144), (0, 0), (54, 36), A4),
# 48x 45.7x21.2mm
4778: (4, 12, (45.7 * mm, 21.2 * mm), (0.25 * cm, 0), (1.1 * cm, 2 * cm), A4),
# APLI 100984 40x 52.5x29.7mm
100984: (4, 10, (52.5 * mm, 29.7 * mm), (0, 0), (0, 0), A4),
}
class AveryLabel:
def __init__(self, label, **kwargs):
data = labelInfo[label]
self.across = data[0]
self.down = data[1]
self.size = data[2]
self.labelsep = self.size[0] + data[3][0], self.size[1] + data[3][1]
self.margins = data[4]
self.top_down = True
self.debug = False
self.pagesize = data[5]
self.position = 0
self.__dict__.update(kwargs)
def open(self, filename):
"""open a canvas for the file"""
self.canvas = canvas.Canvas(filename, pagesize=self.pagesize)
if self.debug:
self.canvas.setPageCompression(0)
self.canvas.setLineJoin(1)
self.canvas.setLineCap(1)
def top_left(self, x=None, y=None):
""" return top left"""
if x is None:
x = self.position
if y is None:
if self.top_down:
x, y = divmod(x, self.down)
else:
y, x = divmod(x, self.across)
return (
self.margins[0] + x * self.labelsep[0],
self.pagesize[1] - self.margins[1] - (y + 1) * self.labelsep[1],
)
def advance(self):
""" move to next position"""
self.position += 1
if self.position == self.across * self.down:
self.canvas.showPage()
self.position = 0
def close(self):
"""save and close canvas"""
if self.position:
self.canvas.showPage()
self.canvas.save()
self.canvas = None
# To render, you can either create a template and tell me
# "go draw N of these templates" or provide a callback.
# Callback receives canvas, width, height.
#
# Or, pass a callable and an iterator. We'll do one label
# per iteration of the iterator.
def render(self, thing, count, offset=0, *args):
""" render loop"""
assert callable(thing) or isinstance(thing, str)
if isinstance(count, Iterator):
self.render_iterator(thing, count)
return
canv = self.canvas
for i in range(offset + count):
if i >= offset:
canv.saveState()
canv.translate(*self.top_left())
if self.debug:
canv.setLineWidth(0.25)
canv.rect(0, 0, self.size[0], self.size[1])
if callable(thing):
thing(canv, self.size[0], self.size[1], *args)
elif isinstance(thing, str):
canv.doForm(thing)
canv.restoreState()
self.advance()
def render_iterator(self, func, iterator):
""" render loop for iterator """
canv = self.canvas
for chunk in iterator:
canv.saveState()
canv.translate(*self.top_left())
if self.debug:
canv.setLineWidth(0.25)
canv.rect(0, 0, self.size[0], self.size[1])
func(canv, self.size[0], self.size[1], chunk)
canv.restoreState()
self.advance()