Reputation: 3051
I am using Reportlab SimpleDocTemplate
to create a pdf file. I have to write (draw) multiple images row-wise so that I can adjust many images within the file.
class PrintBarCodes(View):
def get(self, request, format=None):
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment;\
filename="barcodes.pdf"'
# Close the PDF object cleanly, and we're done.
ean = barcode.get('ean13', '123456789102', writer=ImageWriter())
filename = ean.save('ean13')
doc = SimpleDocTemplate(response, pagesize=A4)
parts = []
parts.append(Image(filename))
doc.build(parts)
return response
In the code, I have printed a single barcode to the file. And, the output is showing in the images as can be seen below.
But, I need to draw a number of barcodes. How to reduce the image size before drawing to the pdf file and adjust in row fashion?
Upvotes: 2
Views: 1441
Reputation: 4532
As your question suggest that you need flexibility I think the most sensible approach is using Flowable
's. The barcode normally isn't one but we can make it one pretty easily. By doing so we can let platypus decide how much space there is in your layout for each barcode.
So step one the Barcode
Flowable
which looks like this:
from reportlab.graphics import renderPDF
from reportlab.graphics.barcode.eanbc import Ean13BarcodeWidget
from reportlab.graphics.shapes import Drawing
from reportlab.platypus import Flowable
class BarCode(Flowable):
# Based on https://stackoverflow.com/questions/18569682/use-qrcodewidget-or-plotarea-with-platypus
def __init__(self, value="1234567890", ratio=0.5):
# init and store rendering value
Flowable.__init__(self)
self.value = value
self.ratio = ratio
def wrap(self, availWidth, availHeight):
# Make the barcode fill the width while maintaining the ratio
self.width = availWidth
self.height = self.ratio * availWidth
return self.width, self.height
def draw(self):
# Flowable canvas
bar_code = Ean13BarcodeWidget(value=self.value)
bounds = bar_code.getBounds()
bar_width = bounds[2] - bounds[0]
bar_height = bounds[3] - bounds[1]
w = float(self.width)
h = float(self.height)
d = Drawing(w, h, transform=[w / bar_width, 0, 0, h / bar_height, 0, 0])
d.add(bar_code)
renderPDF.draw(d, self.canv, 0, 0)
Then to answer your question, the easiest way to now put multiple barcodes on one page would be using a Table
like so:
from reportlab.platypus import SimpleDocTemplate, Table
from reportlab.lib.pagesizes import A4
doc = SimpleDocTemplate("test.pdf", pagesize=A4)
table_data = [[BarCode(value='123'), BarCode(value='456')],
[BarCode(value='789'), BarCode(value='012')]]
barcode_table = Table(table_data)
parts = []
parts.append(barcode_table)
doc.build(parts)
Which outputs:
Upvotes: 2