发动机电控检修工单字段建模与Word页码生成

📅 发布时间:2026/9/17 9:28:07
发动机电控检修工单字段建模与Word页码生成
简介《汽车发动机电控系统检修工单有页码》是面向中职汽车专业学生与实训指导教师的配套教学工单配合校本教材《汽车发动机电控系统检修》开展理实一体化教学。内容围绕桑塔纳2000与本田雅阁两款实训车型展开按发动机电控系统认识、空气供应装置、燃油供应装置、汽油机点火系、电子控制装置五个模块编排采用行动导向教学法组织分组任务引导学生填写元件名称、燃油流动方向、进气系统元件位置并理解空燃比、过量空气系数以及怠速、小负荷、加速、冷启动等工况对混合气成分的要求。资源包共1个doc文档约9.45MB正文带页码便于课堂分发、任务记录与成绩评定。目前已有68人学习下载。对需要组织实训课、编写工作单或备考检修技能考核的师生来说可直接获得完整的任务描述、实训设备清单、资讯获取题与实施流程省去从零设计工单的时间。1. 一份带页码的发动机电控系统检修工单到底解决什么问题三页纸的汽车发动机电控系统检修工单掉了第二页会怎样技师手里只剩故障码页和签字页中间那段数据流实测值写在哪儿、节气门位置传感器的电压是多少全对不上号。维修厂把工单扫描归档时还会撞上一个更尴尬的情况同一台车、同一个故障码两个月内出现四次记录却没法确认这四张是不是同一份拆散后重复上传。页码看着是排版细节实际决定了这份文档能不能被核对、被检索、被追责。规范的电控系统检修工单页码要解决三件事打印件与电子件的页数一一对应翻到第 2 页就知道整份共几页检修工序按问诊、读码、数据流、部件实测、复核签字的固定顺序展开页码本身就是工序顺序归档时页码参与命名缺页和重复一查便知。做汽修厂 DMS 二次开发的人、把纸质工单电子化的技术员、需要批量出单的服务主管后面这套字段设计和生成脚本可以直接拿去改。2. 发动机电控系统检修工单的字段建模与分页规则2.1 电控检修的信息为什么必须分四层把工单拍平成一张大表是最常见的返工来源。发动机电控系统的检修信息天然有四层车辆层VIN、发动机代码、进厂里程、故障层读到的 DTC 列表、测量层每个检修项的单位、标准区间、实测值、判定、结论层更换件、复核人、交车状态。层级混在一起会出现一张工单里同一个故障码对应五六行测量值、却没法判断哪一行属于哪个工序的情况。分层之后工单的物理页也能跟着分层第 1 页放车辆层和问诊记录第 2 页起是故障层加测量层的明细表最后一页是结论层和签名区。这样第几页写什么就固定下来技师填错位置的概率大幅下降也让后面用脚本按序号算页码成为可能。工单模板一旦定稿改动成本主要在明细表的列所以列的粒度要提前想清楚一个测量项一行不要一行塞多个传感器。2.2 工单主表与明细表的字段定义主表只存一份工单一份记录明细表按工序序号展开。下面这套字段在多数维修厂的 DMS 里都能直接落地字段名用下划线风格方便后面往 Word 模板里映射。字段类型必填说明示例wo_novarchar(20)是工单号建议日期工位流水20240612-A03-0007vinchar(17)是车架号归档检索主键LSG×××××××××××××××engine_codevarchar(20)是发动机型号代码决定参数区间见车辆铭牌mileageint是进厂里程单位 km86520dtc_listvarchar(200)否读到的故障码逗号分隔P0300,P0171page_totalsmallint是工单总页数与页脚总页数一致3technicianvarchar(20)是主修人——reviewervarchar(20)否复核人签名页使用——明细表的字段决定了工单能不能被程序校验重点是把标准区间和实测值拆成两个数值列而不是一个结果文本框。字段类型说明seqsmallint工序序号从 1 连续递增缺号即漏项item_typevarchar(10)DTC / 数据流 / 静态实测 / 更换件codevarchar(16)故障码或参数代号namevarchar(64)中文名如 空气流量计、节气门位置传感器unitvarchar(8)V / kΩ / kPa / bar / r/minspec_mindecimal(8,2)标准下限spec_maxdecimal(8,2)标准上限measureddecimal(8,2)实测值未测留空而不是填 0verdictvarchar(6)正常 / 异常 / 待复测建表语句里给 seq 加唯一约束能在入库阶段就挡住重复工序。-- 工单明细表seq 在同一工单内唯一防止重复录项 CREATE TABLE t_wo_item ( wo_no VARCHAR(20) NOT NULL, seq SMALLINT NOT NULL, item_type VARCHAR(10) NOT NULL, code VARCHAR(16), name VARCHAR(64) NOT NULL, unit VARCHAR(8), spec_min DECIMAL(8,2), spec_max DECIMAL(8,2), measured DECIMAL(8,2), verdict VARCHAR(6) DEFAULT 待复测, PRIMARY KEY (wo_no, seq), CONSTRAINT chk_seq CHECK (seq 1) );PK 用 (wo_no, seq) 而不是自增 id是为了让工单号加序号直接对应到纸质件的行位置后面算页码时不用再查一次映射表。measured 允许 NULL 是关键未测量的项和实测为 0 的项在判定逻辑里完全是两回事窄带氧传感器电压为 0 V 是异常未测量只是没做。2.3 从 DTC 前缀路由到检修项的规则故障码前缀本身就带着系统归属用它做路由比让技师手工选模块稳得多。P01 开头指向进气与燃油计量P03 指向点火与失火P21 指向电子节气门U0 指向总线通信。把前缀做成字典读码之后自动带出该查的测量项工单的明细区就先填好了骨架。# DTC 前三位 → (所属模块, 默认带出的测量项) DTC_ROUTE { P01: (进气与燃油计量, [空气流量计电压, 进气歧管压力, 长期燃油修正]), P02: (喷油器电路, [喷油器电阻, 喷油脉宽, 缸压]), P03: (点火与失火, [点火线圈初级电阻, 缸压, 曲轴位置信号]), P04: (排放控制, [前氧电压, 后氧电压, 碳罐电磁阀电阻]), P05: (车速与怠速, [节气门位置电压, 怠速转速]), P06: (ECU 与电源, [ECU 供电电压, 搭铁电阻]), P21: (电子节气门, [节气门位置1电压, 节气门位置2电压, 节气门电机电阻]), U0: (总线通信, [CAN-H 电压, CAN-L 电压, 终端电阻]), } def route_items(dtc_list): 按 DTC 前缀生成明细行骨架seq 全局连续 rows, seq [], 1 for dtc in dtc_list: module, items DTC_ROUTE.get(dtc[:3], (通用检查, [静态检查])) for name in items: rows.append({seq: seq, dtc: dtc, module: module, name: name}) seq 1 return rowsdtc[:3]取前三位P0101 得到 P01P2135 得到 P21前缀表没覆盖的组合走通用检查兜底不会因为新增一个码就报错。实际维护时把这张字典挪进数据库字典表加条目不用改代码。注意同一个 DTC 可能命中多个测量项明细行会变多这也是为什么分页规则要提前定好。2.4 页码与工序序号的绑定算法工单要有页码核心是让页码可预测而不是靠 Word 自动分页碰运气。做法是给明细区定一个每页固定行数序号先算页、再算页内行号。ROWS_PER_PAGE 12 # 明细区每页固定行数按 A4 单面、小五号字实测得出 FRONT_PAGES 1 # 第 1 页为车辆信息与问诊页 def locate(seq, rows_per_pageROWS_PER_PAGE, frontFRONT_PAGES): 由工序序号推算物理页码, 页内行号 body_page (seq - 1) // rows_per_page 1 row_no (seq - 1) % rows_per_page 1 return body_page front, row_no print(locate(1)) # (2, 1) print(locate(13)) # (3, 1)参数只有两个ROWS_PER_PAGE 决定单页信息密度FRONT_PAGES 决定前置页偏移。改了字号或行距这两个值要重新实测否则明细行会被挤到下一页页内行号和实际打印位置就错位了。工单的 page_total 由(max(seq)-1)//ROWS_PER_PAGE 1 FRONT_PAGES 1得出最后那个 1 是签名页。3. 用 python-docx 生成带页码的检修工单3.1 环境准备与最小可运行骨架生成工单不需要重型模板引擎python-docx 加一个合并库就够。虚拟环境是为了避免和 DMS 服务端的依赖打架。python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install python-docx docxcompose最小骨架只做三件事建文档、写标题、存盘。确认这条链路通了再往里面加表格和页脚。from docx import Document from docx.shared import Pt doc Document() h doc.add_paragraph() run h.add_run(发动机电控系统检修工单) run.bold True run.font.size Pt(16) doc.save(wo_min.docx)add_paragraph()返回段落对象格式挂在 run 上而不是段落上这是 python-docx 最容易搞混的一点。字号用Pt(16)这类长度对象不要直接写数字。3.2 在页脚插入 PAGE 与 NUMPAGES 域python-docx 没有插入页码的 API页码在 Word 里是一个域field必须自己拼 XML。一个域由五段组成开始标记、域指令、分隔符、占位显示文本、结束标记。少写分隔符和占位文本WPS 或 LibreOffice 打开时页脚会显示空白。域指令输出内容典型用途PAGE当前页码页脚第 X 页NUMPAGES文档总页数页脚共 Y 页SECTIONPAGES本节总页数多个工单装订成册时STYLEREF指定样式段落的文本页眉回显车型或工单号from docx.oxml import OxmlElement from docx.oxml.ns import qn from docx.enum.text import WD_ALIGN_PARAGRAPH def add_field(paragraph, instr): 在段落末尾插入一个 Word 域instr 例如 PAGE 或 NUMPAGES run paragraph.add_run() begin OxmlElement(w:fldChar) begin.set(qn(w:fldCharType), begin) instr_el OxmlElement(w:instrText) instr_el.set(qn(xml:space), preserve) # 保留指令两侧空格否则域可能失效 instr_el.text f {instr} sep OxmlElement(w:fldChar) sep.set(qn(w:fldCharType), separate) placeholder OxmlElement(w:t) placeholder.text 1 # 未刷新域之前的占位数字 end OxmlElement(w:fldChar) end.set(qn(w:fldCharType), end) for el in (begin, instr_el, sep, placeholder, end): run._r.append(el) def build_footer(section): footer section.footer footer.is_linked_to_previous False # 断开与上一节的页脚继承 p footer.paragraphs[0] p.alignment WD_ALIGN_PARAGRAPH.CENTER p.add_run(第 ) add_field(p, PAGE) p.add_run( 页 / 共 ) add_field(p, NUMPAGES) p.add_run( 页)建好页脚之后还要让 Word 打开文档时自动刷新域否则打印出来可能停在占位值1。doc Document() build_footer(doc.sections[0]) # 告诉 Word 打开时更新所有域 settings doc.settings.element update OxmlElement(w:updateFields) update.set(qn(w:val), true) settings.append(update) doc.save(工单_20240612_A03_0007.docx)section.footer需要 python-docx 较新的版本才支持老版本只能自己操作 footer 部件的 XML。is_linked_to_previous False这一句在多节文档里不能省否则第二节的页脚会直接沿用第一节章节页脚改不动。域的数字由 Word 渲染时计算python-docx 自己不会求值所以脚本里读不到最终页码校验要放到后面第 5 章。3.3 把明细行灌进表格并控制每页行数表格是工单的主体用add_table建表后逐行填充。为了让分页稳定一次性写入固定行数不足的补空行这样每页 12 行才成立。def fill_items(doc, rows, rows_per_page12): 把明细行写入表格工单页数由 rows_per_page 控制 header [序号, 类别, 项目, 单位, 标准区间, 实测, 判定] table doc.add_table(rows1, colslen(header)) table.style Table Grid # 必须有边框否则打印后看不清格线 for i, text in enumerate(header): cell table.rows[0].cells[i] cell.text text cell.paragraphs[0].runs[0].bold True padded rows [None] * (-len(rows) % rows_per_page) # 补空行对齐整页 for r in padded: cells table.add_row().cells if r is None: continue cells[0].text str(r[seq]) cells[1].text r.get(item_type, 静态实测) cells[2].text r[name] cells[3].text r.get(unit, ) cells[4].text f{r.get(spec_min, )}-{r.get(spec_max, )} cells[5].text if r.get(measured) is None else str(r[measured]) cells[6].text r.get(verdict, 待复测)-len(rows) % rows_per_page是个取模补零的写法13 行会补 11 个空行凑成 24 行、正好两页。表格样式必须指定为带边框的样式否则 Word 默认无框线打出来就是一堆散字。实测值留空用而不是0和 2.2 节里 measured 允许 NULL 的约定保持一致。3.4 .doc 与 .docx 的取舍和格式转换老系统收 .doc 是常态但生成环节建议始终以 .docx 为母版最后再转一次。原因是 .doc 二进制格式对域的缓存处理和 .docx 不同直接生成 .doc 的工具链也不如 .docx 成熟。# 先出 docx 母版再转 doc 交付转换会对域求值并写入缓存文本 soffice --headless --convert-to doc --outdir out/ 工单_20240612_A03_0007.docx转换后务必用 Word 或 WPS 打开确认页脚显示的是第 2 页 / 共 3 页而不是第 1 页。LibreOffice 对 NUMPAGES 的处理依赖它能正确分页字体缺失导致行高变化时总页数可能和 Word 里不一致。生产环境的做法是母版留 .docx交付件按对方系统要求转 .doc同时把 PDF 一起归档PDF 的页数才是最终可核对的那份。4. 电控检修参数的填写规范与判定阈值4.1 传感器与执行器的参考区间工单里 spec_min 和 spec_max 不能由写脚本的人拍脑袋填应当从原厂维修手册或 DMS 参数库按发动机代码带出。下表是常见项目的参考区间只用于验证工单字段设计是否合理实际出单时要替换成对应车型的数据。项目单位参考区间测试条件冷却液温度传感器kΩ / Ω20℃ 约 2.0–3.0 kΩ80℃ 约 300–400 Ω断开插头测传感器端子进气温度传感器kΩ20℃ 约 2.0–3.0 kΩ与冷却液温度同温对比空气流量计热线式V怠速 0.8–1.4 V急加速峰值 3.5 V 以上数据流观测节气门位置传感器V怠速 0.5–1.0 V全开 4.0–4.8 V点火开关 ON不启动前氧传感器窄带V0.1–0.9 V 之间10 秒内跳变不少于 8 次闭环工况2500 r/min缸压bar10–14 bar各缸偏差不超过 10%节温器全开拔喷油器燃油压力kPa约 350 kPa无回油系统点火 ON 或怠速同一台发动机在不同温度下的阻值差好几倍所以工单必须记下测试条件只写一个数字等于没写。像节气门位置传感器 0.72 V这样的记录缺了点火 ON、节气门全闭这个前提复核人根本没法判断。4.2 数据流和波形怎么落到纸面工单数据流是连续量纸面工单放不下。可行做法是只截三段关键工况怠速稳定段、急加速段、断油回收段每段写一个特征值加一张波形截图编号。特征值从采集的 CSV 里算出来不要靠人眼读数。import csv from statistics import mean def summarize(path, key_window50): 从数据流 CSV 抽取稳定段特征值供工单实测值列使用 with open(path, newline, encodingutf-8) as f: rows list(csv.DictReader(f)) tail rows[-key_window:] # 取末尾稳定段避开启动时的抖动 o2 [float(r[o2_v]) for r in tail] return { rpm_avg: round(mean(float(r[rpm]) for r in tail), 1), map_avg: round(mean(float(r[map_kpa]) for r in tail), 1), o2_swings: sum(1 for i in range(1, len(o2)) if (o2[i] - 0.45) * (o2[i-1] - 0.45) 0), }key_window50在 10 Hz 采样下对应约 5 秒的稳定工况窗口取太短会被单次抖动带偏取太长会把加速段混进来。o2_swings统计的是氧电压穿过 0.45 V 中值的次数这个数和 4.1 表里10 秒 8 次的判据能直接对上。4.3 填写完整性与阈值一致性校验工单出单前跑一遍校验能拦掉大部分低级错误实测值缺失、超区间却判正常、故障码格式不对、工序序号断号。def check_row(row): errs [] if row.get(measured) is None: errs.append(fseq{row[seq]} 实测值缺失) else: lo, hi row.get(spec_min), row.get(spec_max) if lo is not None and hi is not None and not (lo row[measured] hi): if row.get(verdict) 正常: errs.append(fseq{row[seq]} 超出 {lo}-{hi} 却判定为正常) if row.get(item_type) DTC and not str(row.get(code, )).startswith(P): errs.append(fseq{row[seq]} 故障码格式异常) return errs判定的正常是人工填的实测值是机器读的两者矛盾时优先信实测值这条规则要在校验里写死。断号检查更简单把 seq 排序后逐个比对seq[i] ! i 1就报错。注意 spec_min 或 spec_max 为 None 时跳过区间判断有些定性项目本来就没有数值区间不能让校验把它们误判成错误。5. 检修工单的页码连续性校验与多份合并归档技巧5.1 确认页脚域真的写进去了域是 XML肉眼看不见出单前用 zipfile 直接读页脚部件检查有没有 PAGE 指令比打开 Word 一个个翻快得多。import re, zipfile def footer_has_page_field(path): 检查 docx 的页脚部件里是否存在 PAGE 域 with zipfile.ZipFile(path) as z: footers [n for n in z.namelist() if re.match(rword/footer\d*\.xml, n)] if not footers: return False return all(bPAGE in z.read(n) for n in footers) print(footer_has_page_field(工单_20240612_A03_0007.docx))注意all()而不是any()多节文档里如果只有第一节有页脚说明后面的节还在继承页码虽然能显示但不独立。返回 False 时先回去看 3.2 节里is_linked_to_previous有没有设。5.2 多份工单合并后重排页码一个工位一天出七八份工单装订成册时页码必须连续。docxcompose 能把多份文档顺序拼接但合并后每份子文档的页脚仍各自延续。from docx import Document from docxcompose.composer import Composer master Document(工单封面.docx) composer Composer(master) for p in [工单_A.docx, 工单_B.docx, 工单_C.docx]: composer.append(Document(p)) composer.save(当日工单合订本.docx)合并后要做两件事把每份子文档的页脚统一重建为 PAGE 域确保不使用 SECTIONPAGES再核对合订本总页数是否等于各份 page_total 之和。合并会引入分节符分节符会让 Word 把页面设置重新应用一遍如果各份工单的页边距不一致合订本里会冒出空白页总页数就对不上了。5.3 归档命名与打印前核对命名规则建议固定成VIN后6位_进厂日期_工单号_共X页.docxX 取主表 page_total这样在文件管理器里按名字排序就能看出哪份缺页。核对按三步走先看阅读器状态栏页数是否等于 page_total再用 5.1 的脚本批量扫一遍页脚域最后把 PDF 归档件的页数也数一遍——交付件是 PDF 时PDF 的页数才作准。装订成册那种场景把合订本的页脚换成第 X 页 / 共 Y 页之后打印前翻到中间任意一页看数字是否连续、有没有跳到下一页又跳回来一次就能发现分节符造成的空白页。本文还有配套的精品资源点击获取