用 Canva 的批量创建(Bulk Create)给一场 120 人的活动做工牌:一个工牌模板 + 一张报名表,一次生成全部工牌。生成前用 Python 脚本清洗报名表:去掉重复和空行、提醒名字太长会溢出、超过 300 行自动拆分、不把手机号带进 Canva。
先看清成品
成品是一份多页的工牌设计,可以下载 PDF 打印。本文附带的
prepare.py已实际运行:3 个测试通过;样例报名表 6 行,输出 4 行干净数据,找出重复 1 条、空姓名 1 条、超长字段 3 处;650 行数据自动拆成 300、300、50 三份。本文环境没有 Canva Pro 账号,批量创建的界面操作没有实际执行。
说明:中国大陆用户使用的是 Canva 可画(canva.cn),账号与国际版不通用,部分功能和素材可能不同。本文按国际版帮助中心编写,菜单名称以你看到的界面为准。
注意:报名表含个人信息,只上传工牌需要的字段(脚本只保留姓名、单位、职位),用完删除,遵守个人信息保护法。批量创建是付费功能,免费版不可用。
做完之后你会得到什么?
| 成果 | 说明 |
|---|---|
| 工牌模板 | 姓名、单位、职位三个文本框 |
| 干净的数据 | bulk.csv,去重、去空格 |
| 问题清单 | problems.txt,哪些人名字太长 |
| 全部工牌 | 一次生成,下载 PDF 打印 |
需要准备哪些环境?
| 项目 | 要求 | 说明 |
|---|---|---|
| Canva 账号 | Pro、Teams、Business 等付费计划 | 帮助中心:批量创建仅限付费计划,并且只能在电脑上用 |
| 报名表 | CSV 或 Excel | |
| Python | 3.8+ | 运行清洗脚本 |
官方限制:每次最多 300 行、150 个数据字段;每个单元格只能放一个媒体文件。
第一步:怎样清洗报名表?
1. 样例报名表
姓名,单位,职位,手机
张伟,星河科技,产品经理,13800000000
李娜, 星河科技 ,设计师,
张伟,星河科技,产品经理,
,某公司,工程师,
欧阳娜娜娜娜娜娜,上海某某某某信息技术有限公司,高级前端开发工程师,
Wang Lei,Nova Labs,Engineer,
2. prepare.py
"""为 Canva 批量创建(Bulk Create)准备数据:检查报名表并输出干净的 CSV。
检查项:必填、去重、超长(会在工牌上溢出)、行数上限(Canva 每次最多 300 行)。
用法:python prepare.py 报名表.csv -> bulk.csv + problems.txt
"""
import csv
import sys
import unicodedata
LIMITS = {"姓名": 6, "单位": 12, "职位": 8} # 按你的工牌模板文本框宽度调整(全角字计 1,半角计 0.5)
MAX_ROWS = 300
def width(s: str) -> float:
return sum(1 if unicodedata.east_asian_width(c) in "WF" else 0.5 for c in s)
def clean(s: str) -> str:
return " ".join((s or "").replace("\u3000", " ").split())
def prepare(rows):
out, problems, seen = [], [], set()
for n, r in enumerate(rows, start=2): # 第 1 行是表头
rec = {k: clean(r.get(k, "")) for k in LIMITS}
if not rec["姓名"]:
problems.append(f"第 {n} 行:姓名为空,已跳过")
continue
key = (rec["姓名"], rec["单位"])
if key in seen:
problems.append(f"第 {n} 行:{rec['姓名']}({rec['单位']})重复,已跳过")
continue
seen.add(key)
for k, lim in LIMITS.items():
if width(rec[k]) > lim:
problems.append(f"第 {n} 行:{k}“{rec[k]}”宽度 {width(rec[k])} 超过 {lim},请缩写或调小字号")
out.append(rec)
batches = [out[i:i + MAX_ROWS] for i in range(0, len(out), MAX_ROWS)]
return batches, problems
def main(path):
with open(path, encoding="utf-8-sig") as f:
batches, problems = prepare(list(csv.DictReader(f)))
for i, b in enumerate(batches, 1):
name = "bulk.csv" if len(batches) == 1 else f"bulk-{i}.csv"
with open(name, "w", newline="", encoding="utf-8-sig") as f:
w = csv.DictWriter(f, fieldnames=list(LIMITS))
w.writeheader()
w.writerows(b)
print(f"{name}:{len(b)} 行")
with open("problems.txt", "w", encoding="utf-8") as f:
f.write("\n".join(problems) + ("\n" if problems else ""))
print(f"发现 {len(problems)} 个问题,见 problems.txt")
if __name__ == "__main__":
main(sys.argv[1])
| 要点 | 说明 |
|---|---|
width() |
汉字算 1、英文字母算 0.5,估算占用宽度 |
LIMITS |
按模板文本框实际能放下的字数调整 |
| 去掉手机号 | 输出只有三列 |
| 300 行拆分 | 符合 Canva 单次上限 |
3. 运行
python prepare.py 报名表.csv
本文实际输出:
bulk.csv:4 行
发现 5 个问题,见 problems.txt
第 4 行:张伟(星河科技)重复,已跳过
第 5 行:姓名为空,已跳过
第 6 行:姓名“欧阳娜娜娜娜娜娜”宽度 8 超过 6,请缩写或调小字号
第 6 行:单位“上海某某某某信息技术有限公司”宽度 14 超过 12,请缩写或调小字号
第 6 行:职位“高级前端开发工程师”宽度 9 超过 8,请缩写或调小字号
和活动负责人确认超长的名字怎么处理(例如单位用简称),改好报名表再运行一次。
测试:
from prepare import prepare, width
def test_width():
assert width("张伟") == 2 and width("Wang Lei") == 4
def test_prepare():
rows = [{"姓名": "张伟", "单位": "星河科技", "职位": "产品经理"},
{"姓名": "张伟", "单位": "星河科技", "职位": "产品经理"},
{"姓名": "", "单位": "x", "职位": ""},
{"姓名": "李娜", "单位": "\u3000星河科技 ", "职位": "设计师"}]
batches, problems = prepare(rows)
assert [r["姓名"] for r in batches[0]] == ["张伟", "李娜"]
assert batches[0][1]["单位"] == "星河科技"
assert any("重复" in p for p in problems) and any("姓名为空" in p for p in problems)
def test_split_300():
rows = [{"姓名": f"人{i}", "单位": "a", "职位": "b"} for i in range(650)]
batches, _ = prepare(rows)
assert [len(b) for b in batches] == [300, 300, 50]
第二步:怎样做工牌模板?
- 创建设计 → 自定义尺寸,例如 90×130 毫米。
- 放三个独立的文本框,先输入示例文字“姓名”“单位”“职位”。
- 用最长的名字测试一次,确认字号合适,再把
prepare.py里的LIMITS改成实际能放下的宽度。
帮助中心强调:每个数据字段要有一个单独的文本框。
第三步:怎样批量生成?
- 编辑器左侧 应用 → 找到 批量创建(Bulk Create)。
- 上传数据,选择
bulk.csv。 - 连接数据:点 自动匹配字段,或者把数据字段拖到对应文本框上。
- 点 继续,Canva 为每一行生成一页。
- 逐页翻看,重点检查
problems.txt里提到的人。 - 共享 → 下载 → PDF 打印。
出问题时该怎么调?
1. 中文乱码
CSV 要用 UTF-8 编码。脚本输出的 bulk.csv 已是 UTF-8(带 BOM),Excel 也能正常打开。
2. 文字溢出文本框
调小 LIMITS 重新检查,或在模板里把文本框改成自动缩小的样式后再生成。
3. 找不到批量创建
确认是付费计划,并且在电脑浏览器或桌面应用里操作。
常见问题怎么处理?
| 现象 | 原因 | 解决方法 |
|---|---|---|
| 超过 300 人 | 单次上限 | 用脚本拆分后分批生成 |
| 想放个人照片 | 每格一个媒体文件 | 照片放进相框,按帮助中心的图片字段方式连接 |
| 有人临时报名 | 已经生成 | 复制一页手动改 |
| 英文名太长 | 半角字符也占宽度 | 已按 0.5 计算 |
| 打印出来尺寸不对 | 打印设置缩放了 | 打印时选“实际大小” |
项目资源
| 用途 | 地址 |
|---|---|
| 批量创建 | https://www.canva.com/help/bulk-create/ |
| 批量创建与数据自动填充 | https://www.canva.com/help/bulk-create-data-autofill/ |
| Canva 价格和计划对比 | https://www.canva.com/pricing/ |
| Canva 可画(中国大陆) | https://www.canva.cn/ |
建议先用 5 行测试数据走完整个流程,打印一张确认尺寸和字号。
确认无误后再导入完整名单,生成后由第二个人再检查一遍姓名。