django - weasyprint images
django-pisa: agregar imágenes a la salida PDF (6)
Estoy usando un ejemplo estándar de la web ( http://www.20seven.org/journal/2008/11/pdf-generation-with-pisa-in-django.html ) para convertir una vista / plantilla django en una PDF.
¿Existe una forma "fácil" de incluir imágenes (ya sea desde una url o una referencia en el servidor) en la plantilla para que se muestren en el PDF?
No pude obtener imágenes para que aparezcan a pesar de probar todas las soluciones que pude encontrar en google. Pero este dulce de azúcar funcionó para mí, ya que la versión de línea de comando de pisa muestra imágenes bien:
from tempfile import mkstemp
# write html to a temporary file
# can used NamedTemporaryFile if using python 2.6+
fid, fname = mkstemp(dir=''/tmp'')
f = open(fname, ''w+b'')
f.write(html)
f.close()
# now create pdf from the html
cmd = ''xhtml2pdf "%s"'' % fname
os.system(cmd)
os.unlink(fname)
# get the content of the pdf
filename = fname+''.pdf''
pdf = open(filename, ''r'')
content = pdf.read()
pdf.close()
os.unlink(pdf.name)
# return content
response = HttpResponse(content, mimetype=''application/pdf'')
response[''Content-Disposition''] = ''attachment; filename=draft.pdf''
Esto funcionó donde las imágenes tenían una url o el nombre completo de la ruta, por ejemplo.
<img src="/home/django/project/site_media/css/output/images/logo.jpg" />
<img src="http://www.mysite.com/css/output/images/logo.jpg" />
Puede convertir la imagen a base64 también.
http://www.motobit.com/util/base64-decoder-encoder.asp
Al convertir a base64 nunca tendrá problemas con los enlaces de imagen.
Siempre puede agregar las imágenes luego con IText / ISharp.
Tengo las imágenes funcionando. El código es el siguiente:
from django.http import HttpResponse
from django.template.loader import render_to_string
from django.template import RequestContext
from django.conf import settings
import ho.pisa as pisa
import cStringIO as StringIO
import cgi
import os
def dm_monthly(request, year, month):
html = render_to_string(''reports/dmmonthly.html'', { ''pagesize'' : ''A4'', }, context_instance=RequestContext(request))
result = StringIO.StringIO()
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), dest=result, link_callback=fetch_resources )
if not pdf.err:
return HttpResponse(result.getvalue(), mimetype=''application/pdf'')
return HttpResponse(''Gremlins ate your pdf! %s'' % cgi.escape(html))
def fetch_resources(uri, rel):
path = os.path.join(settings.MEDIA_ROOT, uri.replace(settings.MEDIA_URL, ""))
return path
Esto fue tomado liberalmente de http://groups.google.com/group/xhtml2pdf/browse_thread/thread/4cf4e5e0f4c99f55
Todo el código anterior no funcionó para mí. Al final lo puse en funcionamiento poniendo el procedimiento get_full_path. Entonces el código final se ve así
def render_to_pdf( template_src, context_dict):
now = datetime.now()
filename = now.strftime(''%Y-%m-%d'') + ''.pdf''
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")),result, path=path)
if not pdf.err:
response = HttpResponse(result.getvalue(), mimetype=''application/pdf'')
response[''Content-Disposition''] = ''attachment; filename="''+filename+''"''
return response
return HttpResponse(''We had some errors<pre>%s</pre>'' % escape(html))
def get_full_path_x(request):
full_path = (''http'', ('''', ''s'')[request.is_secure()], ''://'',
request.META[''HTTP_HOST''], request.path)
return ''''.join(full_path)
def render_to_pdf( template_src, context_dict):
template = get_template(template_src)
context = Context(context_dict)
html = template.render(context)
result = StringIO.StringIO()
if page has an image.something:
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), dest=result, link_callback=fetch_resources)
else no image.something :
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")),result)
if not pdf.err:
return HttpResponse(result.getvalue(), mimetype=''examination_report/pdf'')
return HttpResponse(''We had some errors<pre>%s</pre>'' % escape(html))
def fetch_resources(uri, rel):
if os.sep == ''//': # deal with windows and wrong slashes
uri2 = os.sep.join(uri.split(''/''))
else:# else, just add the untouched path.
uri2 = uri
path = ''%s%s'' % (settings.SITE_ROOT, uri2)
return path