How to open a generated PDF file in browser?

2020-06-17 14:25发布

I have written a Pdf merger which merges an original file with a watermark.

What I want to do now is to open 'document-output.pdf' file in the browser by a Django view. I already checked Django's related articles, but since my approach is relatively different, I don't directly create the PDF object, using the response object as its "file.", so I am kind of lost.

So, how can I do is in a Django view?

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条回答
We Are One
2楼-- · 2020-06-17 14:41

I am not sure I follow. If you want the PDF content to be sent to the browser you should use an HttpResponse instance. This line in your code

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

will not serve to write the PDF contents to the response. Instead it looks to me like it will write the contents to a local file, which is not the same.

Update

Based on comment:

How to send PDF content to a HttpResponse object as it will open in the browser, not as an attachment.

AFAIK (if anyone knows better, correct me) this is browser dependent.

If you leave out the Content-Disposition = "attachment; filename=foo.pdf from the response headers you can send the contents to the browser without a specific filename. This prompted my Firefox browser (3.6.10, Ubuntu Jaunty) to ask me if I wanted to open it using a program. On Chrome (6.0.472.62, Ubuntu Jaunty) the file got downloaded as download.pdf without any prompting.

查看更多
狗以群分
3楼-- · 2020-06-17 14:59

remove 'attachment' from this line with Chris comment

response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
查看更多
Animai°情兽
4楼-- · 2020-06-17 15:00

In addition to sending your PDF back to the browser, you can also save some cycles by storing your watermark in a string buffer.

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
查看更多
相关推荐>>
5楼-- · 2020-06-17 15:03

I know its an older post but we can use the embed tag of html to implement this kind of functionality. For e.g.:

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

So in your case, you can simply send the response using render to response as:

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

and in the abc.html you can put this filename (with the path) in the embed tag, as mentioned above.

Hope this helps.

查看更多
登录 后发表回答