I'm having trouble incorporating pyPDF logic to merge two pdf files into my django site. I have written code that works to merge files when run in a python file on the local server(but I need to explicitly identify which files to merge:
from pyPdf import PdfFileReader, PdfFileWriter
output = PdfFileWriter()
input1 = PdfFileReader(file("abc_form0.pdf", "rb"))
input2 = PdfFileReader(file("abc_form1.pdf", "rb"))
total_pages = input1.getNumPages()
total_pages1 = input2.getNumPages()
for page in xrange(total_pages):
output.addPage(input1.getPage(page))
for page in xrange(total_pages1):
output.addPage(input2.getPage(page))
outputStream = file("output.pdf", "wb")
output.write(outputStream)
outputStream.close()
This code (from my django site) works to display a single PDF. However, when more than one PDF is selected, only the final PDF selected displays, hence the need to integrate pyPDF to create one file containing all requested files.
class ABCAdmin(admin.ModelAdmin):
actions = ['print_selected_pdf']
def create_pdf(self, request, queryset):
response = HttpResponse(mimetype="application/pdf")
response['Content-Disposition'] = 'attachment; filename=form.pdf'
for obj in queryset:
response.write(obj.form)
ABC.objects.filter(pk=obj.pk).update(user=request.user,pdf_printed="1",request_time=time.strftime("%H:%M:%S"),request_date=datetime.datetime.today())
return response
def print_selected_pdf(self, request, queryset):
# prints the pdfs for those that are selected,
# regardless if the pdf_printed field is true or false
qs = queryset.filter(pdf_printed__exact=0)
return self.create_pdf(request, qs)
I'm struggling with finding a way to combine these two methods. What I have tried is the following, but get an IO error [Errno 2] No such file or directory: 'obj.form'. So it is not reading in obj.form - I need to find a way for it to read in these objects correctly. Anyway, this is what I've tried.
def create_pdf(self, request, queryset):
response = HttpResponse(mimetype="application/pdf")
response['Content-Disposition'] = 'attachment; filename=form.pdf'
for obj in queryset:
output = PdfFileWriter()
input = PdfFileReader(file("obj.form","rb"))
total_pages = input.getNumPages()
for page in xrange(total_pages):
output.addPage(input.GetPage(page))
outputStream = file("output.pdf", "wb")
response.write(outputStream)
outputStream.close()
ABC.objects.filter(pk=obj.pk).update(user=request.user,pdf_printed="1",request_time=time.strftime("%H:%M:%S"),request_date=datetime.datetime.today())
return response
def print_selected_pdf(self, request, queryset):
# prints the pdfs for those that are selected,
# regardless if the pdf_printed field is true or false
qs = queryset.filter(pdf_printed__exact=0)
return self.create_pdf(request, qs)
As always, thanks for any help or tips you may be able to provide!
I used stringIO in the output stream to get around this. I also had to define each page of the PDF form to be added to the output. This works to iterate for any number of forms that I need to be requested.
def create_form(self, request, queryset):
response = HttpResponse(mimetype="application/pdf")
response['Content-Disposition'] = 'attachment; filename=form.pdf'
output = PdfFileWriter()
for obj in queryset:
input = PdfFileReader(cStringIO.StringIO(obj.form))
output.addPage(input.getPage(0))
output.addPage(input.getPage(1))
output.addPage(input.getPage(2))
output.addPage(input.getPage(3))
ABC_Self.objects.filter(pk=obj.pk).update(user=request.user,pdf_printed="1",request_time=time.strftime("%H:%M:%S"),request_date=datetime.datetime.today())
outputStream = cStringIO.StringIO()
output.write(outputStream)
response.write(outputStream.getvalue())
return response
All you need to do is provide the full absolute path to your PDF files, e.g.
/home/joseph/form.pdf
or
c:/home/joseph/form.pdf
etc.
来源:https://stackoverflow.com/questions/7123977/pypdf-merging-and-displaying-as-httpresponse-through-django