I have a very strange problem and tried everything for about 5 hours to solve this odd issue but no luck.
I was able to generate a PDF file with images successfully using xhtml2pdf
on my machine which is running windows 10, but when I deployed to Ubuntu my image just got broken for no reason!
I think the problem is that, on Ubuntu, it doesn't build the path to this image correctly, but, ironically, it does on windows perfectly!
here is the section which is working just fine on windows but not on Ubuntu:
<table>
<tr>
<td> <img src="test_logo.png" alt="logo"></td>
</tr>
</table>
And test_logo.png
is located at the root of my project just like this:
my_project/
app1/
app2/
requirements.txt
test_logo.png
And my link_callback()
def link_callback(uri, rel):
"""
Convert HTML URIs to absolute system paths so xhtml2pdf can access those
resources
"""
sUrl = settings.STATIC_URL # Typically /static/
sRoot = settings.STATIC_ROOT # Typically /home/userX/project_static/
mUrl = settings.MEDIA_URL # Typically /media/
mRoot = settings.MEDIA_ROOT # Typically /home/userX/project_static/media/
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
# 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'm using Django 2.2.18
and the latest xhtml2pdf
version with python 3.8
This is just strange, it should work on all platforms or not at all.
Thanks
I finally found the issue!
After taking a look at how xhtml2pdf
gets the file here, it turns out that for files with no path it gets the current working directory and use it, this worked for me at windows because my environment was at the project's root so the file was there, but broke at ubuntu because my environment was at a totally different location than where the project is located.
After knowing this, the fix was simple, just return the BASE_DIR
path, here is my lick_callback()
after the fix
def link_callback(uri, rel):
"""
Convert HTML URIs to absolute system paths so xhtml2pdf can access those
resources
"""
sUrl = settings.STATIC_URL # Typically /static/
sRoot = settings.STATIC_ROOT # Typically /home/userX/project_static/
mUrl = settings.MEDIA_URL # Typically /media/
mRoot = settings.MEDIA_ROOT # Typically /home/userX/project_static/media/
bRoot = settings.BASE_DIR # Project's base directory
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 os.path.join(bRoot, '../', uri)
# 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