mcpField
O
office-remediation

office-remediation

github.com/community-access文档处理429198 次安装今天更新
代码仓库

关于 office-remediation

为以编程方式修复 Microsoft Office 文档无障碍问题提供 API 参考与代码模式,涵盖 Word、Excel 和 PowerPoint。适合处理文档元数据、结构、替代文本及验证流程的开发者。

主要功能

  1. 01Word 文档修复模式
  2. 02Excel 工作簿修复模式
  3. 03PowerPoint 演示文稿修复模式
  4. 04PowerShell COM 自动化
  5. 05OOXML 直接修改与安全规则

适用场景

  1. 01补充文档标题和语言信息
  2. 02修复表格标题行与工作表名称
  3. 03为图片添加替代文本并检查幻灯片结构

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/community-access/accessibility-agents --skill office-remediation

安装后在 Claude Code 中输入/office-remediation确认已加载。

详细介绍

Office 无障碍修复模式技能

以编程方式修复 Microsoft Office 文档无障碍问题的 API 参考和代码模式。


python-docx 模式(Word .docx)

设置文档标题
from docx import Document
doc = Document("input.docx")
doc.core_properties.title = "Descriptive Title"
doc.save("output.docx")
设置文档语言
from docx import Document
from docx.oxml.ns import qn
from lxml import etree

doc = Document("input.docx")
styles_element = doc.styles.element
rPrDefault = styles_element.find(qn("w:docDefaults/w:rPrDefault/w:rPr"))
if rPrDefault is not None:
    lang = rPrDefault.find(qn("w:lang"))
    if lang is None:
        lang = etree.SubElement(rPrDefault, qn("w:lang"))
    lang.set(qn("w:val"), "en-US")
doc.save("output.docx")
设置表格标题行
from docx import Document
from docx.oxml.ns import qn
from lxml import etree

doc = Document("input.docx")
for table in doc.tables:
    first_row = table.rows[0]._tr
    trPr = first_row.get_or_add_trPr()
    existing = trPr.find(qn("w:tblHeader"))
    if existing is None:
        header_elem = etree.SubElement(trPr, qn("w:tblHeader"))
        header_elem.set(qn("w:val"), "true")
doc.save("output.docx")
为图像添加替代文本
from docx import Document
from docx.oxml.ns import qn

doc = Document("input.docx")
for rel in doc.part.rels.values():
    if "image" in rel.reltype:
        # Images are referenced via <wp:docPr> in the document XML
        # Alt text is the 'descr' attribute on the docPr element
        pass

# Direct XML approach for inline images:
body = doc.element.body
for docPr in body.iter(qn("wp:docPr")):
    if not docPr.get("descr"):
        docPr.set("descr", "TODO: Add alt text")
doc.save("output.docx")
修正标题级别
from docx import Document

HEADING_MAP = {
    "Heading 3": "Heading 2",  # Example: fix skipped level
}

doc = Document("input.docx")
for para in doc.paragraphs:
    if para.style.name in HEADING_MAP:
        para.style = doc.styles[HEADING_MAP[para.style.name]]
doc.save("output.docx")

openpyxl 模式(Excel .xlsx)

设置工作簿标题和作者
from openpyxl import load_workbook

wb = load_workbook("input.xlsx")
wb.properties.title = "Descriptive Title"
wb.properties.creator = "Author Name"
wb.save("output.xlsx")
设置打印标题行(重复标题行)
from openpyxl import load_workbook

wb = load_workbook("input.xlsx")
for ws in wb.worksheets:
    if ws.max_row > 1:
        ws.print_title_rows = "1:1"  # Repeat row 1 on every printed page
wb.save("output.xlsx")
检测通用工作表名称
GENERIC = {"Sheet", "Sheet1", "Sheet2", "Sheet3", "Tabelle1", "Feuil1"}

from openpyxl import load_workbook
wb = load_workbook("input.xlsx")
for ws in wb.worksheets:
    if ws.title in GENERIC:
        print(f"Generic sheet name: '{ws.title}' — rename to describe content")
检测合并单元格
from openpyxl import load_workbook

wb = load_workbook("input.xlsx")
for ws in wb.worksheets:
    if ws.merged_cells.ranges:
        for merged in ws.merged_cells.ranges:
            print(f"Sheet '{ws.title}': merged range {merged}")

python-pptx 模式(PowerPoint .pptx)

设置演示文稿标题
from pptx import Presentation

prs = Presentation("input.pptx")
prs.core_properties.title = "Descriptive Title"
prs.save("output.pptx")
检查是否缺少幻灯片标题
from pptx import Presentation

prs = Presentation("input.pptx")
for i, slide in enumerate(prs.slides, 1):
    title_shape = slide.shapes.title
    if title_shape is None:
        print(f"Slide {i}: No title placeholder")
    elif not title_shape.text.strip():
        print(f"Slide {i}: Empty title")
为图像设置替代文本
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE

prs = Presentation("input.pptx")
for i, slide in enumerate(prs.slides, 1):
    for shape in slide.shapes:
        if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
            if not getattr(shape, "_element").get("descr", ""):
                # Access via XML for older python-pptx versions
                shape._element.set("descr", "TODO: Add alt text")
prs.save("output.pptx")
检查阅读顺序
from pptx import Presentation
from lxml import etree

prs = Presentation("input.pptx")
for i, slide in enumerate(prs.slides, 1):
    shapes = [(s.left, s.top, s.name) for s in slide.shapes]
    # Visual order (top-to-bottom, left-to-right) vs. XML order
    visual = sorted(shapes, key=lambda s: (s[1], s[0]))
    xml_order = [s.name for s in slide.shapes]
    visual_order = [s[2] for s in visual]
    if xml_order != visual_order:
        print(f"Slide {i}: Reading order may differ from visual layout")

PowerShell COM 自动化(Windows + Office)

Word — 设置标题
$word = New-Object -ComObject Word.Application
$word.Visible = $false
$doc = $word.Documents.Open("C:\path\document.docx")
$doc.BuiltinDocumentProperties("Title").Value = "Accessible Title"
$doc.Save()
$doc.Close()
$word.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($word) | Out-Null
Excel — 设置标题和工作表名称
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$wb = $excel.Workbooks.Open("C:\path\spreadsheet.xlsx")
$wb.BuiltinDocumentProperties("Title").Value = "Accessible Title"
# Rename sheets (example)
# $wb.Sheets.Item(1).Name = "Revenue Data"
$wb.Save()
$wb.Close()
$excel.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel) | Out-Null
PowerPoint — 设置标题
$ppt = New-Object -ComObject PowerPoint.Application
$prs = $ppt.Presentations.Open("C:\path\presentation.pptx")
$prs.BuiltinDocumentProperties("Title").Value = "Accessible Title"
$prs.Save()
$prs.Close()
$ppt.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($ppt) | Out-Null

OOXML 直接操作(ZIP + XML)

对于没有 Python 或 Office 的环境,可以将文档作为 ZIP 存档直接操作:

提取并编辑 core.xml(标题/语言)
# Extract
mkdir -p extracted
unzip -o document.docx -d extracted

# Edit title in docProps/core.xml
sed -i 's|<dc:title/>|<dc:title>Accessible Title</dc:title>|' extracted/docProps/core.xml

# Repackage
cd extracted && zip -r ../document-fixed.docx . && cd ..
关键 OOXML 路径
属性文件XML 元素
标题docProps/core.xml<dc:title>
作者docProps/core.xml<dc:creator>
语言word/settings.xml<w:themeFontLang>
标题样式word/document.xml<w:pStyle w:val="Heading1">
替代文本word/document.xml<wp:docPr descr="...">
表格标题word/document.xml<w:tblHeader/>

安全规则

  1. 始终备份原始文件,然后再进行任何修改
  2. 切勿覆盖原始文件 — 使用 -fixed 后缀或单独的输出路径
  3. 修复后进行验证 — 建议使用 Microsoft Accessibility Checker 或重新审计
  4. COM 清理 — 使用 COM 自动化后,始终调用 ReleaseComObject 和 Quit()
  5. 编码 — OOXML 使用 UTF-8;如果 core.xml 中存在 BOM,请予以保留

评论

支持 Markdown