auto: sync OpenClaw config 2026-09-17 04:13

This commit is contained in:
2026-09-17 04:13:36 +08:00
parent f6383f5725
commit 376fde448b
27 changed files with 899 additions and 3 deletions
@@ -0,0 +1,52 @@
---
name: fill-official-forms
description: 填写工伤认定/申报审批等官方表格:从材料取证据、只填可核实项、标注缺失并导出 PDF 校验。
---
# 填写官方表格(申报/审批类)
## 适用
用户给出空白表格(.doc/.docx/.xls/.xlsx+ 佐证材料(认定书、病历、证明、截图),要求"帮我填好",
并允许就缺失信息向你提问。
## 步骤
1. **清点两个方向的内容**:列出表格文件与材料文件(`ls -la` / `find`),逐份判断是空白模板、部分已填、还是参考材料。
完成标准:能逐份说出它的用途(必填表 / 模板 / 佐证)。
2. **实测工具链,别信依赖清单**`which soffice pandoc tesseract``python3 -c "import docx, openpyxl"`
缺什么补什么:`sudo apt-get install -y --no-install-recommends libreoffice-calc libreoffice-writer`
`pip3 install --break-system-packages python-docx openpyxl xlrd`
已安装技能文档里的"已安装"表格可能与实际不符,一律以实测为准。
完成标准:`soffice` 可执行,且所需 Python 库都能 import。
3. **提取材料事实**:文字层 PDF 用 `pdftotext -layout`.docx 用 python-docx.xls 用 xlrd;图片/扫描件用
`tesseract`。命令、格式转换与 OCR 失败时的重试写法见 `references/legacy-office-and-ocr.md`
完成标准:每条要填的事实都能指到出处(哪个文件、哪一行/哪一区域)。
4. **先建字段映射,再动手填**:左列=表格字段(定位到单元格坐标或段落/表格序号),右列=取值 + 出处。
取不到出处的字段一律不猜。
5. **回填**Excel 用 openpyxlWord 用 python-docx(写法见 `references/legacy-office-and-ocr.md`)。
- 缺失项写「待补充」并用醒目字体(如橙色加粗)标出,不要留空——留空会被当成漏填。
- 要求本人手写/签名的字段(表格若写明"亲笔书写,不得代写、打印")**不得代填**,在交付说明里点名。
- 只填有据可查的信息:单位名称、日期、经过一律取自材料,不推断、不润色、不补全。
6. **校验再交付**:读回文件确认值落在正确字段(openpyxl / python-docx 重读);再
`soffice --headless --convert-to pdf` 导出预览,用 `pdftotext` 抽查关键字段是否出现在预期位置。
完成标准:抽查字段全部正确,或已修正后复验通过。
7. **交付结构**:原始文件保持不动;填写件放子目录(如 `已填写/`),另附 `预览PDF/``原始模板/`
再写一份说明文件,内容为 ① 已填了什么 ② 逐字段待补清单(指明补在哪个字段)③ 针对性疑问
④ 时限提醒。完成标准:用户不打开表格就知道要补什么、补到哪一格。
## 决策点与坑
- **管辖先确认**:表格的颁发地/受理地若与材料显示的主管地不一致(例如参保证明显示参保地在 A 市,
而用户下载的是 B 市的表格),先请用户确认受理地再填,不要默认手上这套表就是对的。
- **别用打印缩放"修"页数**:给工作表设 `fitToWidth/fitToHeight` 不会减少 PDF 页数,反而改动原表版式;
原始 .xls 本来就跨多页导出属正常,保持原样。
- 合并单元格只需写一个代表格:openpyxl 写合并区左上角,python-docx 里同一合并区的 cells 返回同一对象。
- 材料日期互相对不上时(如病历写"初诊"日期晚于 MRI 日期、正文又写"复诊"),把它列为疑问请用户澄清,
不要自行选一个填进去。
@@ -0,0 +1,98 @@
# 旧版 Office 文件与 OCR 参考
配合 `fill-official-forms` 第 3、5 步使用。以下命令均为实测可用的写法。
## 读取
```bash
# 文字层 PDF:优先用 -layout,保留表格式对齐
pdftotext -layout "证明.pdf" -
# .docx 正文 + 表格
python3 -c "
from docx import Document
d=Document('模板.docx')
for p in d.paragraphs:
if p.text.strip(): print(p.text)
for ti,t in enumerate(d.tables):
print('table',ti,len(t.rows),'x',len(t.columns))
for ri,r in enumerate(t.rows):
print(' r',ri,[c.text[:30].replace(chr(10),'/') for c in r.cells])
"
# 旧版 .xlsopenpyxl 读不了,用 xlrd(含合并单元格)
python3 -c "
import xlrd
wb=xlrd.open_workbook('表.xls', formatting_info=True)
for sh in wb.sheets():
print(sh.name, sh.nrows, sh.ncols, sh.merged_cells)
for r in range(sh.nrows):
print(r, ' | '.join(str(sh.cell_value(r,c)).strip() for c in range(sh.ncols)))
"
```
`pypdf``extract_text()` 对多列表格会把字段顺序打乱(实测:参保证明一行里的险种、单位、缴费额错位),
需要按列对齐时改用 `pdftotext -layout`
## 旧版 .doc / 无法直接解析的文件:先转新格式
```bash
soffice --headless --convert-to docx --outdir /tmp/conv "旧模板.doc"
soffice --headless --convert-to xlsx --outdir /tmp/conv "旧表格.xls"
```
转完再按上面的方式读;.doc 直接当二进制解 UTF-16 只能捞到零散字符串,不可靠。
## 回填写法
```python
# Excel:合并单元格只写左上角
import openpyxl
from openpyxl.styles import Alignment, Font
c = ws["C5"]; c.value = "取值"
c.alignment = Alignment(horizontal="left", vertical="center", wrap_text=True)
c.font = Font(color="FFC000", bold=True) # 待补项用橙色加粗标出
# Word:写入第一段 run,清掉多余 run,避免残留占位文字
def set_cell(cell, text):
p = cell.paragraphs[0]
if p.runs:
p.runs[0].text = text
for r in p.runs[1:]: r.text = ""
else:
p.add_run(text)
for extra in cell.paragraphs[1:]:
for r in extra.runs: r.text = ""
```
合并单元格在同一合并区里的多个 `cells` 是同一个对象,写一次即可;但跨行拆分出来的格子要按行分别写。
## 导出校验
```bash
soffice --headless --convert-to pdf --outdir 预览PDF *.xlsx *.docx
pdfinfo "预览PDF/xx.pdf" | grep Pages
pdftotext -f 1 -l 1 "预览PDF/xx.pdf" - | head -40 # 抽查关键字段落在正确位置
```
注意:给工作表设 `fitToWidth=1 / fitToHeight=0` **不会**减少 PDF 页数(实测设置前后页数不变),
不要再试图用打印缩放"整理"页数,也不要因此改动原表版式。
## OCR(图片 / 扫描件)
```bash
tesseract 图片.jpg - -l chi_sim+eng --psm 6 # 常规截图/竖版文档
```
- 截图类(考勤、列表)用 `--psm 6` 通常可直接读出。
- **地图类图片实测无输出**:直接对地图截图 OCR 得到空白。可行的重试是先放大再识别:
```bash
python3 -c "
from PIL import Image
im=Image.open('路线图.jpg'); im=im.convert('L').resize((im.width*3, im.height*3), Image.LANCZOS)
im.save('/tmp/up.png')"
tesseract /tmp/up.png - -l chi_sim+eng --psm 11
```
放大 3 倍 + `--psm 11` 后能读出部分地名,但结果零散、含大量乱码——**只用于定位线索,不能作为填报依据**。
地图/路线内容仍需向用户确认。
- 输出重定向到文件比管道到 stdout 更稳,便于反复查看。