Ernestpneug 发表于 2025-10-24 19:45:54

PDF + ZIP 合并器:把ZIP文件打包至PDF文件中

因工作需要,需要将文件导入内网电脑,但一个办公区只能有一个公用U盘,操作不便,确可以通过手机App将文件传至内网(限制办公文件类型的传输),故开发此工具,KIMI提供帮助。
新文件会自动重命名,如new,new1,new2...
https://attach.52pojie.cn/forum/202507/31/220559m8ldojohap458da8.png?lhttps://attach.52pojie.cn/forum/202507/31/220714xflpjsrmsez7kdd7.png?l


https://attach.52pojie.cn/forum/202507/31/220809thd8h51kb18rrk11.png?l                ICO图标       https://attach.52pojie.cn/forum/202507/31/215605n9o2ly1ry6ofydk2.png?l


PYTHON直接运行,直接复制下面代码即可


import os,sys
import configparser
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from tkinterdnd2 import DND_FILES, TkinterDnD
import subprocess
import platform
from pathlib import Path



# ---------- 持久化 ini 路径 ----------
def get_ini_path() -> Path:
    """
    返回一个可持久写入的 ini 文件路径。
    开发时放在脚本目录;打包后放在用户数据目录。
    """
    if getattr(sys, 'frozen', False):
      # PyInstaller 打包后
      base = Path.home()/ 'PdfZipMerger' \
            if os.name == 'nt' else Path.home() / '.config' / 'PdfZipMerger'
    else:
      # 源码运行
      base = Path(__file__).parent
    base.mkdir(parents=True, exist_ok=True)
    return base / 'zipInPdfSettings.ini'

INI_FILE = get_ini_path()
# ---------- 配置 ----------
def load_output_dir() -> str:
    cfg = configparser.ConfigParser()
    cfg.read(INI_FILE, encoding="utf-8")
    return cfg.get("DEFAULT", "output_dir", fallback="")

def save_output_dir(path: str):
    cfg = configparser.ConfigParser()
    cfg["DEFAULT"] = {"output_dir": path}
    with open(INI_FILE, "w", encoding="utf-8") as f:
      cfg.write(f)

# ---------- 文件名 ----------
def auto_increment_filename(full_path: str) -> str:
    if not os.path.exists(full_path):
      return full_path
    base, ext = os.path.splitext(full_path)
    counter = 1
    while True:
      new_name = f"{base}{counter}{ext}"
      if not os.path.exists(new_name):
            return new_name
      counter += 1

# ---------- 拖拽 ----------
def drop_pdf(event):
    files = root.tk.splitlist(event.data)
    if files:
      pdf_var.set(files)
      if not out_dir_var.get():
            out_dir_var.set(os.path.dirname(files))

def drop_zip(event):
    files = root.tk.splitlist(event.data)
    if files:
      zip_var.set(files)

# ---------- 浏览 ----------
def browse_pdf():
    path = filedialog.askopenfilename(title="选择 PDF 文件", filetypes=[("PDF files", "*.pdf")])
    if path:
      pdf_var.set(path)
      if not out_dir_var.get():
            out_dir_var.set(os.path.dirname(path))

def browse_zip():
    path = filedialog.askopenfilename(title="选择 ZIP 文件", filetypes=[("ZIP files", "*.zip")])
    if path:
      zip_var.set(path)

def browse_out_dir():
    path = filedialog.askdirectory(title="选择输出目录")
    if path:
      out_dir_var.set(path)
      save_output_dir(path)

# ---------- 合并 ----------
def merge():
    pdf_path = pdf_var.get().strip('"')
    zip_path = zip_var.get().strip('"')
    out_dir = out_dir_var.get().strip()
    base_name = out_name_var.get().strip() or "new"
    if not pdf_path or not zip_path:
      messagebox.showerror("错误", "请选择 PDF 和 ZIP 文件!")
      return
    if not out_dir:
      messagebox.showerror("错误", "请选择输出目录!")
      return
    full_out = auto_increment_filename(os.path.join(out_dir, base_name + ".pdf"))
    try:
      with open(full_out, "wb") as out_file:
            out_file.write(open(pdf_path, "rb").read())
            out_file.write(open(zip_path, "rb").read())
      messagebox.showinfo("成功", f"已合并为:{full_out}")
    except Exception as e:
      messagebox.showerror("合并失败", str(e))

# ---------- 快捷按钮 ----------
def open_out_dir():

    out_dir = out_dir_var.get().strip()
    print(out_dir)
    # messagebox.showwarning("提示", f"输出目录不存在:{out_dir}")
    if not out_dir:
      messagebox.showwarning("提示", "请先选择输出目录!")
      return

    # 规范化路径,处理斜杠和反斜杠问题
    out_dir = os.path.normpath(out_dir)

    if not os.path.exists(out_dir):
      messagebox.showerror("错误", f"输出目录不存在:{out_dir}")
      return

    try:
      # 使用更健壮的方式打开文件浏览器
      if platform.system() == "Windows":
            print("Windows")
            subprocess.run(["explorer", out_dir], check=True)
            # os.startfile(out_dir)# Windows系统使用os.startfile
      elif platform.system() == "Darwin":
            print("macOS")
            subprocess.run(["open", out_dir], check=True)# macOS使用open命令
      else:# Linux
            print("Linux")
            subprocess.run(["xdg-open", out_dir], check=True)# Linux使用xdg-open
    except Exception as e:
      print("错误", f"无法打开文件夹:{str(e)}")
      # messagebox.showerror("错误", f"无法打开文件夹:{str(e)}")


def clear_inputs():
    pdf_var.set("")
    zip_var.set("")

# ---------- GUI ----------
root = TkinterDnD.Tk()
root.title("PDF + ZIP 合并器")
root.geometry("600x290")
root.resizable(False, False)

style = ttk.Style()
style.theme_use("vista")
print(style.theme_names())

# 配置按钮样式
style.configure("Red.TButton", background="red", foreground="red")
style.configure("Green.TButton", background="green", foreground="green")

# 拖拽提示
drag_tip = ttk.Label(root, text="PDF 和 ZIP 文件可直接拖拽到对应输入框中",
                     foreground="RoyalBlue", anchor="center", font=("Segoe UI", 12 ))
drag_tip.grid(row=0, column=0, columnspan=3, pady=(6, 0), sticky="ew", padx=10)

# PDF
ttk.Label(root, text="PDF 文件:").grid(row=1, column=0, padx=10, pady=8, sticky="e")
pdf_var = tk.StringVar()
pdf_entry = ttk.Entry(root, textvariable=pdf_var, width=55)
pdf_entry.grid(row=1, column=1, padx=5, pady=8)
pdf_entry.drop_target_register(DND_FILES)
pdf_entry.dnd_bind("", drop_pdf)
ttk.Button(root, text="浏览…", command=browse_pdf).grid(row=1, column=2, padx=5, pady=8)

# ZIP
ttk.Label(root, text="ZIP 文件:").grid(row=2, column=0, padx=10, pady=8, sticky="e")
zip_var = tk.StringVar()
zip_entry = ttk.Entry(root, textvariable=zip_var, width=55)
zip_entry.grid(row=2, column=1, padx=5, pady=8)
zip_entry.drop_target_register(DND_FILES)
zip_entry.dnd_bind("", drop_zip)
ttk.Button(root, text="浏览…", command=browse_zip).grid(row=2, column=2, padx=5, pady=8)

# 输出目录
ttk.Label(root, text="输出目录:").grid(row=3, column=0, padx=10, pady=8, sticky="e")
out_dir_var = tk.StringVar(value=load_output_dir())
out_dir_entry = ttk.Entry(root, textvariable=out_dir_var, width=55)
out_dir_entry.grid(row=3, column=1, padx=5, pady=8)
ttk.Button(root, text="浏览…", command=browse_out_dir).grid(row=3, column=2, padx=5, pady=8)

# 输出文件名
ttk.Label(root, text="新文件名:").grid(row=4, column=0, padx=10, pady=8, sticky="e")
out_name_var = tk.StringVar(value="new")
out_name_entry = ttk.Entry(root, textvariable=out_name_var, width=55)
out_name_entry.grid(row=4, column=1, padx=5, pady=8, sticky="w")
ttk.Button(root, text="打开输出文件夹", command=open_out_dir).grid(row=4, column=2, padx=5, pady=8)
# ttk.Button(btn_frame, text="打开输出文件夹", command=open_out_dir).pack(side="left", padx=10)

# 按钮行
btn_frame = ttk.Frame(root)
btn_frame.grid(row=5, column=0, columnspan=3, pady=12)
# 使用Red.TButton样式
ttk.Button(btn_frame, text="清空数据", command=clear_inputs, style="Red.TButton").pack(side="left", padx=10)
# 使用Green.TButton样式
ttk.Button(btn_frame, text="合并", command=merge, style="Green.TButton").pack(side="left", padx=10)

drag_tip2 = ttk.Label(root, text=f"配置文件路径:{INI_FILE}",
                     foreground="RoyalBlue", font=("Segoe UI", 10))
drag_tip2.grid(row=6, column=0, columnspan=3, pady=(6, 0), sticky="w", padx=10)
root.mainloop()



使用 pyinstaller 打包成单文件时需要添加 hook-tkinterdnd2.py,与上面代码 run.py 在同级目录即可,cmd 打包命令如下


pyinstaller -F -w -n="PDF + ZIP 合并器" --icon=a.ico run.py --additional-hooks-dir=.


hook-tkinterdnd2.py 代码如下


from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files('tkinterdnd2')





成品链接
https://xcherry.lanzouu.com/iQpQD32a0rwf

寒哥Gh61ac8 发表于 2025-10-24 19:46:24

改后缀没用啊,文件检测可不是傻子,会检测文件头和文件末尾的格式对不对的。
我把压缩包改成视频文件都需要老老实实塞一集猫和老鼠进去。然后有人下了资源发现这猫和老鼠真好看。

风之影赫 发表于 2025-10-24 19:47:14

事实上直接把文件放进 office 文档里就是了
office 文档 docx   xlsx   pptx 等,本身就是个zip压缩文件
使用7zip 打开office 文档,往里面扔文件即可
添加了文件后的office文件依旧能打开,只是会报个错,不影响使用

风之影赫 发表于 2025-10-24 19:47:25

有点意思的,先收藏一波

huoxianghui913 发表于 2025-10-24 19:48:24

这个平时真用不着 不过用时真找不到收藏是必须的

风之影赫 发表于 2025-10-24 19:48:34

改后缀名行不行呢?zip直接改pdf。

寒哥Gh61ac8 发表于 2025-10-24 19:49:28

收藏,谢谢啦

风之影赫 发表于 2025-10-24 19:50:13

要看zip直接改成zip吗?

寒哥Gh61ac8 发表于 2025-10-24 19:51:04

直接改后缀试过,直接被屏蔽了,会检测文件内容的

风之影赫 发表于 2025-10-24 19:51:54

直接有压缩软件打开就行,也可以改后缀
页: [1] 2
查看完整版本: PDF + ZIP 合并器:把ZIP文件打包至PDF文件中