mcpField
L
libreoffice-calc

libreoffice-calc

github.com/dfk1352文档处理7116 次安装3 天前更新
代码仓库

关于 libreoffice-calc

libreoffice-calc 是通过 UNO 驱动 LibreOffice Calc 电子表格操作的技能,面向需要用 Python 处理表格的用户。它提供会话式编辑、结构化目标和可批量应用的操作补丁。

主要功能

  1. 01读取和写入单元格及区域
  2. 02格式化并设置数据验证
  3. 03创建、更新和删除图表
  4. 04管理工作表与命名区域
  5. 05通过补丁批量应用操作
  6. 06导出文件并生成区域快照

适用场景

  1. 01编辑并格式化现有电子表格
  2. 02为表格数据创建图表
  3. 03批量更新工作簿内容
  4. 04导出表格或检查布局快照

安装

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

$npx skills add https://github.com/dfk1352/libreoffice-skills --skill libreoffice-calc

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
troubleshooting.md
scripts/
colors.py
constants.py
exceptions.py
patch_base.py
session.py
uno_bridge.py
scripts/calc/
__init__.py
core.py
exceptions.py
patch.py
session.py
snapshot.py
targets.py

详细介绍

LibreOffice Calc

使用捆绑的 calc 模块处理由 UNO 支持的 Calc 电子表格。 所有路径都必须是绝对路径。捆绑模块位于此技能目录下的 scripts/ 中,因此请设置 PYTHONPATH=<skill_base_dir>/scripts。 如果出现设置或运行时问题,请查阅 references/troubleshooting.md。

API 接口

# Non-session utilities
create_spreadsheet(path, source=None)              # source: path to .json or .xml file to import
export_spreadsheet(path, output_path, export_format)   # formats: "pdf", "xlsx", "csv"
snapshot_area(doc_path, output_path, sheet="Sheet1", row=0, col=0, width=None, height=None, dpi=150)

# Session (primary editing API)
CalcSession(path) -> context manager

CalcSession methods:
  read_cell(target: CalcTarget) -> dict[str, object]
  write_cell(target: CalcTarget, value, value_type="auto")
  read_range(target: CalcTarget) -> list[list[dict[str, object]]]
  write_range(target: CalcTarget, data)
  format_range(target: CalcTarget, formatting: CellFormatting)
  list_sheets() -> list[dict[str, object]]
  add_sheet(name, index=None)
  rename_sheet(target: CalcTarget, new_name)
  delete_sheet(target: CalcTarget)
  define_named_range(name, target: CalcTarget)
  get_named_range(target: CalcTarget) -> dict[str, object]
  delete_named_range(target: CalcTarget)
  set_validation(target: CalcTarget, rule: ValidationRule)
  clear_validation(target: CalcTarget)
  create_chart(target: CalcTarget, spec: ChartSpec)
  update_chart(target: CalcTarget, spec: ChartSpec)
  delete_chart(target: CalcTarget)
  recalculate()
  patch(patch_text, mode="atomic") -> PatchApplyResult
  export(output_path, export_format)
  reset()
  close(save=True)

# Standalone patch utility
patch(path, patch_text, mode="atomic") -> PatchApplyResult

结构化目标:CalcTarget

from calc import CalcTarget

CalcTarget(
    kind="cell" | "range" | "sheet" | "named_range" | "chart",
    sheet=None,
    sheet_index=None,
    row=None,
    col=None,
    end_row=None,
    end_col=None,
    name=None,
    index=None,
)
目标类型
类型支持的字段用途
cellsheet 或 sheet_index、row、col读取或写入一个单元格
rangesheet 或 sheet_index、row、col、end_row、end_col读取、写入、设置格式、验证或为矩形区域创建图表
sheetsheet 或 sheet_index重命名或删除一个工作表
named_rangename检查或删除一个命名区域
chartsheet 或 sheet_index,以及 name 或 index更新或删除一个图表
解析规则
  • 坐标从 0 开始,且必须为非负数。
  • sheet 和 sheet_index 不能同时使用。
  • name 和 index 不能同时使用。
  • 区域目标必须满足 end_row >= row 且 end_col >= col。
  • 图表目标必须指定一个工作表和一个图表选择器。
  • Calc 不会自动将单单元格区域转换为单元格目标;请明确保留这两种类型。

单元格读取结果

read_cell() 和 read_range() 返回形状相同的单元格字典:

{
    "value": 100.0,
    "formula": None,
    "error": None,
    "type": "number",
    "raw": 100.0,
}

空单元格返回 type="empty",且 value=None:

{"value": None, "formula": None, "error": None, "type": "empty", "raw": None}

公式单元格使用 type="formula";当 Calc 报告公式错误时,会填充 error,并将 value 设为 None。

布尔值(True/False)以数值 1.0/0.0 存储。读取用 Python 布尔值写入的单元格时,返回的是 type="number",且 value=1.0 或 value=0.0,而不是文本字符串。

格式设置载荷:CellFormatting

from calc import CellFormatting

CellFormatting(
    bold=None,
    italic=None,
    font_name=None,
    font_size=None,
    color=None,          # named color or integer
    number_format=None,  # "currency" | "percentage" | "date" | "time"
)

说明:

  • 必须至少设置一个格式字段。
  • color 接受命名颜色或 0xRRGGBB 整数。
  • format_range() 既适用于 cell 目标,也适用于矩形 range 目标。

验证载荷:ValidationRule

from calc import ValidationRule

ValidationRule(
    type="whole",
    condition="between",
    value1=1,
    value2=10,
    show_error=True,
    error_message="Enter a value from 1 to 10.",
    show_input=True,
    input_title="Allowed values",
    input_message="Only integers from 1 to 10 are valid.",
    ignore_blank=True,
    error_style=0,
)

支持的 type 值:

  • any
  • whole
  • decimal
  • date
  • time
  • text_length
  • list

支持的 condition 值:

  • between
  • not_between
  • equal
  • not_equal
  • greater_than
  • less_than
  • greater_or_equal
  • less_or_equal

图表载荷:ChartSpec

from calc import CalcTarget, ChartSpec

ChartSpec(
    chart_type="line",
    data_range=CalcTarget(
        kind="range",
        sheet="Data",
        row=0,
        col=0,
        end_row=5,
        end_col=1,
    ),
    anchor_row=7,
    anchor_col=0,
    width=10000,
    height=7000,
    title="Revenue Trend",
)

说明:

  • chart_type 必须为 bar、line、pie 或 scatter 之一。
  • width 和 height 使用 Calc 图表矩形单位(与打包 API 已接受的单位相同)。
  • 创建图表时以工作表为目标;更新或删除图表时以图表为目标。

补丁 DSL

使用 patch() 或 session.patch() 按顺序应用电子表格操作。

[operation]
type = write_range
target.kind = range
target.sheet = Revenue Data
target.row = 0
target.col = 0
target.end_row = 2
target.end_col = 1
data <<JSON
[["Label", "Value"], ["Revenue", 100], ["Cost", 80]]
JSON

[operation]
type = format_range
target.kind = range
target.sheet = Revenue Data
target.row = 1
target.col = 1
target.end_row = 2
target.end_col = 1
format.number_format = currency
format.bold = true

[operation]
type = create_chart
target.kind = sheet
target.sheet = Revenue Data
chart.chart_type = line
chart.data_range.kind = range
chart.data_range.sheet = Revenue Data
chart.data_range.row = 0
chart.data_range.col = 0
chart.data_range.end_row = 2
chart.data_range.end_col = 1
chart.anchor_row = 5
chart.anchor_col = 0
chart.width = 9000
chart.height = 6000
chart.title = Revenue Trend
支持的操作类型
  • write_cell
  • write_range
  • format_range
  • add_sheet
  • rename_sheet
  • delete_sheet
  • define_named_range
  • delete_named_range
  • set_validation
  • clear_validation
  • create_chart
  • update_chart
  • delete_chart
  • recalculate
补丁值规则
  • 主目标使用 target.* 字段。
  • CellFormatting 使用 format.* 字段。
  • ValidationRule 使用 rule.* 字段。
  • ChartSpec 使用 chart.* 字段;图表源区域使用 chart.data_range.*。
  • data 必须是有效的 JSON。
  • 支持使用 <<TAG ... TAG heredoc 块来提供多行 JSON 或文本。
模式
  • atomic 遇到首个失败时停止、重置会话,且不持久化任何内容。
  • best_effort 保留此前成功的操作,并记录失败。

PatchApplyResult 字段:

  • mode
  • overall_status = "ok" | "partial" | "failed"
  • operations = PatchOperationResult 列表
  • document_persisted

对于独立的 patch(path, ...),document_persisted 表示更改已保存到磁盘。对于 session.patch(...),它表示补丁在当前打开的会话状态中成功产生了变更。

示例:在会话中构建电子表格

from pathlib import Path

from calc import (
    CalcSession,
    CalcTarget,
    CellFormatting,
    ChartSpec,
    ValidationRule,
)
from calc.core import create_spreadsheet

output = str(Path("test-output/revenue-report.ods").resolve())
create_spreadsheet(output)

with CalcSession(output) as session:
    session.rename_sheet(CalcTarget(kind="sheet", sheet="Sheet1"), "Revenue Data")
    session.add_sheet("Summary")
    session.write_range(
        CalcTarget(kind="range", sheet="Revenue Data", row=0, col=0, end_row=2, end_col=1),
        [["Label", "Value"], ["Revenue", 100], ["Cost", 80]],
    )
    session.format_range(
        CalcTarget(kind="range", sheet="Revenue Data", row=1, col=1, end_row=2, end_col=1),
        CellFormatting(number_format="currency", bold=True),
    )
    session.define_named_range(
        "RevenueValues",
        CalcTarget(kind="range", sheet="Revenue Data", row=1, col=1, end_row=2, end_col=1),
    )
    session.set_validation(
        CalcTarget(kind="range", sheet="Revenue Data", row=1, col=1, end_row=2, end_col=1),
        ValidationRule(type="whole", condition="greater_than", value1=0),
    )
    session.create_chart(
        CalcTarget(kind="sheet", sheet="Revenue Data"),
        ChartSpec(
            chart_type="line",
            data_range=CalcTarget(
                kind="range",
                sheet="Revenue Data",
                row=0,
                col=0,
                end_row=2,
                end_col=1,
            ),
            anchor_row=5,
            anchor_col=0,
            width=9000,
            height=6000,
            title="Revenue Trend",
        ),
    )
    session.recalculate()

示例:修补现有电子表格

from calc import patch

result = patch(
    "/abs/path/revenue-report.ods",
    """
    [operation]
    type = write_cell
    target.kind = cell
    target.sheet = Summary
    target.row = 1
    target.col = 1
    value = Ready
    value_type = text

    [operation]
    type = format_range
    target.kind = cell
    target.sheet = Summary
    target.row = 1
    target.col = 1
    format.bold = true

    [operation]
    type = recalculate
    """,
    mode="best_effort",
)

print(result.overall_status)

快照

from pathlib import Path
from calc import snapshot_area

result = snapshot_area(doc_path, "/tmp/revenue.png", sheet="Revenue Data", row=0, col=0, dpi=150)
print(result.file_path, result.width, result.height)
Path(result.file_path).unlink(missing_ok=True)   # clean up used snapshots

交付前,使用快照验证图表位置、格式和工作表布局。

  • snapshot_area() 输出的尺寸可能与请求尺寸略有差异;少量像素差异属于正常情况。

常见错误

  • 传入相对路径;面向 UNO 的 Calc API 要求使用绝对文件路径。
  • 混淆 cell 和 range 目标;即使是单单元格选区,Calc 也会将两者区分开。
  • 使用从 1 开始的坐标;行和列的索引都从 0 开始。
  • 以为 create_chart() 会随机选择另一个目标名称;设置 title 后,后续使用相同名称定位图表是最稳妥的做法。
  • 打包的 API 未提供图表列表或验证检查辅助工具;在高级工作流中,深入验证可能需要直接检查 UNO。
  • 修改图表操作时,忘记设置 chart.data_range.* 字段。
  • 期望 snapshot_area() 导出的 PNG 尺寸与请求完全一致;Calc 导出结果可能会有少量差异。
  • 检查完成后忘记清理捕获的快照。
  • 在调用 session.close() 后继续调用会话方法。
  • 导入 JSON / XML 需要 LibreOffice 26.2+。

评论

支持 Markdown