使用reportlab.platypus创建具有基于内容长度的动态高度的pdf

问题描述 投票:0回答:0

正在使用 django Rest 框架中的 reportlab 创建销售收据。我希望所有收据内容都在一页中,因此高度应该根据购买的产品数量动态变化。宽度固定为80mm。为了设计收据,我将高度设置为 1000 点,以容纳一页中的所有内容。 Here is the output of the receipt

这是生成收据的代码。

def generate_receipt_pdf(self, products_data, total_sales, cash_received, change, username):
        doc = BaseDocTemplate("sales_receipt.pdf", pagesize=portrait((226.08, 1000)), leftMargin=0,
                    rightMargin=0,
                    topMargin=14.17,
                    bottomMargin=0,)

        elements = []

        styles = getSampleStyleSheet()
        styles['Heading5'].fontName = 'Helvetica'
        styles['Heading5'].alignment = TA_CENTER
        styles['Heading5'].spaceAfter = 0
        styles['Heading5'].spaceBefore = 3

        elements.append(Paragraph("Denloy Investments", styles['Heading5']))
        elements.append(Paragraph("P.O. BOX 617", styles['Heading5']))
        elements.append(Paragraph("KERUGOYA", styles['Heading5']))

        styles['Heading5'].fontName = 'Helvetica-Bold'
        elements.append(Spacer(1, 6))
        elements.append(Paragraph("Sales Receipt", styles['Heading5']))
        elements.append(Spacer(1, 6))

        current_time = get_current_time()
        styles['Heading6'].fontName = 'Helvetica'
        elements.append(Paragraph(f"Date: {current_time.strftime('%d/%m/%Y')} {current_time.strftime('%I:%M %p')}", styles['Heading6']))
        elements.append(Paragraph(f"Cashier: {username.capitalize()}", styles['Heading6']))
        elements.append(Spacer(1, 6))

        styles['Normal'].fontSize = 7
        product_name_style = ParagraphStyle(
            name='product_name_style',
            fontName='Helvetica',
            fontSize=7,
            alignment=TA_LEFT,
            spaceAfter=0,
            spaceBefore=0,
        )

        # Convert products_data to a list of rows for the table
        table_data = [["Product Name", "Price", "", "Amount"]]
        for product in products_data:
            row = [Paragraph(product['product_name'], product_name_style), str(product['unitPrice']), f"x{str(product['units'])}", str(product['amount'])]
            table_data.append(row)

        spacer_row = ["", "--------------------", "", "---------"]
        table_data.append(spacer_row)
        total_row = ["", "Total", "", Paragraph(str(total_sales), styles['Normal'])]
        table_data.append(total_row)
        cash_row = ["", "Cash Received", "", Paragraph(str(cash_received), styles['Normal'])]
        table_data.append(cash_row)
        change_row = ["", "Change", "", Paragraph(str(change), styles['Normal'])]
        table_data.append(change_row)

        table = Table(table_data, colWidths=[116, 40, 20, 50])
        style = TableStyle([
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 1),
            ('FONTSIZE', (0, 0), (-1, -1), 7),
            ('BOTTOMPADDING', (0, 1), (-1, -1), 0),
        ])

        table.setStyle(style)
        elements.append(table)

        styles['Normal'].alignment = TA_CENTER
        elements.append(Spacer(1, 6))
        elements.append(Paragraph("________________________________", styles['Normal']))
        elements.append(Paragraph("Thank you for shopping with us.", styles['Normal']))
        elements.append(Spacer(1, 6))

        page_frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
        main_template = PageTemplate(frames=[page_frame])
        doc.addPageTemplates(main_template)

        doc.build(elements)
        with open("sales_receipt.pdf", "rb") as pdf_file:
            pdf_content = pdf_file.read()

        return pdf_content

经过研究,我尝试将高度设置为“无”,但它只需要浮动类型,我也尝试使用KeepInFrame,但它以没有属性“_fontName”的错误开始,并且只是导致兔子洞。任何创建具有基于内容的动态高度的 pdf 的方法都很棒。

python django-rest-framework reportlab
© www.soinside.com 2019 - 2024. All rights reserved.