有趣的便签网站-使用Sdcb.WordCloud生成词云图
前言
最近也是忙着面试、背题,终于闲下来,也是来更新下网站顺便写一篇文章~
上周在网上看到一个静态的便签网站,我也是拿来用并发布了一篇文章,找到一个有趣的便签墙网站 - ZY知识库,后续也是制作了一个可以提交内容的便签网站,也发布了一篇文章,可以提交内容的便签墙来了 - ZY知识库。
这两篇文章都比较火,特别是可以提交内容的便签网站,截止今日,已经有4000 千多条评论,去除重复的也有3000 多条,保守估计,网站搭建至今,访问人数和使用人数应该总和有100+。
大部分人提交的内容都是表白、鼓励、吐槽之类的内容,也有一些人发布了恶意评论,当然已经被我删除掉了。
需要注意的是,网站默认 只会展示最新的150 条信息,如果你发现你之前的信息找不到了,刷新网页好多次还是没看到,那么可能排序到最新的第150条数据后面去了。
下面是网站发布以来更新的内容
- 2025/11/04 限制内容长度不能超过30字
- 2025/11/05 限制
xss攻击 - 2025/11/06 高估互联网的素质了,还是加上了关键词过滤
- 2025/11/07 被恶意刷屏,无奈添加接口限流
那么也是为了看看大家都发布的什么内容,也是心血来潮想着用词云图实现一下,通过数据清洗、筛选来看看出现频率最高的词语有哪些,并用 词云图 的形式展示出来,话不多说开始操作。
便签网站直达地址:https://pljzy.top/noteweb
前端设计
前端页面就很简单的设计了一个词云图跳转按钮,通过点击这个按钮可以查看词云图。

后端设计
后端采用的是.Net框架,那么生成词云图必然也是.Net框架下的包,我这里使用的是 Sdcb.WordCloud 包。
csharp
dotnet add package Sdcb.WordCloud
这个包Star 数比较少,可能因为词云图本身不是很知名吧,之前绘制词云图还是学校时期用 python 绘制过。不得不说 python 的包是又多又方便~
sdcb/Sdcb.WordCloud: Generate WordCloud image from .NET/.NET Core
踩坑指南
我在本地 windows 环境下生成词云图是没问题的,当我部署到 Liunx 系统下时,会提示缺少依赖,后面发现需要手动导入 SkiaSharp.NativeAssets.Linux.NoDependencies 包。
csharp
dotnet add package SkiaSharp.NativeAssets.Linux.NoDependencies
关键代码
csharp
public async Task GenerateWordCloud()
{
try
{
using var scope = _serviceProvider.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<MyDbContext>();
var allNotes = await db.Notes.Select(n => n.Content).ToListAsync();
var text = string.Join(" ", allNotes);
// 处理文本并生成词频统计
var words = ProcessText(text)
.GroupBy(word => word)
.ToDictionary(g => g.Key, g => g.Count())
.OrderByDescending(kv => kv.Value) // 按词频降序排序
.Take(150) // 取前150个高频词
.ToDictionary(kv => kv.Key, kv => kv.Value)
.Select(kv => new WordScore(kv.Key, kv.Value)); // 转换为WordScore对象集合
// 创建词云实例,设置画布大小为1000x1000
WordCloud wc = WordCloud.Create(new WordCloudOptions(1000, 1000, words));
byte[] pngBytes = wc.ToSKBitmap().Encode(SKEncodedImageFormat.Png, 100).AsSpan().ToArray();
string filePath = "wwwroot/wordcloud.png";
// 将PNG图片保存到文件
await File.WriteAllBytesAsync(filePath, pngBytes);
_logger.LogInformation($"词云图已更新: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
}
catch (Exception ex)
{
_logger.LogError(ex, "生成词云图时发生错误");
}
}
这里由于各方面因素影响,只获取了词频出现最多的前 150 条数据。
定时任务
由于词云图生成比较慢,我试了一下150条数据,生成大概要 20~30s ,如果做成接口的话响应很慢,用户体验也不好。
那么我也是采用后台定时任务去执行,我使用的是 Hangfire ,每隔4小时重新绘制一次图像。
csharp
dotnet add package Hangfire
dotnet add package Hangfire.MemoryStorage
关键代码
csharp
builder.Services.AddHangfire(config =>
config.UseMemoryStorage());
builder.Services.AddHangfireServer();
// 每天0:00, 4:00, 8:00, 12:00, 16:00, 20:00执行
RecurringJob.AddOrUpdate<WordCloudService>(
"generate-wordcloud",
service => service.GenerateWordCloud(),
"0 0,4,8,12,16,20 * * *");
多提一嘴
Hangfire 可以选择是否开启仪表板,仪表板截图如下,用来查看任务执行情况还是挺方便的。

词云图效果
好像大家都有喜欢的人呀,词云图每隔4小时更新一次,如果发现自己发的文字没有在里面可能是出现频率不高,不过不建议大家刷留言~

结尾
如果对项目源代码感兴趣的可以访问 Github 并点上 Star ,ZyPLJ/NoteWeb: 便签墙带后端版本,可以随心所欲(注意文明用语)的发送便签~。
这个项目也就到这里结束了,后续不会更新内容,网站会一直存在,除非服务器到期和其他不可避免因素导致网站关闭。
总的来说,这是一个很有趣的项目,希望能一直存在下去~