关于 xlsx
这项技能使用 openpyxl、pandas 等 Python 工具创建、编辑和分析 Excel 工作簿,适合处理电子表格的用户。它强调使用公式、重新计算与错误检查,以及编辑时保留工作簿功能。
主要功能
- 01创建和编辑格式化工作簿
- 02用 pandas 读写表格数据
- 03重新计算并扫描公式错误
- 04核验公式和预期值
- 05保留宏和工作簿功能
- 06用 MarkItDown查看工作表
适用场景
- 01构建由公式驱动的电子表格
- 02安全更新现有工作簿
- 03检查公式和缓存值
- 04将表格数据导出为 XLSX
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ k-dense-ai/ scientific-agent-skills --skill xlsx安装后在 Claude Code 中输入/xlsx确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtscripts/office/helpers/__init__.pypptx_chart.pypptx_slide.pypptx_theme.pyscripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsdopc-coreProperties.xsdopc-digSig.xsdopc-relationships.xsdscripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsddml-chartDrawing.xsddml-diagram.xsddml-lockedCanvas.xsddml-main.xsddml-picture.xsddml-spreadsheetDrawing.xsddml-wordprocessingDrawing.xsdpml.xsdshared-additionalCharacteristics.xsdshared-bibliography.xsdshared-commonSimpleTypes.xsdshared-customXmlDataProperties.xsdshared-customXmlSchemaProperties.xsdshared-documentPropertiesCustom.xsdshared-documentPropertiesExtended.xsdshared-documentPropertiesVariantTypes.xsdshared-math.xsdshared-relationshipReference.xsdsml.xsdvml-main.xsd详细介绍
XLSX 创建、编辑与分析
| 任务 | 方法 |
|---|---|
| 使用公式/格式进行创建或编辑 | openpyxl — 参见下方注意事项 |
| 批量导入或导出数据 | pandas(read_excel、to_excel) |
| 快速查看工作表 | markitdown file.xlsx — 每个工作表以 ## SheetName 表示,不含单元格坐标。对 .xlsm 和精确编辑请使用 openpyxl |
| 读取模型(公式和值) | 两次 load_workbook 调用 — 参见注意事项 |
不要假设已预装相关包。复用合适的环境,或使用
uv run --with openpyxl==3.1.5 python your_script.py。仅在需要时安装可选的表格读取器;MarkItDown 需要其xlsxextra。随附的工作流已使用 openpyxl 3.1.5 和 LibreOffice 26.2.4.2 验证;当前在线 LibreOffice 帮助文档描述的是 26.8。
下方脚本路径均相对于本技能的目录。
每份输出的要求
- 全文使用专业字体(Arial、Times New Roman),除非用户另有说明。
- 零公式错误。 只要
recalc.py报告errors_found,就绝不交付。如果你认为某个错误早于你存在,请证明它:用data_only=True加载原始文件并查看该单元格。你引入的错误和你继承的错误看起来完全一样。 - 使用公式,绝不用硬编码结果。 写
sheet['B10'] = '=SUM(B2:B9)',而不是 Python 计算出的总和。当输入变化时,工作表必须重新计算。 - 严格遵循用户的规格说明。 精确的标签页名称、精确的列标题,以及他们明确写出的公式。一个计算了别的东西的重新设计,无论多么优雅,都是失败的。
- 记录每项假设和硬编码数字,放在读者能看到的地方 — 单元格批注,或表格末尾的相邻单元格。存在真实来源时要引用它(
Source: Company 10-K, FY2024, Page 45, Revenue Note, [SEC EDGAR URL]);当数字来自用户时,要明确说明。 - 你创建供他人填写的工作簿需要一个简短图例,指明应编辑哪些单元格,并附一行示例行,展示预期格式的真实值。绝不要向你被要求编辑的文件添加这样的行。
- 编辑现有文件:完全匹配其约定。 它们优先于本处的每一条准则。先找到其指定的输入单元格 — 独特的字体颜色、填充或底纹会标记它们 — 除非用户要求更改公式,否则保留其公式。在副本上进行所请求的更改。
重新计算并验证
openpyxl 不会计算公式。通过它保存会移除工作表公式缓存;
此后 load_workbook(data_only=True) 对这些公式单元格返回 None,直到某个电子表格
引擎计算出它们为止。输入常量仍然保留。仅设置 fullCalcOnLoad 不会
生成缓存值。
python scripts/recalc.py output.xlsx 30 # optional timeout in seconds; default 30
python scripts/recalc.py --help
该辅助工具会在一个暂存副本上运行 LibreOffice 的 calculateAll(),使用临时配置文件,
禁用文档宏,并禁用链接文档更新。它会检查文件是否已被重写、原始公式锚点是否仍然存在,
以及公式是否具有缓存(空字符串结果也是有效的)。检查成功后,它会以原子方式替换原始路径。
请保留备份: LibreOffice 在导出期间可能会更改格式、嵌入对象、公式和外部链接。
这是一项计算兼容性检查,而非原生 Excel 认证或网络沙箱。
读取 JSON,而不只是退出代码:
status: success:未发现带类型的错误单元格。total_formulas统计的是公式单元格, 包括数组锚点,而非数组的每个输出单元格。status: errors_found:重新计算已完成,且文件已被替换,但其中包含 带类型的 Excel 错误。两种状态均以 0 退出。total_errors和error_summary报告错误; 每种类型最多列出 100 个位置,并带有可选的locations_truncated计数。- 带有
error键但没有status:转换或验证失败;原始文件未被 替换,命令以 1 退出。无效的 CLI 参数以 2 退出。请保留原始文件并 进行调查,而不要将其视为一次成功的重新计算。
一次无错误的扫描并不能证明结果正确或数组输出完整。 请独立
检查预期值、单位、总计、公式范围和每个预期的数组输出单元格。
比较相关样式、图表、链接和宏在操作前后的变化;在其预期应用中
打开或渲染工作簿,并检查列宽、数字格式、打印区域和图表。
office/validate.py 明确不执行任何 XLSX 架构验证;其退出代码不是
XLSX 有效性证书。
外部链接和受保护的功能
='[1]Returns Analysis'!$B$2 通过工作簿的外部引用列表引用另一个文件。
keep_links=True(openpyxl 的默认值)在支持的情况下保留外部链接数据;
它在保存时不会保留工作表公式的缓存结果。源文件不可用时,
在重新计算后可能会将先前缓存的结果变为错误。
该辅助工具在识别到直接引用、名称引用和数组引用缺少工作表
缓存时会拒绝它们。这是一项部分防护:传递性名称、图表、条件格式
和其他链接可能会逃过检测。--force 会绕过该防护并接受可能的损失;请
仅在一次性副本上使用。它不会提供缺失的源文件或刷新链接数据。
对于重要的外部链接、VBA/UDF、动态溢出、控件或其他 Excel 专属功能,
请使用兼容的 Excel 工作流并验证实际的目标引擎。如果请求的是静态值,
请从原始的缓存值加载中提取它们,并清楚地标注该转换。
选择能经受验证的公式
使用 openpyxl 编写的公式要用英文函数名和逗号,即使 Calc 的界面使用分号。原始规范之后新增的 OOXML 函数可能需要 _xlfn.;有些还额外使用 _xlws.。前缀并不保证引擎支持。
SUMIFS、INDEX、MATCH、IFERROR和SUMPRODUCT仍然是实用的可移植选择。- 按需为新函数添加前缀,例如
=_xlfn.TEXTJOIN(",",TRUE,A1:A3)。 在部署所用的引擎中验证确切的公式;不要根据拼写推断其受支持情况。 - 标量 XLOOKUP 和 XMATCH 在当前 LibreOffice 中可用。 两者均于 24.8 加入;
_xlfn.XLOOKUP(2,A1:A3,B1:B3)和_xlfn.XMATCH(2,A1:A3)已在 26.2.4.2 中测试。 XMATCH 返回位置;它不是溢出的数组函数。 SORT、FILTER、UNIQUE和SEQUENCE也自 LibreOffice 24.8 起存在,但数组 存储方式很重要。在测试的往返过程中,单独的=_xlfn.SEQUENCE(3,1,1,1)只产生了第一个值, 且没有报错。不要将无错误的单元格等同于完整的溢出。- 对于固定输出范围,openpyxl 支持
ArrayFormula;将其赋给该范围的 左上角单元格,并验证每一个输出。这并不保证 Excel 动态溢出会自动调整大小。当需要调整大小/溢出语义时,请使用原生 Excel。
from openpyxl import Workbook
from openpyxl.worksheet.formula import ArrayFormula
wb = Workbook()
ws = wb.active
ws["A1"] = ArrayFormula("A1:A3", "=_xlfn.SEQUENCE(3,1,1,1)")
wb.save("sequence.xlsx")
wb.close()
# Run recalc.py sequence.xlsx, then verify A1:A3 == [1, 2, 3].
openpyxl 注意事项
- 读取模型需要加载两次。
data_only=True产出缓存值,公式不复存在;默认值产出公式字符串,没有值。一次加载无法同时得到两者。 - 如果保存,
data_only=True具有破坏性。 该工作簿不再有公式,因此保存会将每一个公式永久替换为字面量。 - 对 openpyxl 刚写入的文件使用
data_only=True,公式单元格会返回None—— 先运行recalc.py。(结果为""的公式读回时也是None。) - 合并单元格:只写入左上角锚点单元格。 该范围内的其他每个单元格都是
MergedCell,其.value为只读。 .xlsm会丢失宏,除非向load_workbook传入keep_vba=True。这会保留 VBA 数据,但不是每一个 Excel 特性。在编辑特性丰富的工作簿之前,请清点形状、控件、绘图和其他嵌入对象;openpyxl 不会保留所有这些内容。保存一份可用的副本,并在保存和重新计算后比较这些对象。如果必需的对象无法在往返过程中保留,请改用兼容的 Excel 工作流,而不是交付一个被剥离的工作簿。- 跨工作表引用中的工作表名称要加引号:
='Assumptions Inputs'!$B$5。使用openpyxl.utils.cell.quote_sheetname(name)还可以转义撇号。 - 富文本如果其单元格级格式必须保留,加载时需要
rich_text=True。 - 模板需要
wb.template=True以及匹配的.xltx/.xltm扩展名;重命名普通工作簿是不够的。该辅助函数以AsTemplate=False加载模板以供编辑。 - 以
=开头的不受信任文本必须保持为文本:先赋值,然后将单元格的data_type = "s"。将带前导零的标识符保留为字符串,并将显式单位/日期与度量值分开。
财务模型
除非用户另有说明,或者现有文件已经采用了其他做法。
颜色: 硬编码输入和情景调节项使用蓝色文本(0,0,255)· 公式使用黑色 ·
指向其他工作表的链接使用绿色(0,128,0)· 指向其他文件的链接使用红色(255,0,0)·
关键假设和用户应填写的单元格使用黄色填充(255,255,0)。
数字: 货币使用 $#,##0,并在表头标明单位(Revenue ($mm))· 零显示为
-($#,##0;($#,##0);"-")· 负数放在括号中 ·
百分比使用 0.0%;(0.0%);"-",以小数形式存储(0.15 显示为 15.0%;存储 15 则显示
1500.0%)· 估值倍数使用 0.0"x" · 年份以文本形式表示("2024",绝不要写成 2,024)。
结构: 每个假设都放在各自带标签的单元格中,并由使用它的公式引用
(=B5*(1+$B$6),绝不要写成 =B5*1.05)· 公式在每个预测期间保持一致,因为某一行中间
单独被修改的单元格是最常见的隐性错误 · 对可能为零的分母做保护。
完整验证示例
这个小型的合成示例使用 LibreOffice 26.2.4.2 重新计算。这些浓度
仅用于说明,并非实验测量值。重新计算后请保留公式工作簿;
不要保存 data_only=True 的验证加载结果。
from openpyxl import Workbook, load_workbook
from openpyxl.comments import Comment
from openpyxl.styles import Font
wb = Workbook()
ws = wb.active
ws.title = "Dilution"
ws.append(["Sample", "Stock (mM)", "Stock volume (uL)", "Final volume (uL)", "Final (mM)"])
ws.append(["Example A", 10, 20, 100, "=B2*C2/D2"])
ws["A4"] = "Edit A2:D2; E2 calculates concentration. Synthetic example inputs."
ws["B2"].comment = Comment("Illustrative stock concentration; replace with measured input.", "Source")
for row in ws.iter_rows():
for cell in row:
cell.font = Font(name="Arial", size=11)
for cell in ws[1]:
cell.font = Font(name="Arial", size=11, bold=True)
for col in "ABCDE":
ws.column_dimensions[col].width = 22
ws["E2"].number_format = '0.00'
ws.freeze_panes = "A2"
wb.save("dilution.xlsx")
wb.close()
# Run: python scripts/recalc.py dilution.xlsx
# Then in a separate verification step:
# cached = load_workbook("dilution.xlsx", data_only=True)
# assert cached["Dilution"]["E2"].value == 2
# cached.close()
对于仅导出表格的新文件,pandas 支持
df.to_excel("table.xlsx", sheet_name="Data", index=False, engine="openpyxl")。
pd.read_excel(path, sheet_name=None, engine="openpyxl") 会将所有工作表读入一个字典;
请审慎选择 dtype/converters 以及缺失值处理方式。DataFrame 的往返转换
并不是针对带样式模型、公式或嵌入式对象的保留工作流。
依赖项与已查阅文档
重新计算需要 openpyxl 以及单独安装的 LibreOffice(soffice 位于 PATH 中)。
共享的 OOXML 实用程序还使用 defusedxml 和 lxml。可选的 pandas 用于处理表格数据;
MarkItDown 需要 markitdown[xlsx] 才能进行 XLSX 转换。不要根据
MarkItDown 的 XLSX 转换器就假定其支持 .xlsm:其文档所述的源分派仅识别 .xlsx/XLSX MIME。
工作簿处理不需要 API 凭据或远程服务调用。
- openpyxl 加载、保留和模板
- openpyxl 公式和 ArrayFormula
- pandas read_excel 和 to_excel
- MarkItDown XLSX 转换器
- LibreOffice XLOOKUP、XMATCH 和 SEQUENCE
- LibreOffice 文档加载属性 和 calculateAll
本技能源自 Anthropic。此处改编时加入了仓库元数据和额外的保留指南;条款见 LICENSE.txt。