Правильный способ добавить файл изображения в документ PDF, созданный с помощью Reportlab на AppEngine Python - PullRequest
1 голос
/ 29 февраля 2012

Я пытаюсь сгенерировать отчет в формате PDF с использованием reportlab на App Engine Python.

Но я не знаю, как правильно прикрепить изображение.

Изображение статично.

Это дерево каталогов моего проекта.

enter image description here

и это то, что я делаю (внутри ' chipas.py '), чтобыполучить изображение:

im = Image('../static/logo.png',1*inch, 1*inch)
story.append(im)
...

Трассировка стека, которую я получаю:

Трассировка (последний последний вызов): Файл "C: \ Users \ Lucas \ Dropbox \ Desarrollo \ Python\ windows \ AppEngine \ google \ appengine \ ext \ webapp_webapp25.py ", строка 701, в call handler.get (* groups) Файл" C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python "\ chipas-windows \ src \ chipas.py ", строка 1035, в файле get doc.build (story) Файл" C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \ platypus \ "doctemplate.py ", строка 1117, в сборке BaseDocTemplate.build (self, flowables, canvasmaker = canvasmaker) Файл" C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \ platypus \doctemplate.py ", строка 880, в сборке self.handle_flowable (flowables) Файл" C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \ platypus \ doctemplate.py ", строка 763, в handle_flowable, если frame.add (f, canv, trySplit = self.allowSplitting): файл "C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \ platypus \ frames.py"строка 159, в файле _add w, h = flowable.wrap (aW, h) "C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \ platypus \ flowables.py",строка 408, в переносе возвращает self.drawWidth, файл self.drawHeight "C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \ platypus \ flowables.py", строка 402, в getattr self._setup_inner () Файл "C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \ platypus \ flowables.py", строка 368, в _setup_inner img =Файл self._img "C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \ platypus \ flowables.py ", строка 398, в getattr self._img = ImageReader (self._file) Файл" C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab\ lib \ utils.py ", строка 541, в init , если _isPILImage (fileName): Файл" C: \ Users \ Lucas \ Dropbox \ Desarrollo \ workspace \ python \ chipas-windows \ src \ reportlab \lib \ utils.py ", строка 521, в _isPILImage возвращает isinstance (im, Image.Image). AttributeError: у объекта 'NoneType' нет атрибута 'Image' INFO 2012-02-29 19: 54: 37,276 dev_appserver.py:4247]«GET / pdf? Pedido = ahVkZXZ-Y2hpcGFzLWludGhlY2xvdWRyLwsSBlBlZGlkbyIjMjAxMi0wMi0yOSAxOTo1NDoxOHRlc3RAZXhbXBsZ / h0 * * * * * * * * * * * * * * * * * * * * * * * * * * * не"Большое спасибо заранее!

Ответы [ 4 ]

6 голосов
/ 01 марта 2012

ReportLab требует PIL для изображений, отличных от JPEG (PIL недоступен в Appengine production), но он действительно поддерживает JPEG (см. Примечание ниже). Таким образом, вам нужно предоставить ReportLab с изображениями JPEG при рендеринге файлов PDF. Для изображений, отправленных пользователем, я сначала использую API Appengine для преобразования изображения в JPEG перед рендерингом.

Итак, шаг 1 - изменить логотип с png на jpeg.

Во-вторых, Appengine не позволяет вам читать файлы из статического каталога. При попытке выдает ошибку «Файл недоступен». Переключите .jpg в каталог, отличный от / static /.

Итак, какой бы метод вы ни использовали, чтобы определить относительный путь к файлу (для этого прекрасно подходит код gfortune), для рендеринга изображения просто используйте:

f = open (path_to_file, 'rb')

story.append (Изображение (f))

Примечание. Несколько лет назад в ReportLab была ошибка, из-за которой он все еще пытался получить доступ к PIL, даже для файлов JPEG. Я переписывался с разработчиками, которые предоставили сборку, которая обошла PIL для файлов JPEG. Я не уверен, какая сборка является текущей сборкой, так что имейте это в виду.

3 голосов
/ 29 февраля 2012

Есть 2 способа сделать это.

Если вы просто работаете с холстом:

canvas.drawInlineImage(APP_ROOT + "/static/footer_image.png", inch*.25, inch*.25, PAGE_WIDTH-(.5*inch), (.316*inch))

ИЛИ, если вы используете утконоса и жидкие вещества

(ответ взят из: http://www.tylerlesmann.com/2009/jan/28/writing-pdfs-python-adding-images/)

import os
import urllib2
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Image

filename = './python-logo.png'

def get_python_image():
    """ Get a python logo image for this example """
    if not os.path.exists(filename) :
        response = urllib2.urlopen('http://www.python.org/community/logos/python-logo.png')
        f = open(filename, 'w')
        f.write(response.read())
        f.close()

get_python_image()

doc = SimpleDocTemplate("image.pdf", pagesize=letter)
parts = []
parts.append(Image(filename))
doc.build(parts)
3 голосов
/ 29 февраля 2012

Основное решение

Похоже, оригинальная ошибка для этого поста связана с тем, что PIL, возможно, не установлен, или, возможно, ошибка в старой версии PIL.См. http://www.openerp.com/forum/topic18147.html для аналогичной ситуации.Попробуйте установить последнюю версию PIL.

Также см. Appengine - Reportlab (Получить фотографию с модели) в конце принятого решения и комментарии.

Другоепотенциальная проблема в размещенном коде

Хотя это не может быть напрямую связано с заданным вопросом, вы уверены, что im загружен правильно?Помните, что заданный вами путь относится к каталогу, из которого было запущено приложение, а не к текущему файлу.Используйте __file__ и некоторые хитрости os.path, чтобы сделать путь относительно chipas.py, предполагая, что это проблема.Если это не та проблема, с которой вы сейчас сталкиваетесь, то, безусловно, вы скоро столкнетесь с ней.

Чтобы указать путь относительно каталога текущего файла, вы должны использовать что-то вроде:

Код

import os.path

def path_relative_to_file(base_file_path, relative_path):
    base_dir = os.path.dirname(os.path.abspath(base_file_path))
    return os.path.normpath(os.path.join(base_dir, relative_path))



print(__file__)
print(path_relative_to_file(__file__, '../static/logo.png'))


#Breaks if this code is run from a different directory
print(os.path.abspath('../static/logo.png'))

Вывод

gfortune@gfortune:/var/log$ python /home/gfortune/temp/temp.py
/home/gfortune/temp/temp.py
/home/gfortune/static/logo.png
/var/static/logo.png

Обратите внимание, что путь к '../static' работает, даже если я запустил программу из / var / log.Также обратите внимание, что вслепую используйте ../static с перерывами abspath, если вы запускаете его из / var / log.

Вы можете использовать эту функцию в качестве маленькой вспомогательной функции, передав ее __file__ из рассматриваемого модуля, или вы можете просто использовать логику из нее непосредственно в chipas.py

0 голосов
/ 07 июня 2017

Попробуйте эту простую функцию: Это сработало для меня ....

def PrintImage(request):
    response = HttpResponse(content_type='application/pdf')
    doc = SimpleDocTemplate(response,topMargin=2)

    doc.pagesize = landscape(A6)
    elements = []
    I = Image('http://demoschoolzen.educationzen.com/images/tia.png')
    I.drawHeight =  0.7*inch
    I.drawWidth = 0.7*inch
    elements.append(I)
    doc.build(elements) 
    return response

и звоните по своим URL

...