OpenHarmony开发者论坛

标题: 【SUBJECT技术】Python将Excel文件自动生成Markdown表格 [打印本页]

作者: wangyeyu01    时间: 2023-12-13 19:13
标题: 【SUBJECT技术】Python将Excel文件自动生成Markdown表格
[md]# 一、Excel自动生成Markdown表格的python处理

## 本文着重解决了以下问题

1. 如果有长短不一的单元格存在,markdown自动生成的表格没有对齐,原始文本看起来不够美观;
2. 相同长度中英文字符串显示宽度不同,按照字符长度填充,仍然会参差不齐。
3. Excel表格如何转换为Markdown文件;
4. Excel中一个单元格有多行的情况,如何生成\<br> Markdown换行;
5. Excel中有空值,尤其是第一列有空值,格式化后该行其他列会前移;

## 纯文本的表格是这样的

![not_align.PNG](https://forums-obs.openharmony.c ... 6av1yif3cxyuyna.png "not_align.PNG")

## 对齐的表格是这样的![align.PNG](https://forums-obs.openharmony.c ... rhrlntfetr9skf5.png "align.PNG")

# 二、程序实现

## 1. 程序中用到了excel读写,日期时间,导入相关包

import pandas as pd
import sys, datetime
import sys, datetime, csv

## 2. 获取中英字符串宽度

* 如果遇见汉字字符需要在之前的字符长度上加1

```py
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) for row in _rows]
        max_len = max(col_lens)+1
        col_max_lens.append(max_len)

    return col_max_lens
```

## 4. 格式化一行中英文字符串

* 调用 format 函数格式化字符串

```
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. 格式化多行多列字符串表

* 调用 print_format 函数格式化字符串

```
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[j] = print_format(rows[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文件

* 调用Excel中 csv的存放方式

```python
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 `

```py
excel_to_csvmd('D:\markdown_table\source_data.xlsx')
```

# 总结

Excel自动生成Markdown表格的python处理,完美的解决了开篇所提出的问题。保留了原汁原味的Markdown表格风格,为批量设计说明文档的小伙伴提供一丁点小帮助。
[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5