银行投标响应文档标准化工具(v1.0)。基于 Word 样式体系(Heading 1‑5 + Normal),兼容 GB/T 9704公文格式;统一入口 standardize.py,提供 7 条流水线(全部/修复/重新编号/自动编号/审阅/转换为 Markdown/验证)。
银行投标响应文档标准化工具。基于 Word 内置样式体系(Heading 1-5 + Normal),把任意 docx 一键整理为符合银行投标规范的成品稿。
renumber 一键转阿拉伯层级all 子命令一气呵成——renumber → fix → auto-numberdry-run 预览改动字段值技能名称vkey-bid-standardizer行业银行配置文件vkey_bid_standardizer/profiles/standard.json流水线数7(all / fix / renumber / auto-number / review / convert-md / validate-patterns)测试pytest tests/ — 61 个 case依赖Python 3.7+ / python-docx 1.x / pytest适用文档技术应答、商务标书、实施方案、应答偏离表、投标方案
为统一银行业投标响应文档(技术应答、商务标书、实施方案等)的格式规范, 满足银行招标方评标专家对版面与编号的合规审查要求,提升标书质量与中标率。
本规范遵循的基本原则(金融投标四原则):
序号标准编号标准名称适用要点1GB/T 9704—2012党政机关公文格式版心/页边距/字号/行距2GB/T 15834—2011标点符号用法标点符号全角半角3GB/T 15835—2011出版物上数字用法数字/百分号/单位4GB/T 9851—2008印刷字体分类字体别名识别5JR/T 0067—2017银行信息安全风险管理指引银行业信息安全引用6JR/T 0071—2014金融行业网络安全等级保护实施指引银行业网络安全引用
术语定义样式(Style)Word 中预设的格式集合标题样式Word 内置 Heading 1-9,标识文档层次正文样式菜单栏显示为"正文"的 Normal 样式行距段内行与行的垂直距离(倍数或固定值)段前/段后段落上方/下方的空白距离首行缩进段落首行相对左页边距的内缩多级列表Word 的多级自动编号功能(绑定 Heading 样式)段级覆盖段落自身 pPr(spacing/ind/jc)覆盖样式定义
文档采用五级章节结构,编号 统一带点:
层级编号格式样式示例一级章节1.Heading 11. 概述二级章节1.1Heading 21.1 适用范围三级章节1.1.1Heading 31.1.1 子项说明四级章节1.1.1.1Heading 41.1.1.1 详细说明五级章节1.1.1.1.1Heading 51.1.1.1.1 极详细
禁止:使用 一、 (一) 1 概述(无点)等其他格式。
技能支持 12 种常见手动编号形式( 一、、 (一)、 1.1、第 X 章、附录 X 等)→ 跑 standardize.py renumber 自动转阿拉伯层级。详见 附录 B。
边距标准值允许偏差上3.7 厘米±0.1 厘米下3.5 厘米±0.1 厘米左2.8 厘米±0.1 厘米右2.6 厘米±0.1 厘米
元素西文字体中文字体适用标题Times New Roman黑体标题 1-5正文FangSong仿宋Normal 段落表头Times New Roman黑体表格首行表内FangSong仿宋表格数据
元素字号磅数标识正文四号14ptNormal一级标题小二号18ptHeading 1二级标题三号16ptHeading 2三级标题小三号15ptHeading 3四级标题四号14ptHeading 4五级标题五号10.5ptHeading 5表格表头五号10.5pt—表格内容五号10.5pt—页脚五号10.5pt—
#000000)元素类型值正文固定值20 磅标题 1-5倍数1.25 倍
元素段前段后一级标题16 磅0 磅二级标题14 磅0 磅三级标题12 磅0 磅四级标题10 磅0 磅五级标题8 磅0 磅正文0 磅0 磅
OOXML w:ind 字段单位(必须严格区分,否则 Word 显示与渲染不一致):
字段单位2 字符示例说明w:firstLine1/20 pt(twips)56028pt = 560 twips;用于渲染w:firstLineChars1/100 字符2002 字符必须写 200,不是 2;用于对话框"度量值"显示w:left1/20 pt(twips)0段落左缩进w:leftChars1/100 字符0段落左缩进(字符单位)w:hanging / w:hangingChars同上—悬挂缩进
常见陷阱:python-docx 设
Pt(22.4)时 只写w:firstLine为 twips 值, 不写w:firstLineChars;Word 对话框"度量值"读firstLineChars显示为字符数,缺省时显示 0/1 字符。apply_paragraph_format必须同时写两字段并保持换算一致(firstLineChars = first_line_chars × 100)。
元素字体字号对齐表头黑体10.5pt居中表内仿宋10.5pt左对齐
边框:外框 1.5 磅、内框 0.5 磅、黑色 #000000
表头底纹:浅灰 #D9D9D9(仅首行)
列宽:自动列宽,按内容比例分配
w:tc > w:p 的段级 w:pPr 强制写入 w:ind,阻断样式继承链:xml
<w:pPr>
<w:ind w:firstLine="0" w:firstLineChars="0"/>
</w:pPr>
陷阱:仅
del现有w:firstLine属性无法阻断"无 w:ind 元素"的段落(会继承 Normal 样式)。 必须get_or_add_pPr()+get_or_add_w:ind()显式构造——对应pipeline.py::_fix_tables中"强制段级 firstLine=0"逻辑。
金融投标页脚 默认居中页码,可按需扩展为「项目编号 + 页码」或「招标编号 + 页码 + 总页数」。
属性标准值字体仿宋 10.5 磅(五号)对齐居中位置页底起始页码1格式页码(默认)/ 项目编号 - 页码(可配)
模板与
standard.json::footer.text字段联动。如需项目编号-页码格式,编辑footer.text为{project_code} - {page}(v1.0 占位符占位,v1.1 将完整支持)。
v1.0 唯一 CLI 入口是顶层 standardize.py:
bash
# 全流水线(推荐)
python standardize.py all input.docx -o output.docx
# 单步
python standardize.py fix input.docx
python standardize.py renumber input.docx
python standardize.py auto-number input.docx
python standardize.py review input.docx
python standardize.py convert-md input.md
python standardize.py validate-patterns
通用 flag: --profile standard(默认; bid 是别名)/ --dry-run / --backup / -v / -o
#名称命令作用1全流水线standardize.py allrenumber → fix → auto-number 三步串行2修复样式standardize.py fix应用规范 + 清段级/run 级覆盖3重编号standardize.py renumber手动编号(一、/(一)/1.1)→ 阿拉伯层级4自动编号standardize.py auto-numberHeading 1-5 绑 Word 多级列表5审查standardize.py reviewJSON 审计报告(段级覆盖、issues)6MD→docxstandardize.py convert-md从 Markdown 源生成7模式校验standardize.py validate-patterns22 条模式样本测试
场景一:技术应答文件标准化
bash
python standardize.py all 银行核心系统技术应答_v1.0.docx -o 银行核心系统技术应答_v1.0_标准化.docx
跑完 3 步:手动编号(一、/(一)/1.1)→ 阿拉伯层级 → 套用 GB/T 9704 公文样式 → 绑 Word 多级列表。
场景二:先 dry-run 看会改什么,不写文件
bash
python standardize.py all 银行核心系统技术应答_v1.0.docx --dry-run
只输出计划(如 renumber (62) | fix (1756) | auto-number (5)),不写任何文件——评标前安全预览改动。
场景三:投标合规审查
bash
python standardize.py review 银行核心系统技术应答_v1.0_标准化.docx
输出 JSON 报告: overrides 全为 0 + issues: [] 即符合公文规范。
场景四:备份原文件再修复(防止覆盖)
bash
python standardize.py all 银行核心系统技术应答_v1.0.docx -o 银行核心系统技术应答_v1.0_标准化.docx --backup
自动把原文件备份为 银行核心系统技术应答_v1.0.docx.bak。
场景五:从 Markdown 起草金融投标稿
bash
python standardize.py convert-md 银行核心系统技术应答.md -o 银行核心系统技术应答_v1.0.docx
按附录 C 的 Markdown 规范写,5 级章节 + 表格 + 段落直接转成标准 docx。
维度通过标准样式使用标题用 Heading 1-5,正文用 Normal字体标题黑体,正文仿宋,色 #000000间距行距 1.25 倍 / 固定 20 磅;段前段后符合规范表格表头黑体 10.5pt 灰底,表内仿宋 10.5pt页脚仅页码数字编号标题具备 1./1.1/1.1.1 层级段级覆盖所有 Heading/Normal 段落无 pPr 覆盖( overrides 全为 0)
issues 空 + overrides 全 0standardize.py fix 修复规范通过 vkey_bid_standardizer/profiles/standard.json 集中管理,含 9 个节:
节作用金融投标关注点page页面边距GB/T 9704 版心 156×225mmbody正文样式三号仿宋 + 28 磅固定行距headings5 级标题样式黑体 + 1.5 倍行距tables表格样式 + 边框灰底表头 + 1.5/0.5 磅框footer页脚配置居中页码 / 项目编号-页码numberingWord 多级列表1./1.1/1.1.1 层级patterns22 条手动编号识别中文 / 第X章 / 附录color颜色( #000000)黑白打印兼容metadata(v1.1)项目元数据招标编号 / 项目名称 / 投标类型
bid.json 是 standard.json 的别名(找不到时自动 fallback)。 调整规范 改 standard.json 而非源代码。
模板路径用途标书空白模板templates/bid_blank.mdMarkdown 金融投标起草( convert-md 输入源)
pip install python-docx)组件最低版本备注Python3.7+推荐 3.10+python-docx1.0+pip install python-docxpytest7.0+仅运行测试时需要Microsoft Word2016+需支持多级列表WPS Office2019+兼容多级列表
安装依赖:
bash
pip install python-docx pytest
如果客户 docx 用了 非标准编号形式(不在 12 种内置模式里), renumber 会输出 warning:
text
[Heading 3] 未识别编号: §3.1 系统架构
Step 1:分析样本
从 docx 复制一段未识别的标题,如 §3.1 系统架构。
Step 2:写正则,加到 standard.json::patterns::h3
json
{
"name": "section_sign",
"pattern": "^§(\\d+)\\.(\\d+)\\s+(.*)$"
}
pattern 规则: 第一个捕获组必须是编号。
Step 3:标注解析模式
如果编号含中文数字,加 "cn_to_int": true:
json
{
"name": "part_cn",
"pattern": "^第([一二三四五六七八九十百]+)部分\\s+(.*)$",
"cn_to_int": true
}
或混合(中/阿): "mixed_cn_int": true。
Step 4:模式顺序
更具体的模式放前面(避免被通用模式抢先匹配)。例如 wps_label 必须在 single_arabic 之前。
Step 5:验证
bash
python standardize.py validate-patterns
如样本测试不通过,输出会指明问题。
字段必填说明name✓模式名(英文,warning 输出用)pattern✓正则, 第一个捕获组必须是编号cn_to_int第一组是中文数字(用 parse_cn_num)mixed_cn_int第一组是混合数字( 1 或 三)
版本日期修订人内容V1.02026-06-03vkey-bid-standardizer首次独立发布;统一入口 standardize.py;7 条流水线;22 条编号模式;61 个 pytest case;单一真相源 standard.jsonV1.0.12026-06-04vkey-bid-standardizer修复 3 项 OOXML 规范偏差:① firstLineChars 单位误用(改 ×100);② firstLine 增补 twips 兜底(28pt = 560);③ 表格段落强制段级 firstLine=0 阻断 Normal 样式继承
vkey_bid_standardizer/profiles/standard.json 是规范的 唯一真相源。
完整结构(请直接读源文件):
bash
# 查看完整 JSON
cat vkey_bid_standardizer/profiles/standard.json
# 关键字段速查
python -c "from vkey_bid_standardizer import load_profile; p = load_profile('standard'); print(p['headings'])"
不要在 SKILL.md 里复制完整 JSON——配置可能演化,文档与代码脱钩后维护成本高。
standard.json::patterns 共 22 条正则规则,覆盖 12 种 常见多级编号形式。
模式名层级形式示例chinese_punctH1一、 二、``一、概述``chapter_cnH1第X章(中文)第十章 总则``chapter_arabicH1第N章第3章 术语``appendix_cnH1附录X附录A 数据``appendix_alphaH1Appendix XAppendix A Data``single_arabicH1-H51. 2.``1. 总则``circle_numH1①②③① 条款``cn_paren_bothH2(一) 或 (一)``(一)适用范围``section_cnH2第X节第一节 概述``dot_arabicH21.1``1.1 范围``wps_labelH2/H31. 标题 1``1. 标题 1``arabic_parenH3-H5(1) 或 (1)``(1)数据采集``article_cnH3第X条第一条 范围``dot_tripleH31.1.1``1.1.1 概述``dot_quadH41.1.1.1``1.1.1.1 详细``dot_quintH51.1.1.1.1``1.1.1.1.1 极详细
模式顺序很重要——更具体的模式放前面(避免被通用模式抢先匹配)。
失败降级:未匹配段落原样保留 + warning。
正则源在
standard.json::patterns, 不要在 SKILL.md 里复制正则——配置可能演化。
适用于 standardize.py convert-md 流水线的 Markdown 源文件。
约定:
# 文档标题 仅用于 首行大标题(居中加粗、黑体 18pt),独立成段,不进入目录## 1. 章节名 才是正文章节起点(对应 Heading 1)Markdown 语法Word 样式# 文档标题Normal 段落(居中加粗,黑体 18pt)## 1. 章节名Heading 1### 1.1 子章节Heading 2#### 1.1.1 三级Heading 3##### 1.1.1.1 四级子项Heading 4(独立成行)###### 1.1.1.1.1 五级子项Heading 5(独立成行)| 表头 |表格(1.5pt 外框 + 0.5pt 内框)
要求:标题独立成行 / 表格用标准 Markdown / 不使用代码块 / 列表项末尾加句号。