AgentStack
SKILL unreviewed Apache-2.0 Self-run

Jimureport

skill-jeecgboot-skills-jimureport · by jeecgboot

积木报表生成器 — 自然语言描述报表需求或提供截图,自动生成积木报表(支持数据报表、打印报表、分组报表、循环报表、数据填报等全类型)。Use when user says "积木报表", "jmreport", "Excel报表", "数据填报", "可视化报表", "打印报表", "分组报表", "循环报表", "按照截图生成报表", "创建积木报表", "做一个可视化报表", "积木设计器", "create jimureport", "visual report". Also triggers when user describes report requirements involving Excel-like layouts, data binding with #{}, or multi-sheet reports, or provides a screenshot to g…

No reviews yet
0 installs
11 views
0.0% view→install

Install

$ agentstack add skill-jeecgboot-skills-jimureport

Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Destructive filesystem operation.

What it can access

  • Network access Used
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Jimureport? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

积木报表 AI 生成器

> 不涉及「Online 报表」(cgreport)或「Online 表单」(cgform)。

临时配置文件规则(强制)

所有传给脚本的 --config 必须写到 {系统临时目录}/{SKILL_NAME}/ 下,由操作系统自动清理;skill 与脚本均不主动删除该目录或文件。

import tempfile, os, json

SKILL_NAME = ""               # 请替换为实际的技能名称
skill_dir = os.path.join(tempfile.gettempdir(), SKILL_NAME)
os.makedirs(skill_dir, exist_ok=True)          # 确保目录存在,不主动检查

config_path = os.path.join(skill_dir, 'sk_audit_create.json')   # 示例文件名
with open(config_path, 'w', encoding='utf-8') as f:
    json.dump(cfg, f, ensure_ascii=False, indent=2)

tempfile.gettempdir() 自动适配:Windows %TEMP%、Linux /tmp、macOS /var/folders/.../T(注意 macOS 并非 /tmp)。 文件名建议使用 _.json(如 sk_audit_create.json),无需重复技能前缀,因路径已包含技能名称,便于排错。

❌ 禁止:

  • 写到 /tmp/ 或当前工作目录(污染 skill / 用户项目)
  • 硬编码 /tmpC:\Temp 或任何固定路径(不跨平台)
  • 每步完成后主动 rm / Remove-Item(操作系统会清理,属多余 tool call)
  • 主动 os.path.exists() 检查(其本身即为一次 tool call)

(使用 os.makedirs(…, exist_ok=True) 满足需求,不算主动检查)

临时文件可能被操作系统异步清理,但仍遵循 乐观调用 + 报错补救:仅当脚本返回 FileNotFoundError配置文件不存在 时,使用相同内容、在相同的 {系统临时目录}/{SKILL名称}/ 路径下重写(重写前仍需 os.makedirs(skill_dir, exist_ok=True) 确保目录存在),切勿更换路径或回退至 skill 目录。

一键脚本(必看,覆盖三类全场景)

写自定义 JSON / Python 之前,先看用户需求是否命中下表现成脚本,命中则直接调用,禁止重新组装 JSON 或 Python

| 用户描述(关键词) | 直接调用 | 默认覆盖 | |------|---------|---------| | 「全图表」「所有图表」「图表大全」「测试所有数据集类型」「SQL+API+JSON」「图表展示」 | python scripts/generate_all_reports.py --base-url ... --token ... --name "..." --mysql-host ... --mysql-port ... --mysql-db ... --mysql-user ... --mysql-pwd ... | 25 个图表(SQL 12 + API 2 + JSON 4 + 不绑 7),自动建 chart_demo_all 表插数据 + 自动创建 YApi mock + 一次保存 |

命中规则与禁止事项

  • 关键词命中即用:用户说「生成全部图表」「全图表测试」「演示所有图表」「测试 SQL/API/JSON 三种数据集」时,第一反应就是 generate_all_reports.py不要回头自己写 chart_entry/echarts 模板
  • 3 秒能跑完:实测 ~3.1s 端到端创建。脚本启动后不要分块等待、不要发 AskUser 求确认,直接 Bash 等结果
  • Mock 新建必须用唯一路径create_mock 遇到同路径会静默覆盖已有接口数据,污染他人接口。创建新接口时必须在路径末尾追加时间戳或序号(如 /sales_20260427),只有用户明确说"修改/更新已有接口"时才可复用原路径
  • saveDb 串行:脚本已改为串行调用 save_db,避免 jimu_report_db_field INSERT 并发引发 MySQL deadlock
  • 新增图表类型时:在 CHARTS 列表加一行,写一个 tpl_xxx 函数即可,无需重写主流程

执行流程

第零步(必须):Token 优先

用户消息里没有 X-Access-Token 时,立刻询问,拿到 token 后再读任何文件。等待回复期间不要预读文件——等待时间不计入 3 分钟,文件读取时间计入。

> ⚠️ 凭证禁止读记忆,直接问用户:需要数据库密码、账号密码等任何凭证时,禁止读取 memory 文件获取,必须直接在对话中问用户。

第一步(必须):按「执行速度规范」表选最小文件集

> 不要先 Glob examples/,直接查下方「执行速度规范」表,按场景只读指定文件。禁止在表外额外读文件。 > 场景匹配优先于文件名匹配multi-level-header.md 主要是交叉表 groupRight/dynamic,纵向分组+静态多级表头不要读它(浪费 ~30s 读不适用示例)。

读完指定文件后直接 Write JSON 配置 → 执行 CLI 命令 → 输出预览链接。两步完成,禁止多余动作。

> 报表链接格式(创建成功后直接输出,禁止调接口验证是否存在): > - 设计器:http://{host}/jmreport/index/{report_id}?token={token}&tenantId=1 > - 预览:http://{host}/jmreport/view/{report_id}?token={token}&tenantId=1

> 报表名称规则:用户明确指定名称时直接使用;未指定时 AI 自动生成名称,生成后须调 GET /jmreport/query/report/folder?pageNo=1&pageSize=10&reportType=&name={name}&token={token} 检查是否重复,有同名则追加后缀(如 _2_20260415)。

utils 子模块速查(需确认某函数签名时,Grep 对应小文件,禁止读全量 jimureport_utils.py):

| 需要确认的函数 | 读哪个文件 | |--------------|----------| | Session、genid/code/layer、colletter、computesign | jimureport_core.py | | parseapi、parsesql、savedb、updatedb、parseandsavedataset、parallelparse/save/api | jimureport_dataset.py | | makedesigner、basesave、getreport、reporturls、printsummary | jimureport_report.py | | makestyles、STYLEBASE/DATA/HEADER/TITLE/LINK(命名常量,禁止用魔法数字) | jimureport_styles.py | | chartentry、virtualrow、buildchartlayout、updatechartconfig、parallelfillcharts、pickchartaxes | jimureport_chart.py | | createlink、parallelcreatelinks | jimureport_link.py | | ensuredatasource、finddatasource、getdsconnection、querymysql、executeds | jimureport_datasource.py |

| 禁止 | 替代 | |------|------| | 读全量 jimureportutils.py | 按上表 Grep/Read 对应子模块(各 25-175 行) | | Grep/Read jimureport_gen.py(任何原因) | api_dataset/group/standard 等函数的签名和参数在 SKILL.md 调用示例中已完整给出(baseurl 默认 http://192.168.1.6:8085/jmreport,无需传),"不确定参数"不构成读源码的理由,直接信任文档 | | Grep/Read jimureport_creator.py 确认是否支持某功能(如 fieldList searchMode、paramList 等) | SKILL.md 的 JSON 配置模板和禁止表已覆盖所有场景,直接写 JSON 配置执行,禁止读源码验证 | | Grep/Read jimureport_dataset.py 查看 parsesql 实现 | parse_sql 接受含 FreeMarker 条件的 SQL,服务端以空参评估后解析字段列表,直接调用即可,无需看源码 | | 找 DB 凭证 | 用 memory 中的配置或问用户 | | Windows 下 Bash tool 跑 python | 改用 PowerShell tool 跑 python xxx.py / python -c "...",同步返回(详见下方「Windows 执行环境」) | | 调外部 API 验证字段 | 直接按用户提供的字段写脚本,不预调 API | | 擅自调用 create_mock()init_yapi() | ⛔ 用户已提供接口 URL 时,直接 save_db(api_url=URL),严禁调用 create_mock() / init_yapi() / 任何 YApi 登录或验证操作;只有用户明确说"帮我创建 mock 接口"或完全未提供 URL 时才调用;URL 已知 = 直接用,不验证、不询问、不登录 | | sleep + cat 轮询输出 | Bash 命令在 Windows 始终被后台化;若仍要走 Bash,必须用 TaskOutput(task_id, block=true) 等待结果,禁止用 sleep/cat 轮询 | | 报表创建后调接口验证是否存在 | /save 返回 success:true 即成功,直接输出设计/预览链接,无需查报表列表 | | 手写 border 样式{"style":1} 或任何非数组格式) | 必须用 make_styles() 获取 styles 列表,它已内置正确的 ["thin","#d8d8d8"] 数组格式;手写 border 一律禁止,会导致整表渲染空白 | | customRows 配合空 columns: [] | creator 靠 columns 生成 queryInfo.dbfcolumns 为空则不写入绑定元数据,报表预览完全无数据(即使数据集 records=N)。customRows 只控制视觉布局,columns 必须填数据集的实际字段(至少一个)| | 用户未指定的可选参数自行填值(如 customEditConf.eventParamsfreezerpbarbackground 等) | 只写用户明确给出的字段,其余可选参数一律省略,不得自造默认值 | | 调 report_urls() 工具函数当作 dict 用(如 urls['designer']) | report_urls(report_id, base_url, token, tenant) 返回 tuple (preview_url, design_url),不是 dict;且第一个参数是 reportid 不是 base_url。直接按本节"报表链接格式"拼字符串,不要调用此函数 | | 报表创建走自定义 .py 脚本 | ⛔ 必须用 JSON 配置文件 + jimureport_creator.py CLI:只写 xxx.jsonpython jimureport_creator.py --api-base URL --token TOKEN --config xxx.json。需要同时创建 YApi mock 的 API 数据集报表,用 jimureport_gen.api_dataset(..., mock_data=[...], mock_path="/xxx_日期") 一步完成,内部自动生成 JSON 并调 CLI,无需手写 Python 脚本。用户反馈(2026-05-22 再次确认):"以后只生成JSON"。⚠️ 典型错误场景1:用户要求自定义样式,AI 认为高级函数不支持样式就手写 rows/cols/styles/save_db/base_save——严重违规。⚠️ 典型错误场景2:场景复杂(含钻取+图表+建表),AI 直接写 drill_demo.py 等全流程 Python 脚本——严重违规。正确做法:报表结构部分始终写 JSON;建表/链接创建等 JSON 不支持的步骤写成最小独立 PowerShell inline;两部分分开,不混写。| | PowerShell Out-File -Encoding utf8 写 JSON | 产生 UTF-8 BOM 导致 json.loadUnexpected UTF-8 BOM必须用[System.IO.File]::WriteAllText($path, $content, (New-Object System.Text.UTF8Encoding $false)) |

Windows 执行环境(强制规则,违反会让用户吐槽"执行太慢")

现象:Windows 的 Bash tool 会把 python / python -c / skill 脚本当作长命令自动 run_in_background,tool 立即返回 background ID,真正输出要等完成通知——把毫秒级调用放大到数秒,历史上多次让单报表从 1 分钟拖到 18 分钟。

规则

  • Windows(platform=win32) → 用 PowerShell tool 直接执行 python xxx.py,同步返回。禁止用 Bash tool 跑 python(会被后台化)。
  • Linux / macOS → 用 Bash tool 直接调用 python xxx.py
  • 任何平台都不用 curl:跨平台不一致,Windows Bash 下同样被后台化。

脚本执行前强制检查(2 项)

  1. ✅ Windows 下用 PowerShell tool 执行 python xxx.py不是 Bash tool
  2. ✅ 脚本第一行已加编码声明:import sys; sys.stdout.reconfigure(encoding='utf-8')(防 GBK 崩溃重试)

Windows 正确示例

PowerShell: python /scripts/xxx.py --base-url ... --token ...

> ` 是本 SKILL.md 所在目录,运行时用实际路径替换,禁止写死 C:/Users/...`。

Windows 错误示例

Bash: python generate_all_reports.py ...    ← 返回 "Command running in background with ID: xxx"
Bash: curl -X POST ...                       ← 同上

> 历史教训:曾因默认走 Bash + python 被用户连续吐槽"执行太慢了 / 生成这么慢"。根因是 Bash tool 在 Windows 对 python 会后台化,不限于 curl。另一常见重试原因:脚本缺编码声明导致 UnicodeEncodeError: 'gbk' codec,加第2项检查可消除。 > 典型症状:报表生成完成后仍等待约 2 分钟才结束——这是 Bash 后台化的直接表现:脚本已跑完但 tool 在等 background 完成通知。遇到此现象立即确认是否误用了 Bash tool,改 PowerShell 即可消除。

前置条件

用户须提供 X-Access-Token

SQL 数据集数据源选取(用户未指定 dbSource 时必须执行)

正确流程(必须每次执行,不可跳过):

  1. GET /jmreport/initDataSource 获取数据源列表
  2. 按用户提供的数据库名(如 jeecg-boot-cr精确匹配 name 字段,取其 id
  3. 找不到再询问用户

> ⚠️ 禁止用 memory 中存的数据源ID直接跳过查询:memory 里的ID可能已过期或被重建,必须每次查询后按名字匹配拿到当前有效ID。memory 只用于记住数据库名,不用于记住ID。 > ⚠️ 禁止全量拉取后遍历猜测:有明确数据库名时直接按名字匹配,不要靠含"积木"等模糊规则。

按以下规则处理:

| 返回结果 | 处理方式 | |---------|---------| | result 为空数组 | 告知用户需要先在积木报表中新增数据源,停止创建 | | result 非空,存在 name 含"积木"的项 | 自动选该项,将其 id 作为 db_source 传入 save_db | | result 非空,无含"积木"的项 | 列出所有数据源名称,询问用户选哪个,等待回复后再继续 |

接口返回字段:每项包含 id(传给 db_source)和 name(展示给用户)。

脚本中直接调用(禁止在脚本里重新手写此逻辑):

from jimureport_utils import resolve_db_source
# 用户未指定数据源时:
db_source = resolve_db_source(session)   # 自动选含「积木」的;无则抛 RuntimeError 列出清单

RuntimeError 消息已包含数据源列表,捕获后直接转告用户即可。

> 上下文优先:本次对话中已经通过 resolve_db_source 或用户回复确定过 db_source,后续同一会话的报表直接复用,不得重复调用 initDataSource。 > ⚠️ 禁止全量拉取后遍历猜测:不要拉取全部30+数据源再靠名字模糊匹配,应按用户提供的数据库名精确查找,或直接读 memory。全量拉取是浪费 + 容易选错。

API 数据集前置询问(用户未提供 API 地址时必须先问)

用户未给出 API 地址时,必须先询问

> 请问接口用哪种方式创建? > - mock 接口:通过 YApi 创建 mock 接口(参见下方「YApi Mock 数据源」章节) > - 本地代码:请提供本地 JeecgBoot 项目路径,我直接把 Controller 写入项目

收到答复后的处理规则:

| 用户选择 | 处理方式 | |---------|---------| | mock 接口 | 按「YApi Mock 数据源」章节流程,用 yapi_mock.py 创建 mock 接口,返回 mock URL 填入数据集 | | 本地代码 | 询问项目路径(如 D:\path\to\jeecg-boot),只生成 Controller 写入项目,返回静态数据({"data": [...]}),不生成 Entity / Mapper / Service / SQL |

🚀 CLI 创建(一条命令)

python /scripts/jimureport_creator.py \
  --api-base http://BASE_URL --token TOKEN --config /path/to/config.json

配置 A:SQL 普通/分组报表

{
  "action": "create", "reportName": "报表名称", "theme": "blue",
  "datasets": [{"dbCode":"ds1","dbChName":"数据集","dbDynSql":"SELECT col1,col2 FROM t ORDER BY col1","dbSource":"","isPage":"0"}],
  "table": {"datasetCode":"ds1","title":"报表名称","columns":[
    {"field":"col1","title":"列1","width":120,"group":true},
    {"field":"col2","title":"列2","width":100,"funcname":"SUM"}
  ]}
}

> columns 可选属性:group:true(分组) / funcname:"SUM"(聚合) / subtotalText:"小计"

配置 B:SQL + 图表

{
  "action":"create","reportName":"名称","layout":"chart_bottom",
  "datasets":[
    {"dbCode":"dt","dbChName":"表格","dbDynSql":"SELECT ...","isPage":"1"},
    {"dbCode":"dc","dbChName":"图表","dbDynSql":"SELECT x AS name,y AS value,'' AS type FROM ...","isPage":"0"}
  ],
  "table":{"datasetCode":"dt","title":"名称","columns":[...]},
  "chart":{"datasetCode":"dc","chartType":"bar.simple","title":"图表","width":"650","height":"380"}
}

> layout: chart_bottom / chart_top / chart_right / chart_only

配置 C:JSON 数据集(dbCode 必须字符串!)

{
  "action":"create","reportName":"名称",
  "datasets":[{"dbCode":"my_data","dbChName":"数据","dbType":"3","isList":"1","isPage":"0",
    "jsonData":[{"name":"张三","age":"25"}],
    "fieldList":[["name","姓名"],["age","年龄"]]}],
  "table":{"datasetCode":"my_data","title":"名称","columns":[
    {"field":"name","title":"姓名","width":100},{"field":"age","title":"年龄","width":80}]}
}

> 禁止纯数字 dbCode(如 gen_code()),JSON 数据集模板引擎无法解析。

> f-string 写绑定字段时必须转义花括号f"#{{{db_code}.{field}}}" → 生成 #{db_code.field}。若写成 f"#{db_code}.{field}#" 则花括号被 Python 吃掉,变成 #db_code.field#(格式错误,末尾多 #,数据不渲染)。

配置 D:自定义 rows(复杂多级表头)

buildtablerows 无法满足时(如四级合并表头),传 customRows + customMerges 跳过自动构建:

{
  "action":"create","reportName":"名称",
  "datasets":[{"dbCode":"ds1","dbType":"3","jsonData":[...],"fieldList":[...]}],
  "table":{"datasetCode":"ds1","columns":[{"field":"f1","title":"F1","width":100}]},
  "groupField":"ds1.group_field",
  "customRows":{"1":{"cells":{"1":{"text":"标题","style":0,"merge":[0,5]}},"height":40}},
  "customMerges":["B2:G2"],
  "customStyles":[{"align":"center","font":{"size":16,"bold":true}},{"align":"center","font":{"bold":true,"color":"#FFF"},"bgcolor":"#4472C4"},{"align":"center","valign":"middle"}],
  "customCols":{"0":{"width":27},"1":{"width":100},"len":100}
}

> ⚠️ table.columnscustomRows 同时存在时,columns 仍不可为空数组 [] > creator 依赖 columns 来生成 designerObj 中的 queryInfo.dbf(数据集绑定元数据)。 > 若 columns: []queryInfo.dbf 不会写入,报表预览将完全空白(无数据),即使数据集已保存成功(records=N)。 > 正确做法columns 填入数据集的实际字段(哪怕只有一个),customRows 再覆盖视觉布局;两者独立互不影响。

配置 E:含钻取(drilling)——无需任何额外 Python 脚本

drillinglinkages 键已内置于 creator:creator 自动调用 /link/saveAndEdit 并把 linkIds 回填到 cells / chart extData,全程只需一个 JSON 文件。

{
  "action": "create",
  "reportName": "主报表(三种钻取演示)",
  "theme": "blue",
  "layout": "chart_bottom",
  "datasets": [
    {
      "dbCode": "sales", "dbChName": "学校汇总",
      "dbDynSql": "SELECT leibie AS name, SUM(jine) AS value, '' AS type, 'jeecg.com' AS website FROM school_demo GROUP BY leibie ORDER BY value DESC",
      "dbSource": "1161942757348524032", "isPage": "0"
    }
  ],
  "table": {
    "datasetCode": "sales", "title": "学校汇总报表",
    "columns": [
      {"field": "name",    "title": "类别(点击→子报表)", "width": 140},
      {"field": "value",   "title": "总金额",              "width": 120},
      {"field": "website", "title": "官网(点击→jeecg.com)","width": 180}
    ]
  },
  "chart": {
    "datasetCode": "sales", "chartType": "bar.simple",
    "title": "各类别总金额(点击柱子钻取)", "width": "560", "height": "360"
  },
  "drilling": [
    {
      "name": "钻取1-报表钻取报表",
      "linkType": "0",
      "targetReportId": "",
      "ejectType": "0",
      "source": {"type": "cell", "field": "name"},
      "params": [
        {"paramName": "leibie", "paramValue": "name", "fieldName": "name", "dbCode": "sales", "tableIndex": 0}
      ]
    },
    {
      "name": "钻取2-图表钻取报表",
      "linkType": "0",
      "targetReportId": "",
      "ejectType": "0",
      "source": {"type": "chart"},
      "params": [
        {"paramName": "leibie", "paramValue": "name", "fieldName": "", "dbCode": "sales", "tableIndex": 0}
      ]
    },
    {
      "name": "钻取3-网络钻取",
      "linkType": "1",
      "targetUrl": "http://jeecg.com",
      "ejectType": "0",
      "source": {"type": "cell", "field": "website"},
      "params": [
        {"paramName": "school", "paramValue": "name", "fieldName": "name", "dbCode": "sales", "tableIndex": 0}
      ]
    }
  ]
}

drilling 字段说明:

| 字段 | 说明 | |------|------| | linkType | "0" 报表钻取 / "1" 网络链接 | | targetReportId | linkType=0 时填目标报表 ID;linkType=1 时留空 | | targetUrl | linkType=1 时填外部 URL | | ejectType | "0" 新窗口 / "1" 当前窗口 | | source.type | "cell" 单元格触发 / "chart" 图表触发 | | source.field | cell 时填数据集字段名(creator 自动匹配含该字段的数据行单元格并回填 linkIds) | | params[].paramValue | 单元格钻取填字段名;图表钻取填 name(X轴)/ value(Y轴)/ seriesName |

> 跨报表钻取的顺序:先创建子报表拿到 detail_id,再把 detail_id 填入主报表 JSON 的 targetReportId,两个 JSON 分别跑 CLI 即可,无需额外 Python 脚本。

配置 F:NoSQL 数据集(ES / MongoDB / Redis)

dbType"es"/"mongo"/"mongodb"/"redis",creator 自动补 Calcite schema 前缀;dbSource 必填数据源 ID。

{"action":"create","reportName":"名称",
 "datasets":[
   {"dbCode":"esDs",    "dbChName":"ES员工",   "dbType":"es",    "esIndex":"jmreport_test_employee","dbSource":"",    "isPage":"1"},
   {"dbCode":"mongoDs", "dbChName":"Mongo订单", "dbType":"mongo", "mongoCollection":"orders",        "dbSource":"", "isPage":"1"},
   {"dbCode":"redisDs", "dbChName":"Redis缓存", "dbType":"redis", "dbDynSql":"SELECT * FROM cache",  "dbSource":"", "isPage":"0"}
 ],
 "table":{"datasetCode":"esDs","title":"员工列表","columns":[
   {"field":"emp_id","title":"工号","width":80},{"field":"emp_name","title":"姓名","width":100}
 ]}
}

| 字段 | 说明 | |------|------| | esIndex | ES 专用简写,自动生成 SELECT * FROM es.{索引名};有它可省略 dbDynSql | | mongoCollection | MongoDB 专用简写,自动生成 SELECT * FROM mongo.{集合名} | | dbDynSql | 显式 SQL;ES/Mongo 缺 es./mongo. 前缀时自动补全;Redis 原样传入 |

> ES 字段名若与 Calcite 保留字冲突(position/date/type/value 等),需反引号转义或改用 esIndex 简写(SELECT * 无需列出字段名,天然规避)。详见 pitfalls.md §数据库数据源。

修改已有报表

# get_report → 改 design → base_save(**design 展开,get_report 返回的 design 是安全的)
designer, design = get_report(session, report_id)
design["rows"]["3"]["cells"]["1"]["text"] = "新值"
design["chartList"] = filled_charts   # 如有图表回填,直接替换 chartList
session.request("/save", base_save(report_id, designer, **design))
# ↑ get_report 返回的 design 只含 base_save 接受的 key,**design 展开无冲突
# 注意:手动拼的 design dict 禁止 **展开,必须显式列出 rows/cols/styles/merges/chartList

> **⚠️ Bug 修复必须

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.