Django ReportLab 错误 - 'str' 对象没有属性 'getKeepWithNext
我在用ReportLab生成PDF的时候,想加一张图片,却遇到了一个错误 - 'str'对象没有'getKeepWithNext'这个属性。
我使用的是Django 1.6。
以下是我的文件:
printing.py
import os.path
from reportlab.lib.pagesizes import letter, A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Image
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from reportlab.lib.units import inch
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.enums import TA_RIGHT
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from django.conf import settings
from catalog.models import Product
class MyPrint:
def __init__(self, buffer, pagesize):
self.buffer = buffer
if pagesize == 'A4':
self.pagesize = A4
elif pagesize == 'Letter':
self.pagesize = letter
self.width, self.height = self.pagesize
@staticmethod
def _header_footer(canvas, doc):
# Save the state of our canvas so we can draw on it
canvas.saveState()
styles = getSampleStyleSheet()
# Header
header = Paragraph('This is a multi-line header. It goes on every page. ' * 5, styles['Normal'])
w, h = header.wrap(doc.width, doc.topMargin)
header.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin - h)
# Footer
footer = Paragraph('This is a multi-line footer. It goes on every page. ' * 5, styles['Normal'])
w, h = footer.wrap(doc.width, doc.bottomMargin)
footer.drawOn(canvas, doc.leftMargin, h)
# Release the canvas
canvas.restoreState()
def print_products(self):
buffer = self.buffer
doc = SimpleDocTemplate(buffer,
rightMargin=inch/4,
leftMargin=inch/4,
topMargin=inch/2,
bottomMargin=inch/4,
pagesize=self.pagesize)
# Our container for 'Flowable' objects
elements = []
# A large collection of style sheets pre-made for us
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='centered', alignment=TA_CENTER))
styles.add(ParagraphStyle(name='RightAlign', fontName='Arial', align=TA_RIGHT))
# Draw things on the PDF. Here's where the PDF generation happens.
# See the ReportLab documentation for the full list of functionality.
products = Product.objects.all()
elements.append(Paragraph('My Products', styles['Heading1']))
elements.append('<img src="el45.jpg" height="5">')
for i, product in enumerate(products):
elements.append(Paragraph(product.info(), styles['Normal']))
doc.build(elements, onFirstPage=self._header_footer, onLaterPages=self._header_footer, canvasmaker=NumberedCanvas)
# Get the value of the BytesIO buffer and write it to the response.
pdf = buffer.getvalue()
buffer.close()
return pdf
class NumberedCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = []
def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()
def save(self):
"""add page info to each page (page x of y)"""
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.draw_page_number(num_pages)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)
def draw_page_number(self, page_count):
# Change the position of this to wherever you want the page number to be
self.drawRightString(211 * mm, 15 * mm + (0.2 * inch),
"Page %d of %d" % (self._pageNumber, page_count))
views.py
def print_products(request):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename="Product.pdf"'
buffer = BytesIO()
report = MyPrint(buffer, 'Letter')
pdf = report.print_products()
response.write(pdf)
return response
我的图片文件和这两个文件在同一个文件夹里。
1 个回答
3
你只能把 reportlab 的 Flowable
加入到故事中。如果你想添加一张图片,就得按照 reportlab 的方法来做:
把下面这行代码:
elements.append('<img src="el45.jpg" height="5">')
改成:
elements.append(Image('el45.jpg', width=None, height=5))
你需要调整宽度和高度的参数。而且,记得在设置大小的时候要乘上你想要的单位,比如 5*inch
。想要了解更多信息,可以查看 reportlab 用户手册的第 9.3 章!