根据数据和模板批量生成Markdown文件

Obsidian真是一个绝佳的笔记软件,特别是当我意识到,如果拿它整理游戏资料的话,就相当于做了一个本地Wiki。我终于不用再为每一个心爱的游戏写一个长长的word文档了,简直是游戏肥宅的新纪元。

不过,要把游戏资料真正整理成一个本地Wiki,就要好好利用其双向链接功能,为每一个人物/道具/技能……都建立一个.md文件才好。想也知道一个个手写实在是太痛苦了。游戏Wiki对此又是怎么做的呢?我研究了一下灰机Wiki,发现游戏Wiki的管理员可以利用工具批量上传游戏原始数据,使用自己设置的模板生成Wiki页面。那么对应到Obsidian的话,就应当致力于使用一个数据表和一个编辑好的.md模板,就能批量生成文件。

于是接下来我就研究要如何实现这一点。本着能偷懒就偷懒的原则,我先搜索了一下Obsidian的第三方插件,发现还真有一个这种用途的插件,叫做JSON/CSV Importer。遗憾的是,这个插件似乎只支持英文,使用中文会导出一堆乱码,应当是编码转换的问题。但插件我也不会改,想了想,干脆自己拿Python写一个。

从模板批量生成文件其实是办公自动化的常见话题了,不过基本上都是根据Excel数据表生成Word文件,大概没有多少人热衷于像我一样用Markdown做本地Wiki。生成.md文件实现起来又更容易一些,因为Markdown文件本质上就是个文本文件,只需要安装一个openpyxl模块读取Excel文件就可以了。

(顺便一提,网上看到的一些用Python实现批量生成Word文件的代码简直复杂到离谱,让我深深怀疑是不是越不会写代码的人越喜欢上网显摆……哎,说起来我好像也是。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# --------------------------
# 根据数据(Excel文件)和模板(Markdown文件),批量生成.md文件,以某一列数据命名
# 模板中对应数据统一写作{{某列名}},如更改需修改searchStr变量
# 文件输出到export子文件夹下
# --------------------------

#coding=utf-8

# pip3 install openpyxl
import openpyxl

# 自定义修改区域
pathData = '数据表.xlsx' # 数据路径
pathTemplate = '模板.md' # 模板文件路径
nameColumn = 1 # 文件名所在列

# 读取数据所在sheet(默认为第一个sheet)
dataSheet = openpyxl.load_workbook(pathData).active

# openpyxl读取Excel的索引从1开始
# range函数是左闭右开,所以最大行数和最大列数要+1
for r in range(2, dataSheet.max_row+1): # 遍历行,从第二行开始(跳过标题行),每行替换数据并生成文件
content = open(pathTemplate,'r', encoding='UTF-8').read() # 读取模板文件
for c in range(1, dataSheet.max_column+1): # 遍历列,从第一列开始
searchStr = '{{' + str(dataSheet.cell(row=1, column=c).value) + '}}' # {{该列列名}}
replaceStr = str(dataSheet.cell(row=r, column=c).value) # 对应行、列的数据
content = content.replace(searchStr, replaceStr) # 替换文本
fileName = str(dataSheet.cell(row=r, column=nameColumn).value) # 储存文件名所在列数据
exportFile = open('export/' + str(fileName) + '.md', 'w', encoding='UTF-8') # 在export子文件夹下新建文件
exportFile.write(content) # 写入替换后的文本
exportFile.close()
print('已创建文件:' + str(fileName) + '.md')

print('文件批量创建完毕!')

虽然写的过程中有些波折(毕竟我菜),但成功地解决了批量生成文件的问题,可以快乐写本地Wiki了,十分开心。由此可见,人还是得学点代码,可以不去做码农,但绝对不能妨碍我整理游戏数据。