为什么我必须先从BytesIO转换字节,然后再转换回BytesIO,以便可以将其读取为PDF文件响应?

时间:2018-10-22 02:26:24

标签: python django-rest-framework pypdf2

我使用PyPDF4合并pdf文件,然后将合并的pdf用作HttpResponse。 我使用BytesIOPdfFileMerger获取结果。

我使用此代码正常工作

def mergePDF(listOfPDFFile):
    merger = PdfFileMerger()
    for file in listOfPDFFile:
        merger.append(PdfFileReader(file))
    _byteIo = BytesIO()
    merger.write(_byteIo)
    return _byteIo.getvalue()

然后,当我使用APIView中的方法将合并的pdf作为HttpResponse返回

class DocumentBundlePDFView(APIView):
    def get(self, request, format=None):
        '''
         here goes a process to assign list of document to documentList
        '''
        pdfBytes = mergePDF(documentList)
        pdfFile = io.BytesIO(pdfBytes)
        response = HttpResponse(FileWrapper(pdfFile), content_type='application/pdf')
        return response

但是,为什么我必须两次创建BytesIO对象才能使其工作? 最初,我返回_byteIO实例,然后将实例直接传递到FileWrapper,但它输出0Kb文件。

因此,我将_byteIO实例转换为bytes,然后在APIView中创建另一个BytesIO实例以使其正常工作。

如何简化代码?

1 个答案:

答案 0 :(得分:2)

在您的mergePDF函数中,而不是返回

return _byteIo.getvalue()

采取一些措施以达到效果

_byteIo.seek(0)
return _byteIo
  

最初,我返回_byteIO实例,然后直接传递   实例到FileWrapper,但输出0Kb文件。

问题是当您写入类似文件的对象时,光标被设置为最后一个字节。只需将其移回开头即可,否则就像从空文件中读取一样。