RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1596450
Accepted
Kadenza
Kadenza
Asked:2024-10-12 15:32:40 +0000 UTC2024-10-12 15:32:40 +0000 UTC 2024-10-12 15:32:40 +0000 UTC

如何更轻松、更快速地将 pdf 分割成大小不超过 5MB 的部分

  • 772

我有一项任务将 pdf 文件从一个文件夹复制到另一个文件夹。如果某些 pdf 文件超过 5MB,则需要将其拆分为最多 5MB 的部分。

我写了一个函数来处理这个问题(请不要严格判断)但问题是这个函数对于超过100页的pdf文件需要很长时间才能工作。我需要处理数十万份文档

# Переместить и разбить при необходимости 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:
                print(from_page, to_page)
                new_pdf = fitz.open()
                new_pdf.insert_pdf(source_pdf, from_page=from_page, to_page=to_page)
                new_pdf.save("./tmp.pdf")
                pdf_size_mb = get_file_size_in_mb("./tmp.pdf")
                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
                new_pdf.close()
            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

您还能如何实现这样的算法来加速该过程?

python
  • 1 1 个回答
  • 21 Views

1 个回答

  • Voted
  1. Best Answer
    Kadenza
    2024-10-12T18:05:32Z2024-10-12T18:05:32Z

    我想出了一个快速的解决方案。但我会很感激你的提示

    # получить размер файла в Мб
    def get_file_size_in_mb(file_path):
        size_in_bytes = os.path.getsize(file_path)
        size_in_mb = size_in_bytes / (1024 * 1024)
        return size_in_mb
    
    
    # Получить диапазоны страниц для частей файла размером до max_size_mb
    def get_range_page_by_size(pdf_obj, max_size_mb, tmp_path=tmp_path_for_files):
        sizes_for_page = []
        count_pages = pdf_obj.page_count
        tmp_path = os.path.join(tmp_path, 'tmp.pdf')
    
        try:
            for page in range(count_pages):
                new_pdf = fitz.open()
                new_pdf.insert_pdf(pdf_obj, from_page=page, to_page=page)
                new_pdf.save(tmp_path)
                page_size = get_file_size_in_mb(tmp_path)
                os.remove(tmp_path)
    
                # если размер одной страницы превышает максимальный размер файла
                if page_size > max_size_mb:
                    return []
    
                sizes_for_page.append(page_size)
    
            ranges = []
            current_range = []
            current_size = 0
            for i, size in enumerate(sizes_for_page):
    
                if current_size + size <= max_size_mb:
                    current_range.append(i)
                    current_size += size
                else:
                    ranges.append([current_range[0], current_range[-1]])
                    current_range = [i]
                    current_size = size
    
            if len(current_range) > 0:
                ranges.append([current_range[0], current_range[-1]])
    
            return ranges
    
        except Exception as e:
            print(e)
            return []
    
    
    # Переместить и разбить при необходимости 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)
                range_page_by_size = get_range_page_by_size(source_pdf, max_size_mb=max_pdf_size_mb)
    
                if len(range_page_by_size) == 0:
                    report_message = f"Ошибка: не удалось разбить pdf файл {source_pdf_path} на части меньше {max_pdf_size_mb} МБ"
                else:
                    post_index = 1
    
                    if not os.path.exists(output_dir):
                        os.mkdir(output_dir)
    
                    for from_page, to_page in range_page_by_size:
                        new_pdf = fitz.open()
                        new_pdf.insert_pdf(source_pdf, from_page=from_page, to_page=to_page)
                        new_pdf_save_name = f"{new_pdf_name}_{post_index}.pdf"
                        save_path = os.path.join(output_dir, new_pdf_save_name)
                        new_pdf.save(save_path)
                        new_pdf.close()
                        result_paths_pdf.append(save_path)
                        post_index += 1
            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
    
    • 0

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5