_build_mes_summary.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import re
  4. from datetime import datetime
  5. from openpyxl import load_workbook
  6. BASE = r"c:\work\demo\dayang\mescloud"
  7. EXTRACT = os.path.join(BASE, "_extract_mes_progress_output.txt")
  8. STATUS_XLSX = r"c:\Users\j2742\Desktop\temp\大洋\实施文档\MES实施现状-260716.xlsx"
  9. PIC_DIR = r"c:\Users\j2742\Desktop\temp\大洋\pic"
  10. OUT = os.path.join(BASE, "_mes_milestone_summary.txt")
  11. CELL_RE = re.compile(r"^([A-Z]+)(\d+): (.+)$")
  12. def fmt_val(v):
  13. if v is None:
  14. return ""
  15. if isinstance(v, datetime):
  16. return v.strftime("%Y-%m-%d")
  17. return str(v).strip()
  18. def extract_xlsx(path, max_rows=200, max_cols=30):
  19. lines = []
  20. wb = load_workbook(path, data_only=True)
  21. lines.append(f"文件: {path}")
  22. lines.append(f"工作表: {', '.join(wb.sheetnames)}")
  23. for name in wb.sheetnames:
  24. ws = wb[name]
  25. lines.append("")
  26. lines.append(f"--- 工作表: {name} (维度 {ws.dimensions}) ---")
  27. for row in ws.iter_rows(min_row=1, max_row=max_rows, min_col=1, max_col=max_cols):
  28. for cell in row:
  29. v = cell.value
  30. if v is not None and str(v).strip() != "":
  31. lines.append(f" {cell.coordinate}: {fmt_val(v)}")
  32. wb.close()
  33. return lines
  34. def parse_extract_sheet(text, sheet_name):
  35. pattern = rf"^SHEET: {re.escape(sheet_name)}\s*$"
  36. lines = text.splitlines()
  37. start = None
  38. for i, line in enumerate(lines):
  39. if re.match(pattern, line.strip()):
  40. start = i
  41. break
  42. if start is None:
  43. return []
  44. out = []
  45. for line in lines[start + 1:]:
  46. stripped = line.strip()
  47. if stripped.startswith("SHEET:"):
  48. break
  49. if stripped.startswith("--- Non-empty cells"):
  50. break
  51. m = CELL_RE.match(stripped)
  52. if m:
  53. out.append((m.group(1), int(m.group(2)), m.group(3)))
  54. return out
  55. def cells_to_rows(cells):
  56. rows = {}
  57. for col, row, val in cells:
  58. rows.setdefault(row, {})[col] = val
  59. return rows
  60. def list_images(root):
  61. exts = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".ico"}
  62. found = []
  63. for dirpath, _, filenames in os.walk(root):
  64. for fn in filenames:
  65. if os.path.splitext(fn)[1].lower() in exts:
  66. rel = os.path.relpath(os.path.join(dirpath, fn), root)
  67. found.append(rel.replace("\\", "/"))
  68. return sorted(found, key=lambda x: x.lower())
  69. with open(EXTRACT, "r", encoding="utf-8") as f:
  70. extract_text = f.read()
  71. sections = []
  72. sections.append("=" * 80)
  73. sections.append("六安裕洋 MES 实施里程碑与截图资源汇总")
  74. sections.append(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
  75. sections.append("数据来源: 大洋-京宜安MES实施进度.xlsx、MES实施现状-260716.xlsx、pic/ 目录")
  76. sections.append("=" * 80)
  77. # A
  78. sections.append("")
  79. sections.append("A. 总进度 — 各周完成率(来源:总进度)")
  80. sections.append("-" * 80)
  81. zong_cells = parse_extract_sheet(extract_text, "总进度")
  82. zong_rows = cells_to_rows(zong_cells)
  83. sections.append("汇总表:")
  84. sections.append(" 实施阶段 | 开始时间 | 结束时间 | 具体任务(周) | 任务数 | 完成数 | 合格率")
  85. for r in sorted(k for k in zong_rows if k >= 3):
  86. d = zong_rows[r]
  87. sections.append(
  88. f" {d.get('A','')} | {d.get('B','')} | {d.get('C','')} | {d.get('D','')} | "
  89. f"{d.get('E','')} | {d.get('F','')} | {d.get('G','')}"
  90. )
  91. # B
  92. sections.append("")
  93. sections.append("B. 全流程详细实施计划 — 阶段一至七(关键交付与状态)")
  94. sections.append("-" * 80)
  95. plan_cells = parse_extract_sheet(extract_text, "全流程详细实施计划")
  96. plan_rows = cells_to_rows(plan_cells)
  97. phases = []
  98. for r in sorted(plan_rows):
  99. a = plan_rows[r].get("A", "")
  100. if a and "阶段" in a:
  101. phases.append((r, a.replace("\n", " ")))
  102. for idx, (prow, pname) in enumerate(phases):
  103. end_row = phases[idx + 1][0] if idx + 1 < len(phases) else max(plan_rows) + 1
  104. sections.append("")
  105. sections.append(f"【{pname}】")
  106. for row in range(prow + 1, end_row):
  107. d = plan_rows.get(row, {})
  108. sub = d.get("B", "")
  109. if sub in ("项目准备", "软件框架搭建", "系统蓝图设计", "系统开发", "系统上线", "后续对接", "交付软件", "序号"):
  110. continue
  111. task = d.get("C", "")
  112. if not task and not d.get("H"):
  113. continue
  114. seq = d.get("B", "")
  115. content = d.get("H", "")
  116. status = d.get("P", "")
  117. deliverable = d.get("J", "")
  118. parts = []
  119. if seq:
  120. parts.append(f"{seq}. {task}" if task else f"{seq}.")
  121. else:
  122. parts.append(task)
  123. if content:
  124. parts.append(f"工作: {content}")
  125. if deliverable:
  126. parts.append(f"输出: {deliverable}")
  127. if status:
  128. parts.append(f"状态: {status}")
  129. sections.append(" " + " | ".join(p for p in parts if p))
  130. # C
  131. sections.append("")
  132. sections.append("C. 七月份第一周 / 七月份第二周 — 任务明细")
  133. sections.append("-" * 80)
  134. WEEKLY_COLS = ("B", "C", "D", "E", "F", "G", "H", "I", "J", "K")
  135. def format_weekly_task(row_num, d):
  136. lines = []
  137. title = d.get("B", "") or d.get("C", "")
  138. seq = d.get("A", "")
  139. head = f" 行{row_num}"
  140. if seq:
  141. head += f" / 序号{seq}"
  142. lines.append(head + ":")
  143. lines.append(f" 任务名称: {title}")
  144. if d.get("C"):
  145. lines.append(f" 工作内容: {d.get('C')}")
  146. lines.append(f" 甲方对接人: {d.get('D', '')}")
  147. lines.append(f" 乙方对接人: {d.get('E', '')}")
  148. if d.get("F") or d.get("G"):
  149. lines.append(f" 计划: {d.get('F', '')} ~ {d.get('G', '')}")
  150. lines.append(f" 状态: {d.get('H', '')}")
  151. if d.get("I"):
  152. lines.append(f" 进展说明: {d.get('I')}")
  153. if d.get("J"):
  154. lines.append(f" 备注: {d.get('J')}")
  155. k = d.get("K", "")
  156. if k and not str(k).startswith("=DISPIMG"):
  157. lines.append(f" 备注(K): {k}")
  158. return lines
  159. for sheet in ("七月份第一周", "七月份第二周"):
  160. sections.append("")
  161. sections.append(f"=== {sheet} ===")
  162. cells = parse_extract_sheet(extract_text, sheet)
  163. rows = cells_to_rows(cells)
  164. data_rows = [r for r in sorted(rows) if r >= 3 and any(rows[r].get(c) for c in WEEKLY_COLS)]
  165. for r in data_rows:
  166. sections.extend(format_weekly_task(r, rows[r]))
  167. # D
  168. sections.append("")
  169. sections.append("D. 问题清单(来源:问题清单工作表)")
  170. sections.append("-" * 80)
  171. prob_cells = parse_extract_sheet(extract_text, "问题清单")
  172. prob_rows = cells_to_rows(prob_cells)
  173. for r in sorted(prob_rows):
  174. if r < 3:
  175. continue
  176. d = prob_rows[r]
  177. if not (d.get("B") or d.get("C")):
  178. continue
  179. sections.append(
  180. f" {d.get('A', r-2)}. {d.get('B', '')} | 内容: {d.get('C', '')} | "
  181. f"对接人: {d.get('D', '')} | 后续: {d.get('E', '')} | 进度: {d.get('F', '')}"
  182. )
  183. # E
  184. sections.append("")
  185. sections.append("E. pic/ 目录截图文件完整列表")
  186. sections.append("-" * 80)
  187. imgs = list_images(PIC_DIR)
  188. sections.append(f"共 {len(imgs)} 个图片文件:")
  189. for im in imgs:
  190. sections.append(f" {im}")
  191. # F
  192. sections.append("")
  193. sections.append("F. MES实施现状-260716.xlsx 完整内容")
  194. sections.append("-" * 80)
  195. sections.extend(extract_xlsx(STATUS_XLSX))
  196. with open(OUT, "w", encoding="utf-8") as f:
  197. f.write("\n".join(sections) + "\n")
  198. print(f"Wrote {OUT}")
  199. print(f"Lines: {len(sections)}")