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
"""
https://gist.github.com/lkrone/04ca0e3ae3a78f434e5ac84cfd9ca6b1
https://docs.djangoproject.com/fr/3.0/howto/outputting-pdf/
"""
from reportlab.lib.pagesizes import A4
from reportlab.graphics.shapes import Drawing, String
from reportlab.graphics.barcode.eanbc import Ean13BarcodeWidget
from reportlab.graphics import renderPDF
from reportlab.pdfgen import canvas
from reportlab.pdfbase.pdfmetrics import stringWidth
from reportlab.lib.units import mm
import io
PAGESIZE = A4
SHEET_TOP = PAGESIZE[1]
NUM_LABELS_X = 5
NUM_LABELS_Y = 13
TEXT_Y = 13 * mm
BARCODE_Y = 0
MM_LABEL_WIDTH = 38.1 + 1.95 # adjusted with actual printer and sheet
MM_LABEL_HEIGHT = 21.2 + 1.1 # adjusted with actual printer and sheet
MM_X_LABEL_PADDING = 2
MM_X_MARGIN = 19.5 / 2 - 4 # adjusted with actual printer and sheet
MM_Y_MARGIN = 21.4 / 2 - 10 # adjusted with actual printer and sheet
BAR_HEIGHT = 30.0
LABEL_WIDTH = MM_LABEL_WIDTH * mm
LABEL_HEIGHT = MM_LABEL_HEIGHT * mm
MAX_TEXT_WIDTH = LABEL_WIDTH - 1.5 * MM_X_LABEL_PADDING * mm
LABEL_FONT = "Helvetica"
FONT_SIZE = 7
def label(ean13, name):
"""
Generate a drawing with EAN-13 barcode and descriptive text.
:param ean13: The EAN-13 Code.
:param name: Product name
:return: Drawing with barcode and name
"""
name_part2 = ''
textWidth = stringWidth(name, LABEL_FONT, FONT_SIZE)
if textWidth > MAX_TEXT_WIDTH:
max_char = int(MAX_TEXT_WIDTH/textWidth * len(name))
if textWidth > 2 * MAX_TEXT_WIDTH:
name_part2 = name[max_char-1:max_char*2+1]
name = name[0:max_char-1]
else:
last_sp_idx = name.rindex(" ")
name_part2 = name[last_sp_idx+1:]
name = name[0:last_sp_idx]
if last_sp_idx > max_char:
#transfer some part of name to name_part2
while (name.rindex(" ") > 0 and len(name) > max_char):
last_sp_idx = name.rindex(" ")
name_part2 = name[last_sp_idx+1:] + ' ' + name_part2
name = name[0:last_sp_idx]
# truncate name
text1 = String(0, TEXT_Y, name, fontName=LABEL_FONT, fontSize=FONT_SIZE, textAnchor="start")
text1.x = 0
text2 = String(0, TEXT_Y - 2 *mm, name_part2, fontName=LABEL_FONT, fontSize=FONT_SIZE, textAnchor="start")
text2.x = 0
barcode = Ean13BarcodeWidget(ean13)
# bounds = barcode.getBounds()
# width = bounds[2] - bounds[0]
#height = bounds[3] - bounds[1]
# barcode.barWidth = BAR_WIDTH
barcode.barHeight = BAR_HEIGHT
barcode.x = 0
barcode.y = BARCODE_Y # spacing from label bottom (pt)
label_drawing = Drawing(LABEL_WIDTH, LABEL_HEIGHT)
label_drawing.add(text1)
label_drawing.add(text2)
label_drawing.add(barcode)
return label_drawing
def draw_page(c,sheet_data):
"""Exemple
{'qty': 18.0, 'ean13': '0490010003694', 'name': 'Bière Blonde Brasserie Aveze 75cl'}
{'qty': 18.0, 'ean13': '0490010003243', 'name': 'Bière IPA Brasserie Aveze 75cl'}
{'qty': 12.0, 'ean13': '0490010003236', 'name': 'Bière IPA Brasserie Aveze 33cl'}
{'qty': 6.0, 'ean13': '0490010003267', 'name': 'Bière Rousse Brasserie Aveze 75cl'}
"""
labels_to_draw = []
for l in sheet_data:
for k in range(0,int(l['qty'])):
labels_to_draw.append(label(l['ean13'],l['name']))
i = 0
y0 = SHEET_TOP - LABEL_HEIGHT - (MM_Y_MARGIN * mm)
for l2d in labels_to_draw:
x = MM_X_MARGIN * mm + (i%NUM_LABELS_X) * LABEL_WIDTH
y = y0 - int(i/NUM_LABELS_X)*LABEL_HEIGHT
renderPDF.draw(l2d, c, x, y)
i+=1
c.showPage() # stop drawing on the current page and any further operations will draw on a subsequent page
def pdf_generate(sheets):
# Create a file-like buffer to receive PDF data.
buffer = io.BytesIO()
# Create the PDF object, using the buffer as its "file."
p = canvas.Canvas(buffer)
for s in sheets:
draw_page(p, s)
p.save()
# FileResponse sets the Content-Disposition header so that browsers
# present the option to save the file.
buffer.seek(0)
return buffer