wps-template-engine

wps-template-engine is a skill for Claude Code from Bwkyd/wps-skills. It costs 98 tokens per session (2,181 once invoked), scanned A, original, MIT.

A Word document template tool that replaces {{variable}} placeholders with data from Excel or CSV files. It also supports conditions, loops, dynamic table rows, and formatting such as writing amounts in words.

In plain words
What is it for?
Creating reusable contracts, forms, reports, or other Word documents and generating many filled-in copies from structured data.
Why use it?
It avoids filling out many similar documents by hand and handles cases that simple mail merge cannot, such as optional sections and repeating rows.

Skill for Claude Code

Written for Claude Code: allowed-tools in frontmatter.

Good fit Creating reusable contracts, forms, reports, or other Word documents and generating many filled-in copies from structured data.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/bwkyd/wps-skills/wps-template-engine
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add Bwkyd/wps-skills --skill wps-template-engine
Clone the repo
git clone --depth 1 https://github.com/Bwkyd/wps-skills

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for wps-template-engine

README.md
[![agentmods](https://agentmods.dev/badge/skills/bwkyd/wps-skills/wps-template-engine/github.svg)](https://agentmods.dev/skills/bwkyd/wps-skills/wps-template-engine)
Your own site
<a href="https://agentmods.dev/skills/bwkyd/wps-skills/wps-template-engine"><img src="https://agentmods.dev/badge/skills/bwkyd/wps-skills/wps-template-engine/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for wps-template-engine

Your own site · 80×15
<a href="https://agentmods.dev/skills/bwkyd/wps-skills/wps-template-engine"><img src="https://agentmods.dev/badge/skills/bwkyd/wps-skills/wps-template-engine.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 98 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,181 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00098 $0.02181
Opus 5 $0.00049 $0.01091
Sonnet 5 $0.00020 $0.00436
Haiku 4.5 $0.00010 $0.00218

Measured 9d ago against content hash 3e8a0f05830c, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-09, from the pricing page.

Security

Grade A, and why

wps-template-engine scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

skills/wps-template-engine/SKILL.md · 275 lines

How it starts

The opening of the file, as written. The whole thing — 275 lines — stays where its author put it; the contents beside it link to each section on GitHub.

文档模板引擎

创建带 {{变量}} 的 Word 模板 → 从数据源自动填充 → 批量生成文档。

邮件合并的升级版:支持条件逻辑、循环、表格动态行、嵌套变量。

When to Use

  • 需要创建可复用的文档模板
  • 需要从数据源批量填充文档
  • 需要比邮件合并更强大的模板功能
  • 用户说"帮我做一个模板""文档自动化"

When NOT to Use

  • 简单的邮件合并(无高级功能) → 使用 wps-mail-merge
  • 一次性文档生成 → 使用 wps-docx-writer

模板语法

基础变量

{{变量名}}           → 替换为数据值
{{公司名称}}         → "XX科技有限公司"
{{合同金额}}         → "100,000.00"

日期/格式化

{{今日日期}}         → 自动填充当前日期
{{日期|YYYY年M月D日}} → 格式化日期
{{金额|大写}}        → 自动转金额大写
{{金额|千分位}}      → 添加千位分隔符

条件逻辑

{{#if 性别=男}}先生{{/if}}
{{#if 性别=女}}女士{{/if}}
{{#if 金额>10000}}需要总经理审批{{/if}}
{{#if 部门=技术部}}技术考核标准如下...{{/if}}

循环(表格动态行)

| 序号 | 品名 | 数量 | 单价 | 金额 |
{{#each 商品列表}}
| {{序号}} | {{品名}} | {{数量}} | {{单价}} | {{小计}} |
{{/each}}
| 合计 |  |  |  | {{总金额}} |

内置变量

{{__TODAY__}}        → 当前日期 YYYY-MM-DD
{{__TODAY_CN__}}     → 当前日期 YYYY年M月D日
{{__NOW__}}          → 当前时间 HH:MM
{{__INDEX__}}        → 当前记录序号(批量生成时)
{{__TOTAL__}}        → 总记录数

工作流程

Step 1: 决定路径

用户需要什么?
│
├─ 创建新模板 → Step 2A: 设计模板
│
├─ 用已有模板填充 → Step 2B: 数据填充
│
└─ 两者都要 → 先2A再2B

Step 2A: 设计模板

  1. 理解用户的文档类型和变量需求
  2. 设计模板结构和变量标记
  3. 生成带 {{变量}} 的 .docx 模板文件
  4. 生成配套的数据模板(.xlsx),列名对应变量名

Step 2B: 数据填充

from docx import Document
from openpyxl import load_workbook
import re
import os
import csv
from datetime import datetime

class TemplateEngine:
    """文档模板引擎"""

    BUILTIN_VARS = {
        '__TODAY__': lambda: datetime.now().strftime('%Y-%m-%d'),
        '__TODAY_CN__': lambda: datetime.now().strftime('%Y年%m月%d日'),
        '__NOW__': lambda: datetime.now().strftime('%H:%M'),
    }

    def __init__(self, template_path):
        self.template_path = template_path
        self.vars_found = set()
        self._scan_variables()

    def _scan_variables(self):
        """扫描模板中的所有变量"""
        doc = Document(self.template_path)
        for para in doc.paragraphs:
            self.vars_found.update(re.findall(r'\{\{(.+?)\}\}', para.text))
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    for para in cell.paragraphs:
                        self.vars_found.update(
                            re.findall(r'\{\{(.+?)\}\}', para.text))

    def get_variables(self):
        """返回模板中使用的变量列表"""
        return sorted(self.vars_found)

    def render(self, data, output_path):
        """用数据渲染模板"""
        doc = Document(self.template_path)

        # 注入内置变量
        for key, func in self.BUILTIN_VARS.items():
            data.setdefault(key, func())

        # 格式化处理
        processed = {}
        for key, value in data.items():
            processed[key] = str(value) if value is not None else ''
            # 金额大写
            if key + '|大写' in str(self.vars_found):
                processed[key + '|大写'] = self._amount_to_cn(value)
            # 千分位
            if key + '|千分位' in str(self.vars_found):
                try:
                    processed[key + '|千分位'] = f'{float(value):,.2f}'
                except (ValueError, TypeError):
                    processed[key + '|千分位'] = str(value)

        # 替换段落
        for para in doc.paragraphs:
            self._replace_in_paragraph(para, processed)

        # 替换表格
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    for para in cell.paragraphs:
                        self._replace_in_paragraph(para, processed)

        doc.save(output_path)
        return os.path.abspath(output_path)

    def _replace_in_paragraph(self, para, data):
        """替换段落中的变量(保持格式)"""
        full_text = para.text
        if '{{' not in full_text:
            return

        for var_name, value in data.items():
            placeholder = '{{' + var_name + '}}'
            if placeholder in full_text:
                for run in para.runs:
                    if placeholder in run.text:
                        run.text = run.text.replace(placeholder, value)
                full_text = para.text

    def batch_render(self, records, output_dir,
                     filename_pattern='doc_{{__INDEX__}}'):
        """批量渲染"""
        os.makedirs(output_dir, exist_ok=True)
        generated = []

        for i, record in enumerate(records):
            record['__INDEX__'] = str(i + 1)
            record['__TOTAL__'] = str(len(records))

            fname = filename_pattern
            for key, value in record.items():
                fname = fname.replace('{{' + key + '}}', str(value))
            fname = re.sub(r'[\\/:*?"<>|]', '_', fname)

            output_path = os.path.join(output_dir, f'{fname}.docx')
            self.render(record, output_path)
            generated.append(output_path)

        return generated

    @staticmethod
    def _amount_to_cn(amount):
        """金额转中文大写"""
        try:
            num = float(amount)
        except (ValueError, TypeError):
            return str(amount)
        units = ['', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿']
        digits = '零壹贰叁肆伍陆柒捌玖'
        integer = int(abs(num))
        decimal = round(abs(num) - integer, 2)

        if integer == 0:
            result = '零元'
        else:
            s = str(integer)
            result = ''
            for i, d in enumerate(reversed(s)):
                if int(d) != 0:
                    result = digits[int(d)] + units[i] + result
                else:
                    if not result.startswith('零'):
                        result = '零' + result
            result = result.rstrip('零') + '元'

        jiao = int(decimal * 10) % 10
        fen = int(decimal * 100) % 10
        if jiao == 0 and fen == 0:
            result += '整'
        else:
            if jiao > 0:
                result += digits[jiao] + '角'
            if fen > 0:
                result += digits[fen] + '分'

        return ('负' if num < 0 else '') + result

Read the full file on GitHub · 275 lines

Files

What ships with it

1 file beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 9d ago First seen · 275 lines · 98 tokens per session scan A 3e8a0f05830c

Subscribe to this mod's changes

wps-template-engine is a skill published in the GitHub repository Bwkyd/wps-skills (7 stars, last pushed 4mo ago), licensed MIT. It adds 98 tokens to every session and 2,181 once invoked, about $0.0005 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

Other skills, from other repositories

xlsx

Use this skill any time a spreadsheet file is the primary input or output. This means any task where the user wants to: open, read, edit, or fix an existing .xlsx, .xlsm, .csv, or .tsv file (e.g., adding columns, computing formulas, formatting, charting, cleaning messy data); create a new spreadsheet from scratch or…

lingxling/awesome-skills-cn · 201 tokens

xlsx

Create, edit, analyze, or convert Excel spreadsheets (.xlsx, .xlsm, .xltx) where the workbook file is the primary deliverable. Use for formulas, formatting, financial models, multi-sheet workbooks, and tabular cleanup exported to Excel. Also applies to .csv/.tsv when the user wants spreadsheet output. Do NOT use for…

K-Dense-AI/scientific-agent-skills · 94 tokens

document-generation

Generate Word (.docx), Excel (.xlsx) and PowerPoint (.pptx) documents and fill existing PDF forms, from real NetClaw data, with per-element provenance and no fabrication. Use when someone needs a deliverable rather than an answer — a change record to attach to a CR, an audit workbook for a compliance reviewer, a…

automateyournetwork/netclaw · 91 tokens

dgn-to-excel

Convert DGN files (v7-v8) to Excel databases. Extract elements, levels, and properties from infrastructure CAD files.

datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction · 32 tokens

dwg-to-excel

Convert AutoCAD DWG files (1983-2026) to Excel databases using DwgExporter CLI. Extract layers, blocks, attributes, and geometry data without Autodesk licenses.

datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction · 42 tokens

ifc-to-excel

Convert IFC files (2x3, 4x1, 4x3) to Excel databases using IfcExporter CLI. Extract BIM data, properties, and geometry without proprietary software.

datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction · 45 tokens