0

在加载整个文件之前,该文件不会显示。如何在浏览器中显示进度?

from io import BytesIO
from reportlab.pdfgen import canvas
from django.http import HttpResponse

def some_view(request):
     # Create the HttpResponse object with the appropriate PDF headers.
     response = HttpResponse(mimetype='application/pdf')
     response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'

     buffer = BytesIO()

     # Create the PDF object, using the BytesIO object as its "file."
     p = canvas.Canvas(buffer)

     p.drawString(**, **, "Hello world.") # draw pdf, size > 10M

     # Close the PDF object cleanly.
     p.showPage()
     p.save()

     # Get the value of the BytesIO buffer and write it to the response.
     pdf = buffer.getvalue()
     buffer.close()
     response.write(pdf)
     return response
4

1 回答 1

2

好吧,在您的示例中,我认为这将非常简单(并且几乎是瞬时的)。您只需打印/返回 、 等的进度指示器drawStringshowPage假设您生成的实际 PDF 涉及更多,您可以使用该类的setProgressCallBack方法BaseDocTemplate。当然,这需要您使用 reportlab platypus 引擎。

有一些注意的方法/属性(请参阅注释),假设您有一个自定义模板类,它覆盖BaseDocTemplate

from reportlab.platypus import BaseDocTemplate

class MyDocTemplate(BaseDocTemplate):
    """Override BaseDocTemplate for "progress bar" information"""

    def __init__(self, *args, **kwargs):
        BaseDocTemplate.__init__(self, *args, **kwargs)
        # BaseDocTemplate keeps a "progress" dictionary for its own
        # internal use, which is updated as various drawings are done.
        # This directs reportlab to use your own custom method
        # as the "callback" function when updates are made.
        # Notice the use of the __ prefix for the method, which ensures
        # that it calls *your* custom class's method, and not the default.
        # Should match the signature of the original callback: (self, type, value)
        self.setProgressCallBack(self.__onProgress)

    def __onProgress(self, prog_type, value):
        """Progress monitoring"""

        # One example "progress type" is the "PAGE" key. Which indicates
        # which page reportlab is working on.
        if prog_type == "PAGE":
            print "Drawing page: %s" % value
        elif prog_type == "FINISHED":
            print "Drawing complete!"

这里还有一些值(您可以在 中查看代码reportlab.platypus.doctemplate):

def progressCB(typ, value):
    """Example prototype for progress monitoring.

    This aims to provide info about what is going on
    during a big job.  It should enable, for example, a reasonably
    smooth progress bar to be drawn.  We design the argument
    signature to be predictable and conducive to programming in
    other (type safe) languages.  If set, this will be called
    repeatedly with pairs of values.  The first is a string
    indicating the type of call; the second is a numeric value.

    typ 'STARTING', value = 0
    typ 'SIZE_EST', value = numeric estimate of job size
    typ 'PASS', value = number of this rendering pass
    typ 'PROGRESS', value = number between 0 and SIZE_EST
    typ 'PAGE', value = page number of page
    type 'FINISHED', value = 0

    The sequence is
        STARTING - always called once
        SIZE_EST - always called once
        PROGRESS - called often
        PAGE - called often when page is emitted
        FINISHED - called when really, really finished

    some juggling is needed to accurately estimate numbers of
    pages in pageDrawing mode.

    NOTE: the SIZE_EST is a guess.  It is possible that the
    PROGRESS value may slightly exceed it, or may even step
    back a little on rare occasions.  The only way to be
    really accurate would be to do two passes, and I don't
    want to take that performance hit.
    """
    print 'PROGRESS MONITOR:  %-10s   %d' % (typ, value)
于 2012-10-22T14:33:55.537 回答