Skip to content
Productivity
Skill

/doc-importer

将本地文档批量导入到 WPS 笔记。支持扫描 Obsidian Vault、思源笔记、微信公众号存档、 下载目录或任意用户指定目录,自动识别 HTML、Markdown、PDF、DOCX、PPTX、XLSX 等格式, 转换为 WPS 笔记可读内容并保留图片和富文本格式。 当用户说「导入文档到 WPS 笔记」「把我的 Obsidian 笔记导入」「导入思源笔记」 「把下载的 PDF/Word/PPT 导入笔记」「把公众号文章导入笔记」「同步本地文档到 WPS 笔记」时触发。 不适用于直接编辑 WPS 笔记内容、文档格式转换(不导入到笔记)。

BOOST
From plugin
wpsnote-skills
18037 skills
Install
$ npx -y skills add wpsnote/wpsnote-skills --skill doc-importer --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/doc-importer

Context preview

The summary Claude sees to decide when to auto-load this skill.

将本地文档批量导入到 WPS 笔记。支持扫描 Obsidian Vault、思源笔记、微信公众号存档、 下载目录或任意用户指定目录,自动识别 HTML、Markdown、PDF、DOCX、PPTX、XLSX 等格式, 转换为 WPS 笔记可读内容并保留图片和富文本格式。 当用户说「导入文档到 WPS 笔记」「把我的 Obsidian 笔记导入」「导入思源笔记」 「把下载的 PDF/Word/PPT 导入笔记」「把公众号文章导入笔记」「同步本地文档到 WPS 笔记」时触发。 不适用于直接编辑 WPS 笔记内容、文档格式转换(不导入到笔记)。

SKILL.md

doc-importer.SKILL.md
name: doc-importer
description: >
  将本地文档批量导入到 WPS 笔记。支持扫描 Obsidian Vault、思源笔记、微信公众号存档、
  下载目录或任意用户指定目录,自动识别 HTML、Markdown、PDF、DOCX、PPTX、XLSX 等格式,
  转换为 WPS 笔记可读内容并保留图片和富文本格式。
  当用户说「导入文档到 WPS 笔记」「把我的 Obsidian 笔记导入」「导入思源笔记」
  「把下载的 PDF/Word/PPT 导入笔记」「把公众号文章导入笔记」「同步本地文档到 WPS 笔记」时触发。
  不适用于直接编辑 WPS 笔记内容、文档格式转换(不导入到笔记)。
license: MIT
metadata:
  author: 洛小山 (itshen)
  version: 1.2.0
  category: productivity
  tags: [obsidian, siyuan, wechat, html, import, pdf, docx, pptx, markdown]

文档导入器(Doc Importer)

将本地文档(Obsidian、思源笔记、微信公众号 HTML、下载目录或任意目录)批量导入到 WPS 笔记。

---

快速开始

**当前技能的笔记写入统一走笔记 Agent 工具;如需理解批量扫描和转换逻辑,可先读取本 Skill 自带脚本:**

参考实现:
- read_file("scripts/scan_docs.py")        # 目录扫描与来源识别
- read_file("scripts/import_to_wps.py")    # 转换与导入主流程

实际写入:
- create_note
- get_note_outline
- batch_edit
- insert_image
- read_note / read_blocks
- search_notes
- sync_note

---

支持的文档来源

| 来源 | 说明 | 典型目录结构 | |------|------|------------| | **Obsidian Vault** | 扫描 .md 文件,保留 wiki 链接、Callout、标签 | `Vault/笔记名.md` + `attachments/` | | **思源笔记** | 扫描 .sy 文件(JSON格式),提取 Block Tree | `SiYuan/data/笔记本/文档.sy` | | **微信公众号** | 解析 `原文.html`(含富文本格式、内联样式) | `文章名/原文.html` + `图片/` | | **任意目录** | 用户指定路径,递归扫描子目录 | 任意 |

---

支持的文件格式

| 格式 | 转换方式 | 图片处理 | 富文本保留 | |------|----------|----------|-----------| | `.html` | BeautifulSoup 解析内联样式 | 本地图片 base64 | ✅ 颜色/粗体/标题 | | `.md` / `.markdown` | 直接解析,转 WPS XML | 本地图片 base64 | 基本格式 | | `.pdf` | pdfplumber 提取文本 + pdfimages 提取图片 | 提取嵌入图片 | 标题推断 | | `.docx` | pandoc 转 markdown,提取 word/media/ | 解包提取 | 基本格式 | | `.pptx` | markitdown 提取文本 + 解包媒体 | 解包提取 | 幻灯片结构 | | `.xlsx` | pandas 读取,转 WPS table | 不含图片 | 表格结构 | | `.txt` | 直接读取 | 不含图片 | 无 | | `.sy` | JSON 解析思源 Block Tree | 提取 assets 图片 | 全部 |

---

WPS API 关键限制(必读)

在实际导入前,必须了解以下 WPS 笔记 API 的重要限制,否则会导致内容丢失或图片插入失败。

1. `get_note_outline` 默认只返回 100 个 block

`get_note_outline` 默认按分页视图返回 block,`blocks` 数组可能只覆盖前一部分内容,但 `block_count` 会返回真实总数。

**影响**:大文章(> 100 个 block)如果只靠首屏大纲查占位符,只能找到前一部分 block,后半段图片会丢失。

**解决方案**:先用 `get_note_outline` 拿首批 block,再用 `read_blocks` 续读:

def get_all_blocks(note_id):
    """翻页获取笔记全部 blocks"""
    # 第一页用 get_note_outline(有 preview 字段)
    r = get_note_outline(note_id=note_id)
    data = r.get('data', {})
    total = data.get('block_count', 0)
    blocks = list(data.get('blocks', []))
    last_id = blocks[-1]['id'] if blocks else None

    # 超过首批范围时用 read_blocks 续读
    while len(blocks) < total and last_id:
        r2 = read_blocks(note_id=note_id, block_id=last_id, after=100)
        new_blocks = (r2.get('data') or {}).get('blocks', [])
        if not new_blocks:
            break
        blocks.extend(new_blocks)
        last_id = new_blocks[-1]['id']

    return blocks

> `get_note_outline` 返回的 block 常带 `preview` 字段;`read_blocks` 更适合拿完整 XML 内容。

---

2. `insert_image` 在旧版 WPS 中只能插到前台笔记

**旧版本(< 0.1.4)**:`insert_image` 的图片 `fileID` 绑定到当前 WPS 客户端 UI 中打开的笔记,即使传了 `note_id` 参数,图片也会错误地关联到前台笔记。

**新版本(>= 0.1.4)**:已修复,`insert_image` 可以直接后台插图到任意笔记,无需切换前台。

**处理策略**:

  • 先按后台插图能力执行;如果图片插错位置,再回退为“切到目标笔记后插图”
  • 如果宿主或客户端仍表现为旧版行为,明确提示用户升级或手动切到目标笔记
  • 插图后务必回读验收,不要假设成功

---

3. `list_notes` 返回大数据时要主动收敛范围

`list_notes` 一次返回的数据过大时,不适合拿来做全文去重或全量扫描判断。

**解决方案**:

  • 去重优先用 `search_notes` 按标题关键词搜索
  • 浏览列表时主动分页或缩小筛选范围
  • 不把一次大范围 `list_notes` 当成唯一真相来源

---

4. anchor 失效导致内容静默丢失

连续调用 `batch_edit` 插入内容时,WPS 内部可能重新索引,导致前一次操作返回的 `anchor_id` 失效。如果不处理,后续内容会静默跳过,造成文章后半段内容丢失。

**必须实现重试逻辑**:

def do_insert(note_id, content, get_anchor_fn, max_retries=4):
    """带重试的内容插入,自动刷新 anchor"""
    anchor = get_anchor_fn()
    for attempt in range(max_retries):
        if attempt > 0:
            time.sleep(1.5 * attempt)
            anchor = get_anchor_fn()  # 重新获取最新 anchor
        res = batch_edit(note_id, [{
            'op': 'insert', 'anchor_id': anchor,
            'position': 'after', 'content': content
        }])
        if res.get('ok') is not False:
            anchor = get_anchor_fn()
            return True
    return False  # 4次都失败才放弃

**获取最新 anchor(最后一个 block)**:

def get_last_block_id(note_id):
    r = get_note_outline(note_id=note_id)
    blocks = (r.get('data') or {}).get('blocks', [])
    return blocks[-1]['id'] if blocks else None

---

5. 批量写入的稳定参数

大量内容写入时,`BATCH_SIZE`(每次 `batch_edit` 的 block 数)建议设为 **4**,过大会增加 anchor 失效概率。

BATCH_SIZE = 4  # 不要超过 8,否则容易出现 anchor 失效

---

完整工作流

第一步:确定扫描目录

**优先根据用户已给出的目录 / 文件线索判断来源类型,不足时再 `ask_user` 补最少必要信息:**

优先识别这些常见来源线索:
- Obsidian Vault:`.md` 文件 + `attachments/` 或同类附件目录
- 思源笔记:`.sy` 文件 + `data/assets/`
- 微信公众号存档:`原文.html` + 图片目录 + `meta.json`
- 下载目录混合导入:PDF / DOCX / PPTX / XLSX / Markdown / HTML 混合存在

---

第二步:扫描文档列表

如需对照扫描规则,用 `read_file("scripts/scan_docs.py")` 查看来源识别和输出字段约定;
整理后的清单至少要包含路径、标题、时间、格式、图片数和预计 block 数。

**输出 JSON 格式:**

{
  "source_type": "wechat_mp",
  "root_path": "/Users/xxx/Documents/articles",
  "files": [
    {
      "path": "/Users/xxx/Documents/articles/文章名/原文.html",
      "rel_path": "文章名/原文.html",
      "title": "文章标题",
      "publish_time": "2025-04-21 18:30",
      "size_bytes": 204800,
      "modified": "2025-04-22T10:00:00",
      "format": "html",
      "estimated_images": 12,
      "estimated_blocks": 180
    }
  ],
  "total": 71,
  "formats": {"html": 71}
}

> `estimated_blocks` 帮助预判是否会超过 100 block,提前提示用户。

---

第三步:展示文件清单,询问选择

扫描到 71 个文件:
  - HTML: 71 个

文件列表:
 1. AutoGLM 发布之后,如今国产大模型终于长出了手。  (2025-03-31, 12张图)
 2. 你可能看不懂扣子空间为什么重要…                 (2025-04-21, 17张图)
 ...(超过20个时截断,告知总数)

请问你想如何导入?
 [A] 全部导入(71个文件)
 [B] 手动选择(输入文件编号,如:1,3,5-10)
 [S] 跳过已有标题的笔记(根据笔记标题去重)

---

第四步:去重检测

导入前通过标题检查 WPS 笔记中是否已存在同名笔记。

**注意**:不要把 `list_notes` 当成去重主入口,改用 `search_notes` 按标题关键词搜索:

def check_exists(title):
    r = search_notes(keyword=title[:20], limit=5)
    notes = (r.get('data') or {}).get('notes', [])
    return next((n for n in notes if n['title'] == title), None)

**发现重复时询问用户:**

发现以下笔记在 WPS 中
Read more
Ships withwpsnote-skills

笔记,是思想落地的地方。 本仓库以 wps-note 为基础能力底座,让 Claude Code、Cursor、OpenClaw 等主流 AI Agent 直接驱动 WPS 笔记——往里写、从里读、让它有序、让它被找到。 笔记不再是你自己整理的地方,而是 Agent 替你打理的记忆层。

Get the whole plugin

Other skills on wpsnote-skills.

class-note-builder
Skill

class-note-builder

当用户希望把课堂逐字稿、OCR 笔记、截图资料或零散学习内容整理成结构化的 WPS 学习笔记时使用此 Skill。适合课堂记录整理、培训复盘、补课笔记汇总、课程主笔记构建等场景,尤其适合原始材料很乱、但最终需要一篇可复习、可回看、可继续补充的主笔记时。

coding-assistant
Skill

coding-assistant

多平台编码助手。遵循各平台官方文档做编码规范、单测与编译/lint;协助将核心技术梳理为完整 WPS 笔记技术文档。生成的笔记必须包含 7…

content-creator
Skill

content-creator

【内容创作起点】用户想要写文章/公众号/文案时的首选skill。 触发词:"帮我写""我想写""准备写""开始写""写个文章""写篇稿子""写公众号""写小红书""仿照这个风格写""分析我的写作风格""提取写作模板"。…

content-digest
Skill

content-digest

将任意内容提炼为结构化知识笔记,自动保存到 WPS 笔记。只要用户给出任何内容(链接、图片、本地文件、粘贴文字)并有保存笔记的意图,就应使用此…

ie-connect-dots
Skill

ie-connect-dots

对笔记和想法进行语义聚类、发现想法之间的隐含连接、识别长期重复出现的主题模式。当用户提到"连接想法"、"发现关联"、"想法聚类"、"找到模式"、"这些笔记有什么联系"等需要理解多条笔记之间关系的场景时使用此技能。此技能属于灵感引擎(ie-)推理层,专门处理想法…