Как разделить постранично 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 шт):
Попробуйте библиотеку 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)
Ошибка заключалась в том, что вы записывали всё в один файл и сохраняли под разными названиями, ведь даже после использования метода .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
Переместите команду
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()