Как совместить неограниченное кол-во пдф файлов с другим одним?

Рейтинг: 0Ответов: 1Опубликовано: 25.07.2025

У меня есть функция которая из одного .pdf файла перекидывает электросхемы в другие файлы, но есть проблема:

если зайти в .pdf файлы после всего процесса (условно у меня 3 .pdf документа), то с каждым документом схем будет все больше (первый .pdf = 1 схема второй .pdf = 2 схемы третий .pdf = 3 схемы) а должно быть в каждой по одной

Функция:

from docx import Document
from config import word_path
import os
import re
from config import *
from docx.shared import Inches
from docx import Document
from pdf2docx import Converter
from docx.shared import Inches
import tempfile
from pathlib import Path
from datetime import datetime
from docx.enum.style import WD_STYLE_TYPE
from docx2pdf import convert
import aspose.words as aw
import fitz
from PyPDF2 import PdfReader, PdfWriter
import shutil
from electro import insert_docx_into_docx


def process_pdf_attachment(electro_path, passports_path):
    """Обрабатывает и вставляет PDF в основной документ"""
    # Создаем уникальное имя временного файла
    FILES_DIR = Path(__file__).parent / 'files'
    FILES_DIR.mkdir(exist_ok=True)
    temp_filename = f"temp_{os.path.basename(electro_path).replace('.pdf', '')}.docx"
    temp_docx_path = str(FILES_DIR / temp_filename)

    temp_pdf_folder = Path(passports_path).parent / "Passports_temp"
    try:
        # Конвертируем PDF в DOCX
        if not convert_docx_to_pdf(passports_path, temp_pdf_folder, electro_path):
            return False

        # insert_docx_into_docx(electro_path, temp_pdf_folder, passports_path)

        # Вставляем во временный DOCX в основной документ

        print(f"Временный файл сохранен в: {temp_docx_path}")
        return True

    except Exception as e:
        print(f"Ошибка при обработке PDF: {str(e)}")
        return False


def convert_docx_to_pdf(passports_path, temp_pdf_folder, electro_path):
    """
    Конвертирует DOCX в PDF, удаляет исходные DOCX файлы после успешной конвертации
    и перемещает все PDF в папку Passports_temp рядом с исходной папкой

    :param passports_path: Путь к папке с документами
    :return: Кортеж (количество конвертированных файлов, количество удаленных файлов)
    """
    try:
        folder_path = Path(passports_path)
        print(f"Обрабатываемая папка: {folder_path}")

        if not folder_path.exists():
            print(f"Папка не найдена: {passports_path}")
            return (0, 0)

        # Создаем папку Passports_temp на одном уровне с исходной папкой
        temp_pdf_folder.mkdir(exist_ok=True)
        print(f"Создана временная папка: {temp_pdf_folder}")

        success_count = 0
        deleted_count = 0

        for docx_file in folder_path.glob('*.docx'):
            pdf_path = folder_path / f"{docx_file.stem}.pdf"
            print(f"\nОбработка: {docx_file.name}")

            try:
                # Конвертация в PDF
                doc = aw.Document(str(docx_file))
                doc.save(str(pdf_path))

                if pdf_path.exists():
                    print(f"✓ PDF создан: {pdf_path.name}")
                    success_count += 1

                    # Удаление DOCX после успешной конвертации
                    try:
                        os.remove(docx_file)
                        print(f"🗑️ Удален исходный файл: {docx_file.name}")
                        deleted_count += 1
                    except Exception as delete_error:
                        print(f"× Ошибка при удалении {docx_file.name}: {str(delete_error)}")
                else:
                    print(f"× PDF не создан для: {docx_file.name}")

            except Exception as convert_error:
                print(f"× Ошибка конвертации {docx_file.name}: {str(convert_error)}")
                continue

        # Перемещаем все PDF файлы во временную папку
        pdf_files = list(folder_path.glob('*.pdf'))
        moved_count = 0

        for pdf_file in pdf_files:
            try:
                target_path = temp_pdf_folder / pdf_file.name
                shutil.move(str(pdf_file), str(target_path))
                moved_count += 1
                print(f"⇨ Перемещен PDF: {pdf_file.name} → {target_path}")
            except Exception as move_error:
                print(f"× Ошибка при перемещении {pdf_file.name}: {str(move_error)}")

        print(f"\nИтог:")
        print(f"- Успешно конвертировано: {success_count} файлов")
        print(f"- Удалено исходных DOCX: {deleted_count} файлов")
        print(f"- Перемещено PDF в {temp_pdf_folder.name}: {moved_count} файлов")

        return (success_count, deleted_count)


    except Exception as e:
        print(f"Критическая ошибка: {str(e)}")
        return (0, 0)


def insert_docx_into_docx(electro_path, temp_pdf_folder, passports_path):
    """
    Обрабатывает PDF файлы по одному:
    1. Добавляет схемы из electro_path
    2. Перемещает в папку Паспорта
    3. Удаляет из временной папки
    """
    # Создаем временный файл с повернутыми страницами
    with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as temp_file:
        temp_path = temp_file.name

        # Поворачиваем страницы исходного PDF и сохраняем во временный файл
        with open(electro_path, 'rb') as original_add_file:
            pdf_to_rotate = PdfReader(original_add_file)
            writer = PdfWriter()

            for page in pdf_to_rotate.pages:
                page.rotate(-90)  # Поворот на 90 градусов против часовой стрелки
                writer.add_page(page)

            writer.write(temp_file)

    try:
        # Получаем список PDF-файлов в папке
        pdf_files = [f for f in os.listdir(temp_pdf_folder) if f.lower().endswith('.pdf')]

        if not pdf_files:
            print(f"В папке {temp_pdf_folder} не найдено PDF-файлов.")
            return False

        print(f"Найдено {len(pdf_files)} PDF-файлов для обработки.")

        # Читаем повернутый временный PDF
        with open(temp_path, 'rb') as rotated_file:
            rotated_pdf = PdfReader(rotated_file)

            for pdf_file in pdf_files:
                input_path = os.path.join(temp_pdf_folder, pdf_file)
                output_path = os.path.join(passports_path, pdf_file)

                print(f"\nНачинаем обработку файла: {pdf_file}")

                # Создаем новый PDF с добавленными схемами
                writer = PdfWriter()

                try:
                    # Добавляем оригинальные страницы
                    with open(input_path, 'rb') as original_file:
                        original_pdf = PdfReader(original_file)
                        for page in original_pdf.pages:
                            writer.add_page(page)

                    # Добавляем повернутые страницы схем
                    for page in rotated_pdf.pages:
                        writer.add_page(page)

                    # Сохраняем результат в папку Паспорта
                    with open(output_path, 'wb') as output_file:
                        writer.write(output_file)

                    print(f"✓ Файл {pdf_file} успешно обработан")

                    # Удаляем исходный файл из временной папки
                    try:
                        os.remove(input_path)
                        print(f"🗑️ Файл {pdf_file} удален из временной папки")
                    except Exception as delete_error:
                        print(f"× Ошибка при удалении {pdf_file}: {str(delete_error)}")
                        continue

                except Exception as file_error:
                    print(f"× Ошибка при обработке файла {pdf_file}: {str(file_error)}")
                    continue

        print("\nОбработка всех файлов завершена!")
        return True

    finally:
        # Удаляем временный файл
        os.unlink(temp_path)
        print("Временный файл с повернутыми страницами удален.")

Ответы

▲ 1

Скорее всего, тут проблема с glob, который не справляется с новыми файлами в папке. В результате вновь созданный файл подсовывается вам как очередной. Поэтому, есть два варианта:

  1. Сначала сделать список файлов, а потом их обрабатывать.
  2. Сохранять результат в другой папке.

В Питоне не силён - надеюсь, закодировать сможете сами.