4

Conversion:

html = template.render(context)
resultFile = open(filepath, "w+b")
pdf = pisa.CreatePDF(html.encode('utf-8'), dest=resultFile,encoding='utf-8', link_callback=link_callback)

link_callback

def link_callback(uri, rel):
    sUrl = settings.STATIC_URL      # Typically /static/
    sRoot = settings.STATIC_ROOT    
    mUrl = settings.MEDIA_URL       # Typically /static/media/
    mRoot = settings.MEDIA_ROOT     # Typically /home/userX/project_static/media/

    # convert URIs to absolute system paths
    if uri.startswith(mUrl):
        path = os.path.join(mRoot, uri.replace(mUrl, ""))
    elif uri.startswith(sUrl):
        path = os.path.join(sRoot, uri.replace(sUrl, ""))
    else:
        return uri  # handle absolute uri (ie: http://some.tld/foo.png)

    # make sure that file exists
    if not os.path.isfile(path):
        raise Exception(
            'media URI must start with %s or %s' % (sUrl, mUrl)
        )
    return path

I have created pdf using xhtml2pdf. The file is created but css is not at all applied to it. I have checked the path which is returned from link_callback, its correct but in pdf there is no css applied at all.

css:

#page_1 {position:relative; overflow: hidden;margin: 64px 0px 65px 0px;padding: 0px;border: none;}

#page_1 #p1dimg1 {position:absolute;top:0px;left:20%;z-index:-1;width:600px;height:870px;}
#page_1 #p1dimg1 #p1img1 {width:600px;height:870px;}

#page_2 {position:relative; overflow: hidden;padding-left: 100px;border: none;height: 854px;}

#page_2 #p2dimg1 {position:absolute;left:27%;z-index:-1;width:490px;height:669px;}
#page_2 #p2dimg1 #p2img1 {width:490px;height:669px;}

css path which i got: /Users/mypc/project/project/static/css/lender_borrower.css

3 Answers 3

8

xhtml2pdf doesn't allow linking to external stylesheets.

You will need to provide an internal style sheet - which means writing your styles in the head of the HTML template, between tags

<style type="text/css">HERE</style>

However, note that many CSS styles are not supported. See the docs for what CSS is supported.

Sample template below:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Whatever</title>
  <style type="text/css">

  # PLACE ALL YOUR CSS STYLING HERE

  </style>
</head>
<body>

# content goes here

</body>
</html>
Sign up to request clarification or add additional context in comments.

Comments

0

Images, backgrounds and stylesheets are loaded form an HTML document. Normally xhtml2pdf expects these files to be found on the local drive. They may also be referenced relative to the original document. But the programmer might want to load form different kind of sources like the Internet via HTTP requests or from a database or anything else. Therefore you may define a link_callback that handles these requests.

According to the docs, there is definately a way to add external style sheets via the link_callback function, althrough I have no understanding of how to do so. Could someone help with this? Specifically, loading static files in django.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

As of 2024, you can link to an external stylesheet like this:

Input file:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Assurance Report</title>
    <link rel="stylesheet" type="text/css" href="Styles\assuranceReport.css" />
</head>
<body>
...

Python (on Windows)

from xhtml2pdf import pisa

with open('Docs\\assuranceReport.html', 'r') as input_file:
    source_html = input_file.read()
    result_file = open("My.pdf", "w+b")

    pisa_status = pisa.CreatePDF(
                source_html,
                #default_css - no need for anything here
                dest=result_file)

        result_file.close()
        # return False on success and True on errors
        return pisa_status.err

One thing to watch is that your CSS file must be saved as UTF-8 rather than UTF-8-BOM, as otherwise xhtml2pdf will struggle to parse it:

Bad BOM

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.