PyPDF2 возвращает пустой PDF после копирования

def EncryptPDFFiles(password, directory):
    pdfFiles = []
    success = 0

    # Get all PDF files from a directory
    for folderName, subFolders, fileNames in os.walk(directory):
        for fileName in fileNames:
            if (fileName.endswith(".pdf")):
                pdfFiles.append(os.path.join(folderName, fileName))
    print("%s PDF documents found." % str(len(pdfFiles)))

    # Create an encrypted version for each document
    for pdf in pdfFiles:
        # Copy old PDF into a new PDF object
        pdfFile = open(pdf,"rb")
        pdfReader = PyPDF2.PdfFileReader(pdfFile)
        pdfWriter = PyPDF2.PdfFileWriter()
        for pageNum in range(pdfReader.numPages):
            pdfWriter.addPage(pdfReader.getPage(pageNum))
        pdfFile.close()

        # Encrypt the new PDF and save it
        saveName = pdf.replace(".pdf",ENCRYPTION_TAG)
        pdfWriter.encrypt(password)
        newFile = open(saveName, "wb")
        pdfWriter.write(newFile)
        newFile.close()
        print("%s saved to: %s" % (pdf, saveName))


        # Verify the the encrypted PDF encrypted properly
        encryptedPdfFile = open(saveName,"rb")
        encryptedPdfReader = PyPDF2.PdfFileReader(encryptedPdfFile)
        canDecrypt = encryptedPdfReader.decrypt(password)
        encryptedPdfFile.close()
        if (canDecrypt):
            print("%s successfully encrypted." % (pdf))
            send2trash.send2trash(pdf)
            success += 1

    print("%s of %s successfully encrypted." % (str(success),str(len(pdfFiles))))

Я следую вместе с Pythons Automate the Boring Stuff. У меня возникали проблемы при копировании PDF-документа, но на данный момент каждый раз, когда я запускаю программу, все мои скопированные PDF-файлы представляют собой пустые страницы. В моем недавно зашифрованном PDF-файле правильное количество страниц, но все они пустые (на страницах нет содержимого). У меня было такое раньше, но я не смог воссоздать. Я пытался уснуть перед закрытием файлов. Я не уверен, что лучше всего открывать и закрывать файлы в Python. Для справки я использую Python3.


person stryker14    schedule 05.06.2017    source источник


Ответы (2)


Попробуйте переместить pdfFile.close в самый конец цикла for.

for pdf in pdfFiles:
    #
    # {stuff}
    #
    if (canDecrypt):
        print("%s successfully encrypted." % (pdf))
        send2trash.send2trash(pdf)
        success += 1

    pdfFile.close()

Идея состоит в том, что pdfFile должен быть доступен и открыт, когда pdfWriter наконец записывает, иначе он не сможет получить доступ к страницам для записи нового файла.

person James C. Taylor    schedule 06.06.2017
comment
Спасибо, похоже, это сработало (пришлось закрыть его перед отправкой в ​​​​мусор, однако в моем конкретном примере). Вы определенно правы в том, что pdfReader должен оставаться открытым до тех пор, пока pdfWriter не запишет и не закроется. Полагаю, у меня было ложное предположение, что функция getPage создает всю информацию, необходимую писателю. Если писатель зависит от того, что читатель все еще открыт, даже если вы сохранили из него объект страницы, это кажется нелогичным. Спасибо еще раз! - person stryker14; 07.06.2017

Проблема с получением пустой страницы даже после добавления страницы в ваш PDF-файл с помощью writer.addPage(your_page_name) связана с менеджером контекста. Вы должны убедиться, что вы не закрываете PDF-файл, из которого вы читаете страницу.

Например:

with open(str(_pdf), "rb") as in_f:
    reader = PdfFileReader(in_f)
    _page = reader.getPage(0)
    writer = PdfFileWriter()
    writer.addPage(_page)

with open(_filename, "wb+") as out_f:
    writer.write(out_f)

Это НЕ РАБОТАЕТ, так как дескриптор файла закрывается менеджером контекста. Файл должен быть открыт, поэтому нам нужно сделать отступ. Как следующее:

with open(str(_pdf), "rb") as in_f:
    reader = PdfFileReader(in_f)
    _page = reader.getPage(0)
    writer = PdfFileWriter()
    writer.addPage(_page)

    with open(_filename, "wb+") as out_f:
        writer.write(out_f)

Я знаю, что это не имеет большого значения, но это буквально заставило меня вырвать волосы, отступы потратили впустую мои 6 часов. Вот почему я подумал, что должен написать ответ для других

person Mujeeb Ishaque    schedule 07.08.2020