vak
Апрель 19, 2010 07:33:50
А каким образом выводить web контент в виде pdf? Ну сформировал ответ (или отклик) с помощью reportlab, а дальше как? Подскажите как это делается или ссылочки дайте. Интересует как это делается именно в Pylons-е, может для этого какие готовые инструменты уже есть?
ziro
Апрель 19, 2010 09:05:17
Да в общем-то как везде - необходимо определить заголовки Content-Type и Content-Disposition, а результатом действия вернуть содержимое документа. Ниже пример из рабочего проекта (только там word, но суть примерно такая-же)
def print_price(self):
'Выводит прайс'
response.headers['Content-Type'] = 'application/msword'
response.headers['Content-Disposition'] = 'attachment; filename=price.doc'
c.good_type = catalog.Good
return render('/catalog/price.mako').encode('utf-8')
vak
Апрель 19, 2010 16:29:46
Получается, если отчёты постоянно (по запросам) генерить, то всё придётся сбрасывать во временные файлы pdf а затем “подчищать”. А есть ли способ не создавая файла в файловой системе отдавать содержание по запросу? (Правда сам не понимаю можно ли так сделать использую reportlab).
Ferroman
Апрель 19, 2010 17:02:05
Я бы не советовал так делать. Оперативки, как правило, меньше чем места на диске…
ziro
Апрель 20, 2010 09:40:40
Я reportlab не использовал, но думаю, что им должно поддерживаться сохранение данных не только в файловой системе, но и в file-like объекты типа StringIO/cStringIO. Если это так, то вполне можно не сохранять файл на диске, а использовать StringIO.
Однако, сохранение файла на диске может иметь определенные преимущества в случае, если Ваши данные не закрытые. В этом случае Вы, после генерации отчета, можете просто вернуть статус “302 - Moved temporarily” с указанием URL сгенерированного файла. В этом случае, обязанности доставки файла возмет на себя фронт-сервер (apache, nginx etc), что снизит общую нагрузку на веб-сервер.
vak
Март 22, 2011 06:31:32
ziro
Да в общем-то как везде - необходимо определить заголовки Content-Type и Content-Disposition, а результатом действия вернуть содержимое документа. Ниже пример из рабочего проекта (только там word, но суть примерно такая-же)
def print_price(self):
'Выводит прайс'
response.headers['Content-Type'] = 'application/msword'
response.headers['Content-Disposition'] = 'attachment; filename=price.doc'
c.good_type = catalog.Good
return render('/catalog/price.mako').encode('utf-8')
А можно ли минуя шаблон “выплюнуть” pdf файл?
Андрей Светлов
Март 22, 2011 07:00:59
А вы вспомните, что делает render(…)
ziro
Март 22, 2011 08:16:28
vak
А можно ли минуя шаблон “выплюнуть” pdf файл?
Конечно - просто верните содержимое файла, типа такого
with open('somefile.pdf', 'rb') as f:
data = f.read()
return data
В том куске кода, который я привел, на самом деле возвращался не настоящий MS Word документ, а веб-архив, полученный из шаблонизатора - достаточно грязный хак, но работает - поэтому render и использовался.
vak
Март 22, 2011 08:31:39
response.headers['Content-Type'] = 'applicetion/pdf'
response.headers['Content-Disposition'] = 'attachment; filename=form1.pdf'
return ''
Вот так вроде получается, но не очень…
Получаю какой то “битый” файл. В чем дело не могу понять.
vak
Март 22, 2011 08:57:13
response.headers['Content-Type'] = 'applicetion/pdf'
response.headers['Content-Disposition'] = 'attachment; filename=form1.pdf'
f = open('prnforms/public/prn/form1.pdf','rb')
data = f.read()
return data
Вот так работает.