Как открыть сгенерированный файл PDF в браузере? - PullRequest
6 голосов
/ 22 сентября 2010

Я написал слияние в формате PDF, которое объединяет оригинальный файл с водяным знаком.

Теперь я хочу открыть файл document-output.pdf в браузере в представлении Django. Я уже проверил соответствующие статьи Django, но, поскольку мой подход относительно другой, я не создаю объект PDF напрямую, используя объект ответа в качестве его «файла». Поэтому я немного потерян.

Итак, как я могу это сделать в представлении Django?

from pyPdf import PdfFileWriter, PdfFileReader
from reportlab.pdfgen.canvas import Canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

output = PdfFileWriter()
input = PdfFileReader(file('file.pdf', 'rb'))

# get number of pages
num_pages = input.getNumPages()

# register new chinese font
pdfmetrics.registerFont(TTFont('chinese_font','/usr/share/fonts/truetype/mac/LiHeiPro.ttf'))

# generate watermark on the fly
pdf = Canvas("watermark.pdf")
pdf.setFont("chinese_font", 12)
pdf.setStrokeColorRGB(0.5, 1, 0)
pdf.drawString(10, 830, "你好")
pdf.save()

# put on watermark
watermark = PdfFileReader(file('watermark.pdf', 'rb'))
page1 = input.getPage(0)

page1.mergePage(watermark.getPage(0))

# add processed pdf page
output.addPage(page1)

# then, add rest of pages
for num in range(1, num_pages):
    output.addPage(input.getPage(num))

outputStream = file("document-output.pdf", "wb")
output.write(outputStream)
outputStream.close()

Ответы [ 4 ]

9 голосов
/ 28 сентября 2010

Я знаю, что это старый пост, но мы можем использовать тег встраивания html для реализации такого рода функций. Например ::

<embed height="100%" width="100%"  name="plugin" src="filename.pdf"  type="application/pdf">

Так что в вашем случае вы можете просто отправить ответ с помощью render to response как:

return render_to_response("abc.html",{"filename":filename})

и в файле abc.html вы можете поместить это имя файла (вместе с путем) в тег embed, как упомянуто выше.

Надеюсь, это поможет.

6 голосов
/ 30 марта 2011

Помимо отправки вашего PDF обратно в браузер, вы также можете сохранить некоторые циклы, сохраняя свой водяной знак в строковом буфере.

from pyPdf import PdfFileWriter, PdfFileReader
from reportlab.pdfgen.canvas import Canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from django.http import HttpResponse
try:
   from cStringIO import StringIO
except ImportError:
   from StringIO import StringIO

def some_view(request):
   output = PdfFileWriter()
   input = PdfFileReader(file('file.pdf', 'rb'))

   #create response object
   response = HttpResponse(mimetype='application/pdf')
   response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'

   # get number of pages
   num_pages = input.getNumPages()

   #register the font
   pdfmetrics.registerFont(TTFont('chinese_font','/usr/share/fonts/truetype/mac/LiHeiPro.ttf'))

   # generate watermark on the fly
   buffer = StringIO() # create string buffer for PDF
   pdf = Canvas(buffer)
   pdf.setFont("chinese_font", 12)
   pdf.setStrokeColorRGB(0.5, 1, 0)
   pdf.drawString(96, 26, "88888")
   pdf.save()

   # put on watermark from buffer
   watermark = PdfFileReader(buffer)
   page1 = input.getPage(0)

   page1.mergePage(watermark.getPage(0))

   # add processed pdf page
   output.addPage(page1)


   #stream to browser
   outputStream = response
   output.write(response)
   outputStream.close()

return response
3 голосов
/ 22 сентября 2010

Я не уверен, что следую. Если вы хотите, чтобы содержимое PDF отправлялось в браузер, вы должны использовать экземпляр HttpResponse. Эта строка в вашем коде

outputStream = file("document-output.pdf", "wb")

не будет использоваться для записи содержимого PDF в ответ. Вместо этого мне кажется, что он запишет содержимое в локальный файл, который не совпадает.

Обновление

На основании комментария:

Как отправить содержимое PDF в объект HttpResponse, как он открывается в браузере, а не как вложение.

AFAIK (если кто-то знает лучше, поправьте меня), это зависит от браузера.

Если вы пропустите Content-Disposition = "attachment; filename=foo.pdf из заголовков ответов, вы можете отправить содержимое в браузер без указания конкретного имени файла. Это побудило мой браузер Firefox (3.6.10, Ubuntu Jaunty) спросить меня, хочу ли я открыть его с помощью программы. В Chrome (6.0.472.62, Ubuntu Jaunty) файл загружался как download.pdf без каких-либо подсказок.

1 голос
/ 09 июня 2016

удалить «вложение» из этой строки с комментарием Криса

response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
...