使用 reportlab 和 PyPDF2 合并 PDF 会丢失图像和嵌入字体

Merging PDFs using reportlab and PyPDF2 loses images and embedded fonts

我正在尝试获取存储在 AWS 上的现有 PDF,将其读入我的后端(Django 1.1,Python 2.7)并在边距中添加文本。我当前的代码成功地接受了 PDF 并将文本添加到边距,但它损坏了 PDF:

在浏览器中打开时:

  1. 删除图片
  2. 偶尔在单词之间添加字符
  3. 偶尔完全改变PDF的字符集

在 Adob​​e 中打开时:

  1. 说“无法提取嵌入字体 'whatever font name'。一些 许多字符无法正确显示或打印
  2. 说 "A drawing error occured"
  3. 如果有图片预编辑,提示“数据不足 图片

我制作了自己的 PDF with/without 预定义字体和 with/without 图片。具有预定义字体且没有图像的那些可以按预期工作,但是在 Adob​​e 中打开图像时它会抛出 "There was an error while reading a stream.",并且不会在浏览器中显示图像。我得出的结论是缺少字体是字符出现问题的原因,但我不确定为什么不显示图像。

我无法控制我正在编辑的 PDF 的内容,所以我不能确保它们只使用预定义的字体,而且它们肯定需要在其中包含图像。下面是我的代码

from reportlab.pdfgen import canvas

from PyPDF2 import PdfFileWriter, PdfFileReader
from StringIO import StringIO

class DownloadMIR(APIView):
    permission_classes = (permissions.IsAuthenticated,)

    def post(self, request, format=None):
        data = request.data

        file_path = "some_path"
        temp_file_path = "some_other_path"

        # read your existing PDF

        if default_storage.exists(file_path):
            existing_pdf = PdfFileReader(default_storage.open(file_path, 'rb'))
        else:
            raise Http404("could not find pdf")

        packet = StringIO()
        # create a new PDF with Reportlab
        can = canvas.Canvas(packet)
        height, width = int(existing_pdf.getPage(0).mediaBox.getUpperRight_x()), int(
            existing_pdf.getPage(0).mediaBox.getUpperRight_y())
        print("width:" + str(width) + " height: " + str(height))
        can.setPageSize([width, height])
        can.rotate(90)
        footer = "Prepared for " + request.user.first_name + " " + request.user.last_name + " on " + datetime.now().strftime('%Y-%m-%d at %H:%M:%S')
        can.setFont("Courier", 8)
        can.drawCentredString(width / 2, -15, footer)
        can.save()

        packet.seek(0)
        new_pdf = PdfFileReader(packet)

        output = PdfFileWriter()
        for index in range(existing_pdf.numPages):
            page = existing_pdf.getPage(index)
            page.mergePage(new_pdf.getPage(0))
            output.addPage(page)
            #print("done page " + str(index))

        response = HttpResponse(content_type="application/pdf")

        response['Content-Disposition'] = 'attachment; filename=' + temp_file_path

        output.write(response)
        return response

使用 script I found online,我看到有未嵌入的字体。

Font List
['/MPDFAA+DejaVuSansCondensed', '/MPDFAA+DejaVuSansCondensed-Bold
', '/MPDFAA+DejaVuSansCondensed-BoldOblique', '/MPDFAA+DejaVuSans
Condensed-Oblique', '/ZapfDingbats']

Unembedded Fonts
set(['/MPDFAA+DejaVuSansCondensed-Bold', '/ZapfDingbats', '/MPDFA
A+DejaVuSansCondensed-BoldOblique', '/MPDFAA+DejaVuSansCondensed'
, '/MPDFAA+DejaVuSansCondensed-Oblique'])

问题是这些 - 有没有办法从原始 PDF 中提取嵌入字体并将其嵌入到新 pdf 中;是不是我做的不对导致图像无法嵌入?

经过一些测试,我发现问题不在于生成的 PDF,而是返回 PDF 作为响应。如果我将我的 PDF 保存到存储桶并从 AWS CLI 下载它,它就可以工作。我没有弄清楚如何修复响应以将 PDF 正确发送回前端。