Search code examples
pythonhtml2pdfpisa

Generating PDF using xhtml2pdf in landscape mode


How do I go about creating a 3 col landscape layout using xhtml2pdf?

I tried something like this but it didn't work. Should I even be using frames in the first place?

@page {
    size: a4 landscape;

    @frame left {
        -pdf-frame-content: left;
        -pdf-frame-border: 1;
        width: 9.9cm;
        text-align: left;
    }
    @frame middle {
        -pdf-frame-content: middle;
        -pdf-frame-border: 1;
        width: 9.9cm;
        text-align: left;
    }
    @frame right {
        -pdf-frame-content: left;
        -pdf-frame-border: 1;
        width: 9.9cm;
        text-align: left;
    }
}

Solution

  • I don't think it can be done with xhtml2pdf even though its based on reportlab which allows you to do it.

    After messing with it for a while, the following snippet produces the following image: https://i.sstatic.net/poJox.jpg

    def badge(request):
        # Create the HttpResponse object with the appropriate PDF headers.
        response = HttpResponse(mimetype='application/pdf')
        response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
    
        # Create the PDF object, using the StringIO object as its "file."
        pagesize = pagesizes.landscape(letter)
        pagewidth, pageheight = pagesize
        doc = platypus.BaseDocTemplate(filename=response, pagesize=pagesize,
                showBoundary=1)
        newHeight = doc.bottomMargin + doc.topMargin + doc.height
        newWidth = doc.leftMargin + doc.rightMargin + doc.width
    
        # reset margins
        doc.leftMargin = 0
        doc.bottomMargin = 0
        doc.rightMargin = 0
        doc.topMargin = 0
    
        # create the frames
        frames = []
        left_frame_1 = Frame(doc.leftMargin,
                doc.bottomMargin,
                newWidth / 3,
                newHeight / 6,
                showBoundary=1,
                id="left_frame_1")
        left_frame_2 = Frame(doc.leftMargin,
                doc.bottomMargin + newHeight / 6,
                newWidth / 3,
                newHeight / 6,
                showBoundary=1,
                id="left_frame_2")
        left_frame_3 = Frame(doc.leftMargin,
                doc.bottomMargin + newHeight / 6 * 2,
                newWidth / 3,
                newHeight / 6,
                showBoundary=1,
                id="left_frame_3")
        left_frame_4 = Frame(doc.leftMargin,
                doc.bottomMargin + newHeight / 6 * 3,
                newWidth / 3,
                newHeight / 6,
                showBoundary=1,
                id="left_frame_4")
        left_frame_5 = Frame(doc.leftMargin,
                doc.bottomMargin + newHeight / 6 * 4,
                newWidth / 3,
                newHeight / 6,
                showBoundary=1,
                id="left_frame_5")
        left_frame_6 = Frame(doc.leftMargin,
                doc.bottomMargin + newHeight / 6 * 5,
                newWidth / 3,
                newHeight / 6,
                showBoundary=1,
                id="left_frame_6")
        mid_frame_1 = Frame(doc.leftMargin + newWidth / 3,
                doc.bottomMargin,
                newWidth / 3,
                newHeight / 6 * 4,
                showBoundary=1,
                id="mid_frame_1")
        mid_frame_2 = Frame(doc.leftMargin + newWidth / 3,
                doc.bottomMargin + newHeight / 6 * 4,
                newWidth / 3,
                newHeight / 6 * 2,
                showBoundary=1,
                id="mid_frame_2")
        right_frame_1 = Frame(doc.leftMargin + newWidth / 3 * 2,
                doc.bottomMargin,
                newWidth / 3,
                newHeight / 6 * 2,
                showBoundary=1,
                id="right_frame_1")
        right_frame_2 = Frame(doc.leftMargin + newWidth / 3 * 2,
                doc.bottomMargin + newHeight / 6 * 2,
                newWidth / 3,
                newHeight / 6 * 3,
                showBoundary=1,
                id="right_frame_2")
        right_frame_3 = Frame(doc.leftMargin + newWidth / 3 * 2,
                doc.bottomMargin + newHeight / 6 * 5,
                newWidth / 3,
                newHeight,
                showBoundary=1,
                id="right_frame_3")
    
        frames.append(left_frame_1)
        frames.append(left_frame_2)
        frames.append(left_frame_3)
        frames.append(left_frame_4)
        frames.append(left_frame_5)
        frames.append(left_frame_6)
        frames.append(mid_frame_1)
        frames.append(mid_frame_2)
        frames.append(right_frame_1)
        frames.append(right_frame_2)
        frames.append(right_frame_3)
    
        Elements = []
    
        styles = getSampleStyleSheet()
    
        # LEFT COL CONTENT
        Elements.append(Paragraph("LEFT1, " * 10,
            styles['Normal']))
        Elements.append(FrameBreak())
        Elements.append(Paragraph("LEFT2, " * 10,
            styles['Normal']))
        Elements.append(FrameBreak())
        Elements.append(Paragraph("LEFT3, " * 10,
            styles['Normal']))
        Elements.append(FrameBreak())
        Elements.append(Paragraph("LEFT4, " * 10,
            styles['Normal']))
        Elements.append(FrameBreak())
        Elements.append(Paragraph("LEFT5, " * 10,
            styles['Normal']))
        Elements.append(FrameBreak())
        Elements.append(Paragraph("LEFT6, " * 10,
            styles['Normal']))
        Elements.append(FrameBreak())
    
        # MID COL CONTENT
        Elements.append(Paragraph("MID_2, " * 20,
            styles['Normal']))
        Elements.append(FrameBreak())
        Elements.append(Paragraph('''
        <para><b>NOTE</b><br />
        (1) Please check the registration handy kit to ensure you have received
        the item(s) as marked on the cover. <br />
        (2) The official receipt(s) for the payments you have made are enclosed.
        Please check to ensure that it was issued correctly. <br />
        (3) You will be requested to present the appropriate coupon(s)/ ticket (s)
        for admission to lunch, banquet or other events. <br />
        (4) The organizer nor its appointed Professional Conference Organiser shall
        not be responsible for any loss or damage to this kit <br />
        </para>
        ''', styles['Normal']))
        Elements.append(FrameBreak())
    
        # RIGHT COL CONTENT
        Elements.append(Paragraph("RIGHT_1 " * 30,
            styles['Normal']))
        Elements.append(FrameBreak())
        Elements.append(Paragraph('''
        <para><b><font size="16">REGISTRATION Handy Kit</font></b> <br />
        This kit contains the checked items: <br />
        [] Namebadge <br />
        [] Official Receipt(s) <br />
        [] Lunch Coupon(s) <br />
        [] Banquet Ticket & Reply Slip <br />
        [] Others: <br />
        _________________________________
        _________________________________
        _________________________________
        _________________________________
        <br />
        <br />
        <br /> 
        <i>If any of the checked items are missing in your kit, please inform the
        registration counter staff</i>
        </para>
        ''', styles['Normal']))
        Elements.append(FrameBreak())
        Elements.append(Paragraph("RIGHT_3, " * 10,
            styles['Normal']))
    
        doc.addPageTemplates(platypus.PageTemplate(id="TwoCol", frames=frames))
        doc.build(Elements)
    
        return response