使用Python和PyPDF2合并PDF文件会引发TypeError

时间:2018-04-06 21:38:28

标签: python pdf pypdf2

我正在使用Python 3.6.5将PDF合并在一起,但遇到了问题。下面的代码会引发'TypeError: 'NumberObject' object is not subscriptable'错误。我究竟做错了什么?当我用merger.append注释掉该行时,它会正确地打印出文件路径。

import webbrowser
import os
from PyPDF2 import PdfFileMerger, PdfFileReader

path = 'C:/test/pdfs'
merger = PdfFileMerger()
for pdf in os.listdir(path):
      merger.append(PdfFileReader(open(os.path.join(path,pdf), 'rb')))
      print(os.path.join(path,pdf))
merger.write(path+'/merged.pdf')
merger.close()
webbrowser.open_new(path+'/merged.pdf')
  

文件" C:\ test \ pdftest.py",第9行,in       merger.append(PdfFileReader(open(os.path.join(path,pdf),' rb')))     文件" C:\ python \ lib \ site-packages \ pypdf2-1.26.0-py3.6.egg \ PyPDF2 \ pdf.py",第1084行, init       self.read(流)     文件" C:\ python \ lib \ site-packages \ pypdf2-1.26.0-py3.6.egg \ PyPDF2 \ pdf.py",第1805行,读取       断言xrefstream [" / Type"] ==" / XRef"   TypeError:' NumberObject'对象不可订阅

当我更改merger.append以获取文件路径时,我得到:

  

文件" C:\ test \ pdftest.py",第9行,in       merger.append(os.path.join(路径,PDF))     文件" C:\ python \ lib \ site-packages \ pypdf2-1.26.0-py3.6.egg \ PyPDF2 \ merger.py",第203行,附加       self.merge(len(self.pages),fileobj,bookmark,pages,import_bookmarks)     合并文件" C:\ python \ lib \ site-packages \ pypdf2-1.26.0-py3.6.egg \ PyPDF2 \ merger.py",第133行,合并       pdfr = PdfFileReader(fileobj,strict = self.strict)     文件" C:\ python \ lib \ site-packages \ pypdf2-1.26.0-py3.6.egg \ PyPDF2 \ pdf.py",第1084行, init       self.read(流)     文件" C:\ python \ lib \ site-packages \ pypdf2-1.26.0-py3.6.egg \ PyPDF2 \ pdf.py",第1805行,读取       断言xrefstream [" / Type"] ==" / XRef"   TypeError:' NumberObject'对象不可订阅

更新:看起来文件夹中的一个PDF导致了此问题。与PDF不同的唯一不同之处在于它使用Type 1字体而其他PDF使用TrueType字体。有没有人知道解决方法或修复此问题?

1 个答案:

答案 0 :(得分:0)

这似乎是由无法识别或错误的 PDF 格式引起的。我不是 PDF 专家,但 PyPDF2 似乎在抱怨外部参照表中的记录。我发现解决此问题的最简单方法是重新格式化 PDF。

我所做的是将 merger.append(PDFFileReader(file)) 放在 try 中,如果我在异常中找到 'NumberObject' object is not subscriptable 消息,我会通过子进程在无头模式下使用 LibreOffice“转换”PDF:< /p>

command = [r'"C:\Program Files\LibreOffice\program\soffice.bin"',
           '--convert-to', 'pdf', '--outdir', f'"{dest_file_path}"', f'"{file_name}"']
pdf_convert = subprocess.Popen(' '.join(command)) 

关于使用 LibreOffice 和子进程的注意事项:无论出于何种原因,我发现作为列表传递会导致我在 Windows 中出现拒绝访问错误,这就是我改用 join 的原因。