使用 cnchar 生成汉字拼音、笔画、组词数据(Node.js 实战教程)

一、使用场景

在汉字学习、识字类项目中,通常需要提前生成:

  • 汉字
  • 拼音(带声调)
  • 笔画数
  • 笔画类型(横竖撇捺等)
  • 常见组词

本文使用 Node.js + cnchar 生成 JSON 数据,供后端直接导入数据库使用。


二、安装依赖

bash 复制代码
npm install cnchar cnchar-order cnchar-poly cnchar-words cnchar-voice

三、生成脚本

generate_char_data1.js

js 复制代码
// generate_char_data_for_execjs.js
// Node ESM / execjs / cnchar
// 生成:拼音 / 笔画数 / 笔画名 / 原始笔画数据

import cnchar from 'cnchar';
import order from 'cnchar-order';
import poly from 'cnchar-poly';
import words from 'cnchar-words';
import voice from 'cnchar-voice';
import fs from 'fs';

// =======================
// 1️ 注册插件
// =======================
cnchar.use(order, poly, words, voice);
// =======================
// 2️ 获取单字数据
// =======================
function getCharacterData(char) {
  try {
    // 拼音
    const spell = cnchar.spell(char, 'tone');
    const pinyin = Array.isArray(spell) ? spell.join(' / ') : spell || '';

    // 笔画数
    const strokeCount = cnchar.stroke(char) || 1;

    // 笔画名称(标准)
    const strokeNameList = cnchar.stroke(char, 'order', 'name');
    const strokeNames = Array.isArray(strokeNameList)
      ? strokeNameList.join(',')
      : '';

    // ⭐ 原始笔画(detail 模式)
    const strokeDetailList = cnchar.stroke(char, 'order', 'detail');
    const strokesRaw = cnchar.stroke(char, 'order', 'shape')

    // 组词
    const wordList = cnchar.words(char);
    const wordsStr = Array.isArray(wordList)
      ? wordList.slice(0, 8).join(',')
      : '';

    return {
      character: char,
      pinyin,
      stroke_count: strokeCount,
      stroke_names: strokeNames,
      strokes_raw: strokesRaw,   // 新增字段
      words: wordsStr
    };
  } catch (err) {
    return {
      character: char,
      pinyin: '',
      stroke_count: 1,
      stroke_names: '',
      strokes_raw: [],
      words: ''
    };
  }
}

// =======================
// 3️Node 直接运行示例
// =======================
if (process.argv[1] && process.argv[1].includes('generate_char_data')) {
  const chars = ['一', '人', '好', '学', '你', '我'];

  const data = chars.map(getCharacterData);

  fs.writeFileSync(
    './char_data.json',
    JSON.stringify(
      {
        generated_at: new Date().toISOString(),
        total: data.length,
        characters: data
      },
      null,
      2
    ),
    'utf-8'
  );

  console.log(' 已生成 char_data.json(含原始笔画)');
}

// =======================
// 4️ execjs 导出
// =======================
export { getCharacterData };

四、运行脚本

bash 复制代码
node generate_char_data1.js

生成文件:

txt 复制代码
generated_characters.json

五、生成结果示例

json 复制代码
{
  "generated_at": "2025-12-27T02:47:57.131Z",
  "total": 6,
  "characters": [
    {
      "character": "一",
      "pinyin": "Yī",
      "stroke_count": 1,
      "stroke_names": "横",
      "strokes_raw": [
        [
          "一"
        ]
      ],
      "words": "八一,八一队,不一,不一定,创一流,初一,单一,第一"
    },
    {
      "character": "人",
      "pinyin": "Rén",
      "stroke_count": 2,
      "stroke_names": "撇,捺",
      "strokes_raw": [
        [
          "丿",
          "㇏"
        ]
      ],
      "words": "爱人,爱人民,保护人,被告人,北京人,本人,辩护人,别人"
    },
    {
      "character": "好",
      "pinyin": "Hǎo",
      "stroke_count": 6,
      "stroke_names": "撇点,撇,横,横撇|横钩,竖钩,横",
      "strokes_raw": [
        [
          "𡿨",
          "丿",
          "一",
          "㇇|乛",
          "亅",
          "一"
        ]
      ],
      "words": "爱好,爱好者,办好,备好,变好,不好,大好,打好"
    },
    {
      "character": "学",
      "pinyin": "Xué",
      "stroke_count": 8,
      "stroke_names": "点,点,撇,点2,横撇|横钩,横撇|横钩,竖钩,横",
      "strokes_raw": [
        [
          "丶",
          "丶",
          "丿",
          "㇀",
          "㇇|乛",
          "㇇|乛",
          "亅",
          "一"
        ]
      ],
      "words": "爱科学,爱学习,办学,博学,不科学,才学,辍学,初学"
    },
    {
      "character": "你",
      "pinyin": "Nǐ",
      "stroke_count": 7,
      "stroke_names": "撇,竖,撇,横撇|横钩,竖钩,撇,点",
      "strokes_raw": [
        [
          "丿",
          "丨",
          "丿",
          "㇇|乛",
          "亅",
          "丿",
          "丶"
        ]
      ],
      "words": "你的,你好,迷你,你们,你我"
    },
    {
      "character": "我",
      "pinyin": "Wǒ",
      "stroke_count": 7,
      "stroke_names": "撇,横,竖钩,提,斜钩|卧钩,撇,点",
      "strokes_raw": [
        [
          "丿",
          "一",
          "亅",
          "㇀",
          "㇂|㇃",
          "丿",
          "丶"
        ]
      ],
      "words": "你我,忘我,我厂,我处,我方,我国,我局,我军"
    }
  ]
}

六、注意事项(重要)

  • stroke_count 可靠
  • stroke_names 仅用于基础展示
  • 教学级笔顺 / 动画 建议前端使用 HanziWriter
  • 不推荐在 Django / Java 中直接计算笔画

七、总结

  • cnchar 适合 数据预生成
  • Node.js 非常适合做 汉字数据工具脚本
  • 后端只负责存储,前端负责交互与动画
相关推荐
沉默小管13 小时前
我用 NestJS + Nuxt 3 做了个导航站,聊几个踩过的坑
node.js·seo
非优秀程序员1 天前
第02章 杭电的英语老师与一台服务器|《互联网产品恩仇录》
数据库·node.js·代码规范
Hone2 天前
juejin-skills 系列 ②:我把「看掘金热榜」也做成了 Agent 技能
开源·node.js·ai编程
w16632 天前
零 Root 无 PC:我让 AI 在手机上把鸿蒙 HDC 协议的底裤扒了下来
node.js
严肃小白兔3 天前
TanStack Router 更新构建工具链:Node.js 兼容性、路由分割与前端工程实践
前端·node.js·状态模式
一缕82年的清风4 天前
用了 3 年 Notion 和 Obsidian 后,为什么我最终把所有身家搬到了思源笔记?
node.js
Dumbness4 天前
一份 JSON 生成增删改查接口,入参清洗漏了什么:Number(" ") 是 0,搜 100% 把 1000 元券也搜出来
node.js·express
FungLeo5 天前
成为全栈·基础补充·Node.js 运行时:事件循环与异步
javascript·node.js·事件循环·后端开发·异步编程·成为全栈
用户087308654876 天前
用 GUI 自动化写了一个群聊 AI:5 个真实事故,和 7 条让 AI 不像机器人的设计
node.js
Dumbness7 天前
毕设后台导出 CSV 的 4 个坑:date 字段漏了公式防护,搜索框输入 % 能扫全表
node.js·express