代码之家  ›  专栏  ›  技术社区  ›  JayBee

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

  •  0
  • JayBee  · 技术社区  · 7 年前

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

    在浏览器中打开时:

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

    在Adobe中打开时:

    1. 表示“无法提取嵌入字体‘任意字体名称’” 许多字符无法正确显示或打印“
    2. 表示“发生绘图错误”
    3. 如果有预编辑的图片,则表示“没有足够的数据用于 “图像”

    我已经制作了自己的PDF,有/没有预定义的字体,有/没有图像。那些具有预定义字体且没有图像的文件按预期工作,但对于图像,它会抛出“读取流时出错”在Adobe中打开时,只是不在浏览器中显示图像。我得出的结论是,缺少字体是字符出现问题的原因,但我不确定为什么图像没有显示出来。

    我无法控制正在编辑的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中;还有,是不是有什么我做得不好导致图像无法嵌入?

    1 回复  |  直到 6 年前
        1
  •  0
  •   JayBee    6 年前

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