Top.Mail.Ru
Ответы
Аватар пользователя
8мес
Аватар пользователя
Аватар пользователя
Программирование
+1

Как проще и быстрее разбить pdf на часть размером до 5Мб

У меня есть задача копировать файлы pdf из одной папки в другую. Если какие-то файлы pdf более 5Мб то их надо разбить на части до 5Мб.

Я написал функцию, которая с этим справляется (просьба строго не судить) Но проблема в том что эта функция работает оооочень долго для pdf у которых более 100 страниц. А мне требуется обработать сотни тысяч документов

Как еще можно реализовать такой алгоритм чтобы ускорить процесс?


12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
 # Переместить и разбить при необходимости pdf 
def copy_and_split_pdf(source_pdf_path, output_dir, new_pdf_name, max_pdf_size_mb=5.0): 
    report_message = "" 
    result_paths_pdf = [] 
 
    try: 
        file_size_in_mb = get_file_size_in_mb(source_pdf_path) 
        if file_size_in_mb > max_pdf_size_mb: 
            source_pdf = fitz.open(source_pdf_path) 
 
            result_pdfs_obj = [] 
            qty_pages = source_pdf.page_count 
            from_page = 0 
            to_page = qty_pages-1 
 
            while True: 
                new_pdf = fitz.open() 
                pdf_stream = io.BytesIO() 
                new_pdf.insert_pdf(source_pdf, from_page=from_page, to_page=to_page) 
                new_pdf.save(pdf_stream) 
                pdf_size_bytes = pdf_stream.getbuffer().nbytes 
                pdf_size_mb = pdf_size_bytes / (1024 * 1024) 
                pdf_stream.close() 
 
                if pdf_size_mb < max_pdf_size_mb: 
                    result_pdfs_obj.append(new_pdf) 
 
                    # print(from_page, to_page, pdf_size_mb) 
                    if to_page == qty_pages - 1: 
                        break 
                    from_page = to_page+1 
                    to_page = qty_pages-1 
                else: 
                    if from_page == to_page: 
                        for pdf in result_pdfs_obj: 
                            pdf.close() 
                        result_pdfs_obj = [] 
                        break 
                    to_page -= 1 
 
            source_pdf.close() 
 
            if len(result_pdfs_obj) == 0: 
                report_message = f"Ошибка: не удалось разбить pdf файл {source_pdf_path} на части меньше {max_pdf_size_mb} МБ" 
            else: 
 
                if not os.path.exists(output_dir): 
                    os.mkdir(output_dir) 
 
                for pdf in result_pdfs_obj: 
                    new_pdf_save_name = f"{new_pdf_name}_{result_pdfs_obj.index(pdf)+1}.pdf" 
                    save_path = os.path.join(output_dir, new_pdf_save_name) 
                    pdf.save(save_path) 
                    pdf.close() 
                    result_paths_pdf.append(save_path) 
        else: 
 
            if not os.path.exists(output_dir): 
                os.mkdir(output_dir) 
 
            new_pdf_name = f"{new_pdf_name}.pdf" 
            save_path = os.path.join(output_dir, new_pdf_name) 
            shutil.copy2(source_pdf_path, save_path) 
            result_paths_pdf.append(save_path) 
 
    except Exception as e: 
        print(e) 
        report_message = f"Ошибка: {e} (Не удалось загрузить файл: {source_pdf_path})" 
    finally: 
        return report_message, result_paths_pdf 
По дате
По рейтингу
Аватар пользователя
Искусственный Интеллект
8мес

Сколько $ скинешь на...?

Аватар пользователя
Искусственный Интеллект
8мес

хм.. ты даже не пытаешься использовать процессорный пул и... много операций сброса на диск.. Ладно.

Можно так:
— Фильтруешь крупное файло и с помощью пакетной функции в Wondershare PDFelement сжимаешь в другую папку (обычно получается двухкратное сжатие легко)
— Сжатую папку снова фильтруешь на остатки и списком загружаешь в PDF Shaper Ultimate(есть ком. строка) и делишь на мелкие части, к примеру по 100 стр.

Остается склепать автоматизацию этих приложений. Но они работают в разы быстрее Python, несмотря на то, что ты применяешь pdf-библу.

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