一个python小模块,在windows、linux控制台对齐显示csv数据表格。
写的时候,调整对齐稍微有点费劲的。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from sre_parse import fix_flags
def is_in_linux():
os_name = platform.system()
if os_name == "Linux":
return True
return False
def get_display_width(text):
"""计算字符串的显示宽度,考虑中文字符"""
width = 0
for char in text:
if unicodedata.east_asian_width(char) in ("F", "W"):
width += 2
else:
width += 1
return width
def get_display_width_without_color(text):
"""获取不考虑颜色标识的字符串宽度"""
width = 0
color_pattern = re.compile("\033\[\d+m") # 颜色标识的正则表达式
cleaned_text = re.sub(color_pattern, "", text) # 去除颜色标识
for char in cleaned_text:
if unicodedata.east_asian_width(char) in ("F", "W"):
width += 2
else:
width += 1
return width
def align_string(text, width):
"""根据指定宽度对字符串进行对齐"""
text_width = get_display_width(text)
padding = width - text_width
if padding > 0:
return text + " " * padding
return text
def align_string_without_color(text, width):
"""根据指定宽度对字符串进行对齐"""
text_width = get_display_width_without_color(text)
padding = width - text_width
if padding > 0:
return text + " " * padding
return text
def display_csv_file_windows(csv_file_path):
with open(csv_file_path, "r", newline="", encoding="utf-8") as file:
reader = csv.reader(file)
max_widths = []
rows = list(reader)
# 获取每列的最大字符宽度
for row in rows:
for i, value in enumerate(row):
if i >= len(max_widths):
max_widths.append(0)
width = get_display_width(value) if value else 1 # 将空字符串视为宽度为1的单元格
max_widths[i] = max(max_widths[i], width)
# 打印顶部边框
top_border = "+-" + "-+-".join(["-" * width for width in max_widths]) + "-+"
print(top_border)
# 打印对齐的CSV数据
for row in rows:
formatted_row = []
for i, value in enumerate(row):
formatted_value = value if value else " " # 将空字符串替换为一个空格
formatted_value = align_string(formatted_value, max_widths[i])
formatted_row.append(formatted_value)
print("| " + " | ".join(formatted_row) + " |")
# 打印行与行之间的分隔线
print("+-" + "-+-".join(["-" * width for width in max_widths]) + "-+")
def display_csv_file_linux(csv_file_path):
with open(csv_file_path, "r", newline="", encoding="utf-8") as file:
reader = csv.reader(file)
max_widths = []
rows = list(reader)
# 获取每列的最大字符宽度
for row in rows:
for i, value in enumerate(row):
if i >= len(max_widths):
max_widths.append(0)
width = get_display_width(value) if value else 1 # 将空字符串视为宽度为1的单元格
max_widths[i] = max(max_widths[i], width)
# 打印顶部边框
top_border = (
"+-" + "-+-".join(["-" * (width + 2) for width in max_widths]) + "-+"
)
print(top_border)
# 打印对齐的CSV数据
for i, row in enumerate(rows):
formatted_row = []
for j, value in enumerate(row):
formatted_value = value if value else " " # 将空字符串替换为一个空格
if i == 0 or j == 0:
formatted_value = "\033[94m" + formatted_value + "\033[0m" # 标蓝文本
formatted_value = align_string_without_color(
formatted_value, max_widths[j]
)
formatted_row.append(formatted_value)
print("| " + " | ".join(formatted_row) + " |")
# 打印行与行之间的分隔线
print("+-" + "-+-".join(["-" * (width + 2) for width in max_widths]) + "-+")
def display_csv_file(csv_file_path):
if is_in_linux():
# command = f"column -s, -t < {csv_file_path}" # linux自带的没有边框。
# subprocess.run(command, shell=True)
display_csv_file_linux(csv_file_path)
else:
display_csv_file_windows(csv_file_path)