I had a problem before where it wouldn't show Chinese characters even when I specified #font-face to use a UTF-8 font. It turns out I cannot display images as well... so I seems like I am unable to get any of the files embeded into my pdf.
This is the code I use:
def render_to_pdf(template_src, context_dict):
"""Function to render html template into a pdf file"""
template = get_template(template_src)
context = Context(context_dict)
html = template.render(context)
result = StringIO.StringIO()
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")),
dest=result,
encoding='UTF-8',
link_callback=fetch_resources)
if not pdf.err:
response = http.HttpResponse(result.getvalue(), mimetype='application/pdf')
return response
return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))
def fetch_resources(uri, rel):
import os.path
from django.conf import settings
path = os.path.join(
settings.STATIC_ROOT,
uri.replace(settings.STATIC_URL, ""))
return path
html
<img src="/static/images/bc_logo_bw_pdf.png" />
and
#font-face {
font-family: "Wingdings";
src: url("/static/fonts/wingdings.ttf");
}
I looked at the other quests on SO but it was no help. There are also no exceptions happening in the two functions. Also in fetch_resources function the path returned was the correct full path to the file i.e. /home/<user>/project/static/images/bc_logo_bw_pdf.png and /home/<user>/project/static/fonts/wingdings.ttf and I am at a loss as to what is wrong.
UPDATE
Everytime I create a pdf, I get this message on the console
No handlers could be found for logger "ho.pisa"
could this be related?
UPDATE #2
The font works now I made a dumb mistake... The font I was using did not have the Chinese unicode. But I still cannot embed any images onto the pdf, be it jpeg, gif or png.
I have finally solved the problem I was having... it turns out it doesn't work if I set the body's height with css... once I removed that line the image was loading perfectly...
For me (django 1.4, python 2.7 pisa==3.0.33), If I put the full path of image instead of relative, it works for me.
Try doing the same.
Everything looks better . Try once with JPG image file. In my case PNG file was also not working.
<img src="/static/images/<name>.jpg" />
without width and height attribute image will not work. add width and height attribute.
<img src="{% static 'images/logo.png' %}" alt="image" width="200" height="150" />
this fix works for me.
I have the same problem here. Don't give up with XHTML2PDF Pisa.
Pisa use PIL for generate PDF and use lib zip decoder to inserting images.
You should check if your PIL already installed properly with zip decoder, fonts and several components
I have solve this problem by installing PIL with zip decoder.
http://obroll.com/install-python-pil-python-image-library-on-ubuntu-11-10-oneiric/
If you need more detail information, you can read my article here :
http://obroll.com/how-to-load-images-files-style-css-in-pdf-using-pisa-xhtml2pdf-on-django/
Related
I am trying to make Qr Codes using Python on a Django applicaiton using this code :
def generate_qr_code (reference):
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=10,
border=4,
)
qr.add_data(reference)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white").convert('RGB')
filename = reference+".jpeg"
img.save("C:\\qrs\\"+filename)
Now, this function is called when I click on a "Generate Qr Code" Button. My problem is that I would like the Qr Code to be displayed on a new tab on my browser instead of it being saved as an image, as I only need to print them on paper at that moment and I have no need to keep the images.
Thank you for your help.
convert the image to base64 and show it in your html like this
import base64
b64 = base64.b64encode(image).decode("utf-8")
update:
ofc you don't need to save your image as png to use this feature, you can change the format in html and you can also change the image format without saving it to a file like this
After all, I managed to do so by using this simple line in my HTML:
<img id='barcode' src="https://api.qrserver.com/v1/create-qr-code/?data={{ref}}" alt="" title="{{ref}}" width="150" height="150"/>
You can use SVG format
import qrcode
import qrcode.image.svg
from io import BytesIO
def generate_qr_code (reference):
factory = qrcode.image.svg.SvgImage
qr_string = "sample text"
img = qrcode.make(qr_string, image_factory=factory, box_size=10)
stream = BytesIO()
img.save(stream)
context = {
'qrcode': stream.getvalue().decode()
}
return render(request, 'YOUR HTML.html', context)
and then you can use it in html file:
{{qrcode|safe}}
I have created a plot in a view and saved the plot as a png inside the templates folder. But when I try to display this saved image using an <img> tag in a template html file, the image is not displayed.
Here is an image of my folder structure:
Folder Structure
This is how I save my plot inside a view:
def result(request):
if request.POST and request.FILES:
mycsv=pd.read_csv(request.FILES['csv_file'])
c=mycsv.X
#We divide by the class height(basically) so that Xi+1-Xi=1
x = [d / 5 for d in c]
n=len(x)
b=mycsv.Y
divi=np.sum(b)
f = [e / divi for e in b]
#Thus sum(f)=1, makes calculation of mean simpler
#PLOTTING BEGINS
fig = plt.figure()
ax = plt.subplot(111)
ax.plot(x, f)
plt.title('Pearson Type 1 ')
ax.legend()
#plt.show()
fig.savefig('polls/templates/polls/plot.png')
context = {'n':n,}
return render(request, 'polls/result.html', context)
else:
return HttpResponse("Form Not Submitted")
My result.html file where I try to get the image is:
<h1>Graph with {{n}} points</h1>
<img src='./plot.png' />
I'm running this on my localhost, is there a problem with permissions?
I've just started learning django and wanted to test this thing. Thank you for your help!
There are many things wrong about your approach but I'll try to give you some advice on how to proceed, although you may want to reconsider it.
First of all, saving your file to the templates directory won't make it available to your template. The templates directory is a special configuration that allows you to use Django's template loader, it doesn't load static files like your image.
You could save your image to static files and use the {% static %} template tag to recover it, but, again, it would be the wrong approach, as your image is not static content, it's created dynamically.
As you have no use for the data in the image after it's created, my recommendation would be to store the image in a temporary file using TempFile, or (if it's light enough) in memory using StringIO and then load those bytes in the context as base64
from StringIO import StringIO
import base64
img_in_memory = StringIO()
fig.savefig(img_in_memory, format="png") #dunno if your library can do that.
context['image'] = base64.b64encode(img_in_memory.getvalue())
Then, in your template you'd do something like:
<img src="data:image/png;base64,{{image}}" />
Or simply convert the image to string by
with open(original_image_path, "rb") as img_file:
base64_img = base64.b64encode(img_file.read()).decode('utf-8')
mimetype = mimetypes.guess_type(original_image_path)[0]
once done render this variable on HTML as
<img src="data:{{ mimetype }};base64,{{ base64_img }}"/>
It will handle both jpeg and png both.
I am trying to read a pdf file in html without downloading the pdf. The down code is working fine for images . In place of images i want to read a pdf. is that possible.
db.define_table('mytable',
Field('image', type='upload'))
controller
def tables():
return dict(tables=db().select(db.mytable.ALL))
View
{{for table in tables:}}
<img src="{{=URL('default', 'download', args=table.image)}}" /> <br />
{{pass}}
You could create an png from the PDF. PDF is not something a browser can render in HTML (sure Chrome and Firefox can open a PDF; but that's fullscreen, just the pdf itself; e.g. another URL). Could be out of scope: In some projects I use a crontab that converts uploaded PDF's to jpg to provide a preview:
#Render all PDF's to thumb when no thumb is found
#convert -thumbnail x600 -background white "1.pdf"[0] "1.jpg"
import os,sys
OVERWRITE_EXISTING=False
PDFDIR='uploads'
THUMBDIR=os.path.join('static','thumbs')
import glob
import os
def insensitive_glob(pattern):
def either(c):
return '[%s%s]'%(c.lower(),c.upper()) if c.isalpha() else c
return glob.glob(''.join(map(either,pattern)))
#get all the pdf file names in the current folder
os.chdir('uploads')
files = insensitive_glob("*.pdf")
# and convert each file if needed
for f in files:
convert_needed=True
newFile=os.path.join('..',THUMBDIR,'%s.jpg' % f[:-4])
if not OVERWRITE_EXISTING:
if os.path.exists(newFile):
#print 'Warning:: .jpg already exists; skipping %s' % f
convert_needed=False
if convert_needed:
cmd='convert -density 144 %s[0] %s' % (f,newFile)
print "Converting with: %s" % cmd
os.system(cmd)
I want to generate pdf file from html using Python + Flask. To do this, I use xhtml2pdf. Here is my code:
def main():
pdf = StringIO()
pdf = create_pdf(render_template('cvTemplate.html', user=user))
pdf_out = pdf.getvalue()
response = make_response(pdf_out)
return response
def create_pdf(pdf_data):
pdf = StringIO()
pisa.CreatePDF(StringIO(pdf_data.encode('utf-8')), pdf)
return pdf
In this code file is generating on the fly. BUT! xhtml2pdf doesn't support many styles in CSS, because of this big problem to mark page correctly. I found another instrument(wkhtmltopdf). But when I wrote something like:
pdf = StringIO()
data = render_template('cvTemplate1.html', user=user)
WKhtmlToPdf(data.encode('utf-8'), pdf)
return pdf
Was raised error:
AttributeError: 'cStringIO.StringO' object has no attribute 'rfind'
And my question is how to convert html to pdf using wkhtmltopdf (with generating file on the fly) in Flask?
Thanks in advance for your answers.
The page need render, You can use pdfkit:
https://pypi.python.org/pypi/pdfkit
https://github.com/JazzCore/python-pdfkit
Example in document.
import pdfkit
pdfkit.from_url('http://google.com', 'out.pdf')
pdfkit.from_file('test.html', 'out.pdf')
pdfkit.from_string('Hello!', 'out.pdf') # Is your requirement?
Have you tried with Flask-WeasyPrint, which uses WeasyPrint? There are good examples in their web sites so I don't replicate them here.
Not sure if this would assist anyone but my issue was capturing Bootstrap5 elements as a pdf. pdfkit did not do so and heres a work around on windows using html2image and PIL. This is limited and does not take a full page screenshot.
from html2image import Html2Image
from PIL import Image
try:
hti.screenshot(html_file=C:\yourfilepath\file.html, save_as="test.png")
finally:
image1 = Image.open(r'C:\yourfilepath\test.png')
im1 = image1.convert('RGB')
im1.save(r'C:\yourfilepath\newpdf.pdf')
I have a image in the server folder. In my do_GET() function which handles the Get request I would like to send a image back. I choose to use the self.wfile.write(''). Can anyone tell me how to include the source of the image in to the img tag? Or is there a better way to do this? Thanks.
You can include the "source" of an image in the img tag using a data URI like this:
<img alt="Embedded Image" src="data:image/png;base64,<your base64 encoding here>" />
Generate the base64 string using the base64 python standard lib:
import base64
with open("image.png", "rb") as image:
encoded_string = base64.b64encode(image.read())