一、Excel自动生成Markdown表格的python处理
本文着重解决了以下问题
- 如果有长短不一的单元格存在,markdown自动生成的表格没有对齐,原始文本看起来不够美观;
- 相同长度中英文字符串显示宽度不同,按照字符长度填充,仍然会参差不齐。
- Excel表格如何转换为Markdown文件;
- Excel中一个单元格有多行的情况,如何生成\<br> Markdown换行;
- Excel中有空值,尤其是第一列有空值,格式化后该行其他列会前移;
纯文本的表格是这样的

对齐的表格是这样的
二、程序实现
1. 程序中用到了excel读写,日期时间,导入相关包
import pandas as pd
import sys, datetime
import sys, datetime, csv
2. 获取中英字符串宽度
def get_string_width(msg):
"""
# 获取中英文字符串宽度
"""
width = len(msg)
for word in msg:
if (word >='\u4e00' and word <= '\u9fa5') or word in [';',':',',','(',')','!','?','——','……','、','》','《']:
width+=1
return width
3. 获取每一列的最大宽度
- 为了在分隔符‘|’末尾有空格,需要在最大宽度上加1
def get_cnchar_col_max_len(_rows, max_column):
"""
# 获取每一列的最大宽度
# 中英文混排,宽度不一致时的处理
"""
col_max_lens = []
for i in range(max_column):
col_lens = [get_string_width(row[i]) for row in _rows]
max_len = max(col_lens)+1
col_max_lens.append(max_len)
return col_max_lens
4. 格式化一行中英文字符串
def print_format(msg, width, fill):
"""
# 中英文宽度对齐
# msg: 待对齐的字符串
# width: 该列最大宽度
# fill: 右侧待填充的字符,默认为' '
# align: 默认为左对齐
"""
align = '<'
try:
count = 0
for word in msg:
if (word >='\u4e00' and word <= '\u9fa5') or word in [';',':',',','(',')','!','?','——','……','、','》','《']:
count+=1
if width>=count:
width = width-count
output = '{0:{1}{2}{3}}'.format(msg,fill,align,width)
# print('output', output)
except:
print('Error: print_format eroor')
output = ''
return output
5. 格式化多行多列字符串表
def format_cnchar_equal_len(rows, col_max_lens):
"""
# 含有汉字的情况,将每一列中各行格式化等宽
# rows: 按行存放的字符串列表
# col_max_lens: 各列最大宽度
"""
for i in range(len(rows)):
for j in range(len(col_max_lens)):
rows[i][j] = print_format(rows[i][j],col_max_lens[j],' ')
return rows
6. 格式化 md 表格第二行
def format_style_line(col_max_lens):
"""
# 生成各列最大宽度的连续短划线 '---'
"""
insert_row = []
empty_string = ''
for len in col_max_lens:
insert_row.append(empty_string.ljust(len, "-"))
return insert_row
7.将整理好的字符串表按 '|' 分隔符存放在 md文件
def write_csv( file_name:str, headers:list, rows:list):
"""
# 用 csv 生成 md 文件
"""
try:
with open(file_name, encoding="utf_8_sig", mode="w", newline="\n") as f:
_writer = csv.writer(f, delimiter="|")
for header in headers:
_writer.writerow(header)
_writer.writerows(rows)
except Exception as e:
print("Error: Write_csv exception", e)
8.Excel到md文件转换
- 目前仅支持第一个表格的转换
_sheet = _wb.worksheets[0]
- 生成的 md 文件和 python 代码同目录
def excel_to_csvmd(input_file, cnchar=True):
"""
# 将 excel 第一张表格转换成 md 文件;
# 将单元格中多行文本末尾用 <br> 替换;
# 如果超长路径需要换行, 首先在excel中硬换行, 在这里替换成' <br>',注意前面有一个空格;
# 输出为'None'为空值;
# input_file:就是上面的文件名称
# cnchar: 默认True为中英混合表格,否则为字母和数字表格
"""
if len(input_file) < 5:
print("error no input file name")
sys.exit(1)
print("Convert file:{}".format(input_file))
_wb = oxl.load_workbook(filename=input_file, read_only=True, data_only=True)
_sheet = _wb.worksheets[0]
_rows = [[str(x).replace("\n", " <br>") for x in _rows] for _rows in _sheet.values]
if cnchar==True:
col_max_lens = get_cnchar_col_max_len(_rows, _sheet.max_column)
_rows = format_cnchar_equal_len(_rows, col_max_lens)
else:
col_max_lens = get_col_max_len(_rows, _sheet.max_column)
_rows = format_equal_len(_rows, col_max_lens)
insert_row = format_style_line(col_max_lens)
dfs = _rows[:1] + [insert_row] +_rows[1:]
_wb.close()
output_path = '{}.md'.format(datetime.datetime.now().strftime("%m%d_%H%M_%S"))
write_csv(output_path, [], dfs)
print('Convert end, output_path: ', output_path)
9. 程序入口
输入参数:待转换的Excel文件,例如 D:\markdown_table\source_data.xlsx
excel_to_csvmd('D:\markdown_table\source_data.xlsx')
总结
Excel自动生成Markdown表格的python处理,完美的解决了开篇所提出的问题。保留了原汁原味的Markdown表格风格,为批量设计说明文档的小伙伴提供一丁点小帮助。