Как разделить постранично pdf файл на Python с PyMuPDF на отдельные файлы?

Пример: имеется pdf файл с платежными поручениями (например 50 страниц), задача разделить файл на платежные поручения, т.е. получить 50 файлов, в каждом платежка.

Пробовал так:

    import pymupdf
    
    doc1 = pymupdf.open("pp_docs.pdf")
    doc2 = pymupdf.open()
    cnt = 0
    
    for page in doc1:
         
         doc2.insert_pdf(doc1,from_page=cnt, to_page=cnt, final=0)
         
         f_name = 'pdf_'+ str(cnt)+ '.pdf'
         doc2.save(f_name)
         doc2.close
         cnt +=1
    doc1.close

Результат: формируется 50 файлов, в этих файлах не каждая страница, а, почему-то набор страниц:

  • первый файл с первой странницей;
  • второй с первой и второй;
  • третий с первой, второй, третьей и т.д.
  • последний файл содержит все страницы.

Что делаю не так, и как сделать, чтобы разделить файл по отдельным страницам, т.е. каждая платежка в отдельном файле?


Ответы (3 шт):

Автор решения: ZxNuClear

Попробуйте библиотеку PyPDF2:

from PyPDF2 import PdfWriter, PdfReader

pdf = PdfReader(open("pp_docs.pdf", "rb"))

for i in range(len(pdf.pages)):
    output = PdfWriter()
    output.add_page(pdf.pages[i])
    with open("page-%s.pdf" % (i+1), "wb") as outputPDF:
        output.write(outputPDF)
→ Ссылка
Автор решения: VitoR InA

Ошибка заключалась в том, что вы записывали всё в один файл и сохраняли под разными названиями, ведь даже после использования метода .close() файл остаётся в качестве переменной со всеми его данными.

import pymupdf
    
src_doc = pymupdf.open("") #Ваш PDF файл

for page in src_doc:
    dst_doc = pymupdf.open() #ОШИБКА ТУТ
    dst_doc.insert_pdf(src_doc, from_page=page.number, to_page=page.number) #Лучше использовать атрибут страницы

    file_name = f"pdf_{page.number}.pdf" #f строки удобнее
    dst_doc.save(file_name)
    dst_doc.close

src_doc.close
→ Ссылка
Автор решения: MarianD

Переместите команду

doc2 = pymupdf.open()

в цикл:

for page in doc1:
     doc2 = pymupdf.open()
     doc2.insert_pdf(doc1,from_page=cnt, to_page=cnt, final=0)

Объяснение:

Проблема состоит в том, что вы в цикле повторно используете тот же самый документ doc2 (созданный как пустой только в начале), добавляя в него постепенно следующую и следующую страницу.


Примечание:

Вместо ручной манипуляции с переменной cnt вы можете ее применить в качестве переменной цикла, т.е. вместо команды

for page in doc1:

использовать команду

for cnt in range(doc1.page_count)

Другой подход — метод .select():

import pymupdf

DOC_PATH = "pp_docs.pdf"

doc = pymupdf.open(DOC_PATH)
pages = doc.page_count

for page in range(pages):
     doc = pymupdf.open(DOC_PATH)
     doc.select([page])                # сохранит только страницу page, остальные уберет
     doc.save(f'pdf_{page+1:02d}.pdf') # pdf_01.pdf, pdf_02.pdf, ...,  pdf_50.pdf
doc.close()
→ Ссылка