一键生成[合并 颜色 字体]基于Python【附完整代码】"/>
Markdown复杂表格一键生成[合并 颜色 字体]基于Python【附完整代码】
文章目录
-
多样化、复杂化表格的需求 - 写在前面的话:
- 写在前面的话:
-
于是乎,通过一番观察思索,发现实现起来也不难 - 这是一个较为复杂表格的代码,借此来分析
-
构造模板,给入数据,一键生成! - 1. 取最小单元:一格 作为模板
- 2. 而后通过循环,逐一套入数据、参数,并将表格数据拼接
- 从文本获取模板所需数据--代码:
- 表头设计--代码:
- 表格设计--代码:
- 表格构建--代码:
- 总代码
当然此处的markdown指的是csdn的markdown |
多样化、复杂化表格的需求 |
写在前面的话:
当然,csdn的markdown编辑器已经有快捷的表格建立语法。
但是很可惜的是,只能按固定格式创建,就是所创建的表格每一行的列数是固定的,相同的。如下
大多数情况下,这种表格已经能满足一些需求。但有时候,我们需要做一些“合并单元格”,“颜色标注”来灵活使用表格,于是这种简单使用的语法,就不能满足了。
要是耐心搜索的话,也能在csdn上搜寻到用markdown制作高级表格的方法——像写Html一样。【如下】
要是码字速度够快,对html语法熟悉,那完全可以每次随手一码。
不过要是能够有直接喂给数据,然后按要求生成表格数据的脚本,那岂不是快哉,快男的快,快的一批的快。
于是乎,通过一番观察思索,发现实现起来也不难 |
-
这是一个较为复杂表格的代码,借此来分析
<table>
<tr><td rowspan=1 colspan=1 align=center bgcolor=white><font color=k size=4 face=YaHei>内容</font></td><td rowspan=1 colspan=2 align=center bgcolor=#f0f0f0><font color=b size=4 face=YaHei>说明</font></td>
</tr>
<tr><td rowspan=3 colspan=1 align=center bgcolor=white><font color=k size=5 face=YaHei>飞出个未来</font></td><td rowspan=1 colspan=1 align=left bgcolor=white><font color=b size=4 face=楷体>人名</font></td><td rowspan=1 colspan=1 align=left bgcolor=white><font color=orange size=4 face=楷体>翻译</font></td>
</tr>
<tr><td rowspan=1 colspan=1 align=left bgcolor=#f0f0f0><font color=b size=4 face=楷体>Fry</font></td><td rowspan=1 colspan=1 align=left bgcolor=#f0f0f0><font color=orange size=4 face=楷体>弗莱</font></td>
</tr>
<tr><td rowspan=1 colspan=1 align=left bgcolor=white><font color=b size=4 face=楷体>Leela</font></td><td rowspan=1 colspan=1 align=left bgcolor=white><font color=orange size=4 face=楷体>利拉</font></td>
</tr>
<tr><td rowspan=3 colspan=1 align=center bgcolor=white><font color=k size=5 face=YaHei>马男</font></td><td rowspan=1 colspan=1 align=left bgcolor=#f0f0f0><font color=b size=4 face=楷体>人名</font></td><td rowspan=1 colspan=1 align=left bgcolor=#f0f0f0><font color=orange size=4 face=楷体>翻译</font></td>
</tr>
<tr><td rowspan=1 colspan=1 align=left bgcolor=white><font color=b size=4 face=楷体>bojack</font></td><td rowspan=1 colspan=1 align=left bgcolor=white><font color=orange size=4 face=楷体>波杰克</font></td>
</tr>
<tr><td rowspan=1 colspan=1 align=left bgcolor=#f0f0f0><font color=b size=4 face=楷体>diane</font></td><td rowspan=1 colspan=1 align=left bgcolor=#f0f0f0><font color=orange size=4 face=楷体>戴安</font></td>
</tr>
</table>
内容 | 说明 | |
飞出个未来 | 人名 | 翻译 |
Fry | 弗莱 | |
Leela | 利拉 | |
马男 | 人名 | 翻译 |
bojack | 波杰克 | |
diane | 戴安 |
不难发现:
- 整个表格的内容,都在一个 <table>。。。</table> 节点中。
- 每一“行”表格的内容都在一个 <tr>。。。</tr> 节点中。
- 每一格表格的内容都在一个 <td>。。。</td> 节点中。
- 每格内容字体参数由 <font>。。。</font> 节点控制。
- 表格的具体跨度(合并)由 <td>。。。</td> 节点中的 rowspan 和 colspan 参数来控制
- 一些参数说明如下
参数 | 说明 | |
rowspan | 行跨度 | 整数 |
colspan | 列跨度 | 整数 |
align | 对齐 | left、center、right |
bgcolor | 背景颜色 | 颜色名[red、blue...]/十六进制[#f0f0f0] |
color | 字体颜色 | 颜色名[red、blue...]/十六进制[#f0f0f0] |
size | 字体大小 | 整数 |
face | 字体 | 楷体、宋体、YaHei、仿宋。。。 |
构造模板,给入数据,一键生成! |
思路说明:
1. 取最小单元:一格 作为模板
pt = f'''\t<td rowspan={rowspan} colspan={colspan} align={align} bgcolor={bg}>
\t\t<font color={fcolor} size={fsize} face={font}>{text}</font>
\t</td>
<td rowspan=1 colspan=1 align=center bgcolor=yellow><font color=0 size=0 face=0>没有内容</font></td>
没有内容 |
2. 而后通过循环,逐一套入数据、参数,并将表格数据拼接
这里是最核心的地方。【各部分代码在最后】
- 首先,对输入的数据作何约束,才方便处理?
对于 表头(首行数据),通常需要它的列跨度灵活,就是一格占多列。于是规定每一格内容最后,加上所占的列数【与总列数相符–总列数依据总数据判断】,同一行每列数据中文逗号隔开。
如下:表头共两格,‘内容’格占一列,‘说明’格占两列【效果参考开头的表格】
内容1,说明2
于是希望从该行数据提取到如下信息
title = [['内容', 1], ['说明', 2']]
对于 内容(详细数据),通常需要它的行跨度灵活,就是一格占多行。于是规定每一个占多行的内容,其最后加上所占行数,而且之后行的该列数据为空。同一行每列数据中文逗号隔开。
如下:‘飞出个未来’格占三行,其后两行该列数据为空【效果参考如下】
飞出个未来3,人名,翻译
,Fry,弗莱
,Leela,利拉
马男3,人名,翻译
,bojack,波杰克
,diane,戴安
飞出个未来 | 人名 | 翻译 |
Fry | 弗莱 | |
Leela | 利拉 | |
马男 | 人名 | 翻译 |
bojack | 波杰克 | |
diane | 戴安 |
所期望从文本中提取的数据:
body = [['飞出个未来3', '人名', '翻译'],['', 'Fry', '胡莱'],['', 'Leela', '利拉'],['马男3', '人名', '翻译'],['', 'Bojack', '波杰克'],['', 'Diane', '戴安'], ]
表头的列表很容易提取到信息,但是如上的就稍微绕了。抓住主要矛盾:获取特殊格的行跨度。如何判断是特殊格子呢?很简单,(当前格子内容不为空)and(下一行该位置内容为空),那么其列跨度就是内容之后的数字。【当然有想过直接通过循环之后的空格数来获取列跨度,但是觉得循环算法总给人费时的印象,哈哈,也可能是觉得数据里多写个数字,比写循环要偷懒的多。
而其他参数,就不必包含在数据里了,可以固定化处理,实在想调整的话,倒腾代码吧,设计程序的时候留了后路,也不难实现!
从文本获取模板所需数据–代码:
def get_list(self, filepath):with open(filepath, 'r', encoding='utf8') as f:for line in f.readlines():# 先分割数据texts = line.rstrip('\n').split(',')# 将第一行数据处理后存入 表头列表if not self.title:for tle in texts:tl = [self.text.findall(tle)[-1], int(self.num.findall(tle)[-1])]self.title.append(tl)else:# 其余的存入内容列表self.datas.append(texts)
表头设计–代码:
def make_title(self, fsize=4, fcolor=['k', 'b', 'orange'],\font='YaHei', bg=['white', '#f0f0f0', 'snow', '#f0f0f0']):title = '<tr>\n{}\n</tr>'rowspan = 1align = 'center'lst = ''for i in range(len(self.title)):colspan = self.title[i][-1]text = self.title[i][0]if lst:lst += '\n'lst += self.one.format(rowspan, colspan, align, bg[i % len(bg)],fcolor[i % len(fcolor)], fsize, font, text)return title.format(lst)
表格设计–代码:
def make_body(self, align=['center', 'left', 'left'], bg=['white', '#f0f0f0'],fcolor=['k', 'b', 'orange'], fsize=[5, 4, 4, 4], font=['YaHei', '楷体', '楷体'],):allrow = len(self.datas)cols = len(self.datas[0])colspan = 1body = ''for i in range(allrow):fmt = '<tr>\n{}\n</tr>'lst = ''# 循环一行的每一列内容,以构造一行for j in range(cols):# 如果该行 j列有内容,进行操作if self.datas[i][j]:text = self.datas[i][j]rowspan = 1# 判断之前是否有加入内容单元,有的话换行if lst:lst += '\n'else:pass# 判断,从而获取 行跨度/纠正内容if i < allrow-1:# 如果下一行同一位置内容为空,获取行跨度if not self.datas[i+1][j]:rowspan = int(self.num.findall(text)[-1])# 纠正内容text = self.text.findall(text)[0]if not j:bgc = 'white'else:bgc = bg[i % len(bg)]lst += self.one.format(rowspan, colspan, align[j % len(align)], bgc,fcolor[j % len(fcolor)], fsize[j % len(fsize)], font[j % len(font)], text)else:continueif body:body += '\n'body += fmt.format(lst)return body
表格构建–代码:
def make_html(self, filepath):self.get_list(filepath)html = '<table>\n{}\n{}\n</table>'title = self.make_title()body = self.make_body()html = html.format(title, body)with open(f'{self.title[0][0]}.html', 'w', encoding='utf8') as f:f.write(html)f.close()print(html)
总代码
import reclass Markct():def __init__(self):self.title = []self.datas = []self.num = repile(r'\d+$')self.text = repile(r'.+[\D]')self.one = '\t<td rowspan={} colspan={} align={} bgcolor={}>' \'\n\t\t<font color={} size={} face={}>{}</font>\n\t</td>'def get_list(self, filepath):with open(filepath, 'r', encoding='utf8') as f:for line in f.readlines():texts = line.rstrip('\n').split(',')if not self.title:for tle in texts:tl = [self.text.findall(tle)[-1], int(self.num.findall(tle)[-1])]self.title.append(tl)else:self.datas.append(texts)def make_html(self, filepath):self.get_list(filepath)html = '<table>\n{}\n{}\n</table>'title = self.make_title()body = self.make_body()html = html.format(title, body)with open(f'{self.title[0][0]}.html', 'w', encoding='utf8') as f:f.write(html)f.close()print(html)def make_body(self, align=['center', 'left', 'left'], bg=['white', '#f0f0f0'],fcolor=['k', 'b', 'orange'], fsize=[5, 4, 4, 4], font=['YaHei', '楷体', '楷体'],):allrow = len(self.datas)cols = len(self.datas[0])colspan = 1body = ''for i in range(allrow):fmt = '<tr>\n{}\n</tr>'lst = ''# 循环一行的每一列内容,以构造一行for j in range(cols):# 如果该行 j列有内容,进行操作if self.datas[i][j]:text = self.datas[i][j]rowspan = 1# 判断之前是否有加入内容单元,有的话换行if lst:lst += '\n'else:pass# 判断,从而获取 行跨度/纠正内容if i < allrow-1:# 如果下一行同一位置内容为空,获取行跨度if not self.datas[i+1][j]:rowspan = int(self.num.findall(text)[-1])# 纠正内容text = self.text.findall(text)[0]if not j:bgc = 'white'else:bgc = bg[i % len(bg)]lst += self.one.format(rowspan, colspan, align[j % len(align)], bgc,fcolor[j % len(fcolor)], fsize[j % len(fsize)], font[j % len(font)], text)else:continueif body:body += '\n'body += fmt.format(lst)return bodydef make_title(self, fsize=4, fcolor=['k', 'b', 'orange'], font='YaHei', bg=['white', '#f0f0f0', 'snow', '#f0f0f0']):title = '<tr>\n{}\n</tr>'rowspan = 1align = 'center'lst = ''for i in range(len(self.title)):colspan = self.title[i][-1]text = self.title[i][0]if lst:lst += '\n'lst += self.one.format(rowspan, colspan, align, bg[i % len(bg)],fcolor[i % len(fcolor)], fsize, font, text)return title.format(lst)n = Markct()
n.make_html('data1.txt')
更多推荐
Markdown复杂表格一键生成[合并 颜色 字体]基于Python【附完整代码】
发布评论