pdf.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #!/usr/bin/env python3
  2. """
  3. 图片ZIP转PDF脚本
  4. 将ZIP文件中的图片按序号排序并拼接成PDF文件
  5. """
  6. import zipfile
  7. import os
  8. import re
  9. from PIL import Image
  10. import shutil
  11. def 自然排序键(文件名):
  12. """将文件名转换为自然排序键,支持数字排序"""
  13. return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', 文件名)]
  14. def zip转pdf(zip路径):
  15. """
  16. 将ZIP文件中的图片排序后转换为PDF
  17. Args:
  18. zip路径: ZIP文件的完整路径
  19. Returns:
  20. 成功返回PDF路径,失败返回None
  21. """
  22. try:
  23. # 获取ZIP文件名(不含扩展名)
  24. zip目录, zip文件名 = os.path.split(zip路径)
  25. pdf名称 = os.path.splitext(zip文件名)[0] + '.pdf'
  26. pdf路径 = os.path.join(zip目录, pdf名称)
  27. print(f"正在处理: {zip文件名}")
  28. # 创建临时目录解压文件
  29. 临时目录 = os.path.join(zip目录, 'temp_extract')
  30. if os.path.exists(临时目录):
  31. shutil.rmtree(临时目录)
  32. os.makedirs(临时目录)
  33. # 解压ZIP文件
  34. with zipfile.ZipFile(zip路径, 'r') as zip文件:
  35. zip文件.extractall(临时目录)
  36. # 获取所有图片文件
  37. 支持的格式 = {'.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', '.webp'}
  38. 图片文件 = []
  39. for 根目录, 目录, 文件列表 in os.walk(临时目录):
  40. for 文件 in 文件列表:
  41. if any(文件.lower().endswith(格式) for 格式 in 支持的格式):
  42. 完整路径 = os.path.join(根目录, 文件)
  43. 图片文件.append(完整路径)
  44. if not 图片文件:
  45. print("错误: ZIP文件中没有找到图片文件")
  46. shutil.rmtree(临时目录)
  47. return None
  48. # 按文件名自然排序
  49. 图片文件.sort(key=lambda x: 自然排序键(os.path.basename(x)))
  50. print(f"找到 {len(图片文件)} 张图片,开始转换...")
  51. # 打开第一张图片作为基础
  52. 图片对象列表 = []
  53. for 图片路径 in 图片文件:
  54. try:
  55. 图片 = Image.open(图片路径)
  56. # 转换为RGB模式(确保兼容性)
  57. if 图片.mode != 'RGB':
  58. 图片 = 图片.convert('RGB')
  59. 图片对象列表.append(图片)
  60. except Exception as e:
  61. print(f"警告: 无法打开图片 {图片路径}: {e}")
  62. continue
  63. if not 图片对象列表:
  64. print("错误: 没有成功加载任何图片")
  65. shutil.rmtree(临时目录)
  66. return None
  67. # 保存为PDF(第一张作为主图,其余附加)
  68. 图片对象列表[0].save(
  69. pdf路径,
  70. "PDF",
  71. quality=95,
  72. optimize=True,
  73. save_all=True,
  74. append_images=图片对象列表[1:]
  75. )
  76. # 关闭所有图片对象
  77. for 图片 in 图片对象列表:
  78. 图片.close()
  79. # 清理临时文件
  80. shutil.rmtree(临时目录)
  81. # 删除原ZIP文件
  82. os.remove(zip路径)
  83. print(f"✓ 成功创建PDF: {pdf名称}")
  84. print(f"✓ 已删除原ZIP文件: {zip文件名}")
  85. return pdf路径
  86. except zipfile.BadZipFile:
  87. print(f"错误: {zip路径} 不是有效的ZIP文件")
  88. return None
  89. except Exception as e:
  90. print(f"处理过程中出错: {e}")
  91. # 清理临时文件
  92. if '临时目录' in locals() and os.path.exists(临时目录):
  93. shutil.rmtree(临时目录)
  94. return None
  95. def 批量处理当前目录():
  96. """批量处理当前目录下所有ZIP文件"""
  97. 当前目录 = os.getcwd()
  98. zip文件列表 = []
  99. # 扫描当前目录所有ZIP文件
  100. for 文件 in os.listdir(当前目录):
  101. if 文件.lower().endswith('.zip'):
  102. zip文件列表.append(os.path.join(当前目录, 文件))
  103. if not zip文件列表:
  104. print("当前目录下没有找到ZIP文件")
  105. return
  106. print(f"发现 {len(zip文件列表)} 个ZIP文件,开始批量处理...")
  107. print("-" * 50)
  108. 成功计数 = 0
  109. 失败计数 = 0
  110. for zip路径 in zip文件列表:
  111. print(f"\n[{zip文件列表.index(zip路径) + 1}/{len(zip文件列表)}] 处理: {os.path.basename(zip路径)}")
  112. # 执行转换
  113. 结果 = zip转pdf(zip路径)
  114. if 结果:
  115. 成功计数 += 1
  116. else:
  117. 失败计数 += 1
  118. print("-" * 50)
  119. print(f"批量处理完成!成功: {成功计数} 个,失败: {失败计数} 个")
  120. def 处理指定文件(zip路径):
  121. """处理指定的单个ZIP文件"""
  122. if not os.path.exists(zip路径):
  123. print(f"错误: 找不到文件 {zip路径}")
  124. return False
  125. if not zip路径.lower().endswith('.zip'):
  126. print("错误: 请提供ZIP格式的文件")
  127. return False
  128. # 执行转换
  129. 结果 = zip转pdf(zip路径)
  130. if 结果:
  131. print(f"\n🎉 任务完成!PDF文件已保存为: {结果}")
  132. return True
  133. else:
  134. print("\n❌ 任务失败,请检查错误信息")
  135. return False
  136. def 主函数():
  137. """主函数:智能处理模式"""
  138. import sys
  139. # 优先处理指定文件(如果存在)
  140. 指定文件路径 = r"C:\Users\lenovo\Desktop\新建文件夹\剥头皮量化策略全拆解:低延迟、高频的底层.zip"
  141. # 检查是否有命令行参数
  142. if len(sys.argv) > 1:
  143. # 命令行指定了ZIP文件路径
  144. zip路径 = sys.argv[1]
  145. print(f"通过命令行参数指定文件: {zip路径}")
  146. 处理指定文件(zip路径)
  147. elif os.path.exists(指定文件路径):
  148. # 处理默认指定文件
  149. print(f"处理默认指定文件: {os.path.basename(指定文件路径)}")
  150. 处理指定文件(指定文件路径)
  151. else:
  152. # 自动扫描当前目录所有ZIP文件
  153. print("开始扫描当前目录所有ZIP文件...")
  154. 批量处理当前目录()
  155. if __name__ == "__main__":
  156. 主函数()