本文目录导读:

网页版(最实用,支持导入名单)
完整HTML代码(保存为.html文件即可使用)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">随机点名系统</title>
<style>
body {
font-family: 'Microsoft YaHei', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.container {
background: white;
padding: 30px;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
width: 600px;
max-width: 90vw;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 20px;
}
textarea {
width: 100%;
height: 100px;
padding: 12px;
border: 2px solid #ddd;
border-radius: 8px;
font-size: 14px;
resize: vertical;
margin-bottom: 10px;
}
.btn-group {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.btn {
flex: 1;
padding: 12px;
border: none;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
transition: all 0.3s;
font-weight: bold;
}
.btn-primary {
background: #4CAF50;
color: white;
}
.btn-primary:hover:not(:disabled) {
background: #45a049;
transform: translateY(-2px);
}
.btn-danger {
background: #f44336;
color: white;
}
.btn-danger:hover {
background: #da190b;
}
.btn-warning {
background: #ff9800;
color: white;
}
.btn-warning:hover {
background: #e68a00;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.display-area {
text-align: center;
padding: 30px;
background: #f8f9fa;
border-radius: 10px;
margin: 20px 0;
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
}
#currentName {
font-size: 48px;
font-weight: bold;
color: #333;
animation: none;
}
#currentName.rolling {
animation: shake 0.1s infinite;
color: #ff9800;
}
@keyframes shake {
0% { transform: translateX(-5px); }
50% { transform: translateX(5px); }
100% { transform: translateX(-5px); }
}
.error-msg {
color: red;
font-size: 14px;
margin-top: 5px;
display: none;
text-align: center;
}
#status {
text-align: center;
color: #666;
font-size: 14px;
margin-top: 10px;
}
#history {
margin-top: 20px;
border-top: 1px solid #ddd;
padding-top: 10px;
display: none;
}
#history h3 {
color: #333;
margin-bottom: 10px;
}
#historyList {
list-style: none;
padding: 0;
margin: 0;
max-height: 150px;
overflow-y: auto;
}
#historyList li {
padding: 8px;
background: #f8f9fa;
margin-bottom: 5px;
border-radius: 5px;
border-left: 3px solid #4CAF50;
}
#count {
text-align: center;
color: #999;
font-size: 12px;
margin-top: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1>🎯 随机点名系统</h1>
<div class="btn-group">
<button class="btn btn-warning" onclick="addExample()">加载示例名单</button>
<button class="btn btn-danger" onclick="clearAll()">清空名单</button>
</div>
<textarea id="nameList" placeholder="请输入名单(每行一个名字) 张三 李四 王五" ></textarea>
<div id="count"></div>
<div class="btn-group">
<button class="btn btn-primary" id="startBtn" onclick="startRoll()">🎲 开始点名</button>
<button class="btn btn-danger" id="stopBtn" onclick="stopRoll()" disabled>🛑 停止</button>
<button class="btn btn-warning" id="nextBtn" onclick="rollOnce()" disabled>下一页</button>
</div>
<div class="display-area">
<div id="currentName">点击"开始点名"</div>
</div>
<div class="error-msg" id="errorMsg"></div>
<div id="status"></div>
<div id="history">
<h3>📋 已点名记录</h3>
<ul id="historyList"></ul>
</div>
</div>
<script>
let names = [];
let rollTimer = null;
let userName = '';
let history = [];
let rolledNames = new Set();
let currentIndex = 0;
function getNames() {
const text = document.getElementById('nameList').value.trim();
if (!text) {
showError('请先输入名单');
return null;
}
return text.split('\n').map(n => n.trim()).filter(n => n);
}
function updateCount() {
const allNames = getNames();
document.getElementById('count').textContent = allNames ? `共 ${allNames.length} 个名字,已点名 ${rolledNames.size} 个` : '';
}
function showError(msg) {
const err = document.getElementById('errorMsg');
err.textContent = msg;
err.style.display = 'block';
setTimeout(() => { err.style.display = 'none'; }, 3000);
}
function addExample() {
const example = '张三\n李四\n王五\n赵六\n孙七\n周八\n吴九\n郑十\n钱十一\n陈十二';
document.getElementById('nameList').value = example;
updateCount();
}
function clearAll() {
document.getElementById('nameList').value = '';
document.getElementById('currentName').textContent = '点击"开始点名"';
document.getElementById('history').style.display = 'none';
document.getElementById('historyList').innerHTML = '';
history = [];
rolledNames.clear();
document.getElementById('nextBtn').disabled = true;
document.getElementById('startBtn').disabled = false;
stopRoll();
updateCount();
}
function startRoll() {
names = getNames();
if (!names) return;
if (names.length === 0) {
showError('名单为空');
return;
}
// 重置状态
if (rolledNames.size > 0) {
rolledNames.clear();
history = [];
document.getElementById('historyList').innerHTML = '';
document.getElementById('history').style.display = 'none';
}
document.getElementById('startBtn').disabled = true;
document.getElementById('stopBtn').disabled = false;
document.getElementById('currentName').classList.add('rolling');
// 开始滚动动画
rollTimer = setInterval(() => {
const randomIndex = Math.floor(Math.random() * names.length);
document.getElementById('currentName').textContent = names[randomIndex];
}, 50);
}
function stopRoll() {
clearInterval(rollTimer);
rollTimer = null;
document.getElementById('stopBtn').disabled = true;
document.getElementById('startBtn').disabled = false;
document.getElementById('currentName').classList.remove('rolling');
// 重新决定选人
rollOnce();
}
function rollOnce() {
names = getNames();
if (!names) return;
if (rolledNames.size >= names.length) {
document.getElementById('currentName').textContent = '所有人都已被点名!';
document.getElementById('nextBtn').disabled = true;
return;
}
// 从未点名的中选
let available = [];
for (let i = 0; i < names.length; i++) {
if (!rolledNames.has(i)) {
available.push({index: i, name: names[i]});
}
}
if (available.length === 0) return;
// 快速滚动效果
let counter = 0;
const totalFrames = 20;
const animate = () => {
counter++;
const randomIndex = Math.floor(Math.random() * available.length);
document.getElementById('currentName').textContent = available[randomIndex].name;
if (counter < totalFrames) {
setTimeout(animate, 50);
} else {
// 最终选择
const finalIdx = Math.floor(Math.random() * available.length);
const selected = available[finalIdx];
userName = selected.name;
document.getElementById('currentName').textContent = selected.name;
// 记录
rolledNames.add(selected.index);
history.push(userName);
// 更新历史记录
const historyList = document.getElementById('historyList');
const li = document.createElement('li');
li.textContent = `${history.length}. ${userName}`;
historyList.insertBefore(li, historyList.firstChild);
document.getElementById('history').style.display = 'block';
// 更新按钮状态
if (rolledNames.size >= names.length) {
document.getElementById('nextBtn').disabled = true;
document.getElementById('startBtn').disabled = true;
} else {
document.getElementById('nextBtn').disabled = false;
}
updateCount();
}
};
animate();
}
// 监听输入变化更新计数
document.getElementById('nameList').addEventListener('input', updateCount);
// 初始化
updateCount();
</script>
</body>
</html>
Python脚本版(命令行使用)
保存为 random_call.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import random
import time
def main():
print("🎯 随机点名系统")
print("=" * 30)
# 获取名单
names = []
print("请输入名字(每行一个,输入'q'结束):")
while True:
n = input("> ").strip()
if n == 'q':
break
if n:
names.append(n)
if not names:
print("名单为空!")
return
print(f"\n✅ 已加载 {len(names)} 个名字")
print("=" * 30)
rolled = set()
all_done = False
while not all_done:
print("\n选项:")
print("1. 随机点名 (可跳过已点过的)")
print("2. 不重复点名")
print("3. 显示名单")
print("4. 退出")
print("5. 重置已点名单")
choice = input("\n请选择: ").strip()
if choice == '1':
name = random.choice(names)
print(f"\n🎲 点到的名字: {name}")
elif choice == '2':
available = list(set(names) - rolled)
if not available:
print("\n⚠️ 所有人都已被点名!")
else:
name = random.choice(available)
rolled.add(name)
print(f"\n🎲 点到的名字: {name} (已点名 {len(rolled)}/{len(names)})")
elif choice == '3':
print("\n📋 名单:")
for i, n in enumerate(names, 1):
status = "✅" if n in rolled else "⬜"
print(f"{i}. {status} {n}")
elif choice == '5':
rolled.clear()
print("\n✅ 已重置点名记录")
elif choice == '4':
print("再见!")
break
else:
print("无效选项")
if __name__ == "__main__":
main()
运行方法:
python3 random_call.py
Excel/VBA版(适合办公使用)
在Excel中按 Alt+F11 打开VBA编辑器,插入模块粘贴以下代码:
Sub 随机点名()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
If lastRow < 2 Then
MsgBox "请先在A2开始输入名单!", vbExclamation
Exit Sub
End If
Dim count As Long
count = lastRow - 1
If ws.Range("C1").Value = "" Or ws.Range("C1").Value = count Then
ws.Range("C1").Value = 0
End If
Dim idx As Long
Randomize
idx = Int((count * Rnd()) + 2)
Dim selected As String
selected = ws.Cells(idx, 1).Value
' 显示结果
ws.Range("C2").Value = selected
' 标记已点名(在B列打勾)
Dim i As Long
For i = 2 To lastRow
If ws.Cells(i, 1).Value = selected Then
ws.Cells(i, 2).Value = "√"
End If
Next i
End Sub
然后在Excel中添加按钮,关联此宏即可。
使用建议
- 网页版最推荐 - 有动画效果,界面友好,支持导入名单
- Python版 - 适合程序员或命令行使用
- Excel版 - 适合办公环境快速使用
您可以根据自己的使用场景选择合适的版本,如果还需要其他功能(如语音播报、成绩排名等),告诉我具体需求,我可以再帮您扩展。