🗒️python html表格样式参考
2024-3-2
| 2024-3-3
0  |  0 分钟
type
status
date
slug
summary
tags
category
icon
password
有个需求是把Excel指定行数据邮件发出去,下面是几个html样式参考。主要解决的是是否保留框线、框线的具体展示效果。
  1. 使用HTML table默认框线
  • 缺点:这是默认table框线,无法单独对制定行修改,且框线发虚。
#本段表格是HTML边框样式,没有额外框线,使用默认的table框线,缺点是有点发虚,而且每一行都有框线,不能去掉制定行的框线。 def read_excel_rows(file_path,sheet_name, start_row, end_row): wb = openpyxl.load_workbook(file_path) sheet = wb[sheet_name] # 获取指定行范围的非空数据 rows_data = [] for row_number in range(start_row, end_row + 1): row_data = [''] * sheet.max_column # 初始化一行数据 for cell in sheet[row_number]: #为什么使用index取出数据?避免某个cell是空值导致写入错乱 if cell.value is not None: col_index = openpyxl.utils.cell.column_index_from_string(cell.coordinate[0]) - 1 # 获取列索引 row_data[col_index] = cell.value if any(row_data): # 如果该行数据非空才添加 rows_data.append(row_data) if rows_data: # 将读取的数据加入邮件正文,格式化为带有表格样式的 HTML email_body = "<table border='1' cellspacing='0' cellpadding='5' style='font-family: Arial, Helvetica, sans-serif;'>" # 添加表头,加粗、填充色明亮蓝色 email_body += "<tr style='font-weight: bold; background-color: #2F75B5; color: white;'>" email_body += "<td>" + "</td><td>".join(["{}".format(cell) for cell in rows_data[0]]) + "</td>" email_body += "</tr>" # 添加数据部分,带有框线 for row_data in rows_data[1:]: email_body += "<tr>" email_body += "<td>" + "</td><td>".join(["{}".format(cell) for cell in row_data]) + "</td>" email_body += "</tr>" email_body += "</table>" return email_body else: print("文件指定行为空") logger1.debug("文件指定行为空") sys.exit('11')
  1. 使用HTML table默认框线,再额外套上样式
  • 优点:border: 1px solid black 会生成加粗的框线
  • 缺陷:如果两个html_body都使用此方法处理,后合并在邮件里,如果列数不一致,则列数多的表格可能会变成一个个单独的小格子,展示效果很丑,但是合并的HTML粘贴到HTML网页工具里,效果是正常的。故不同的客户端/平台展示效果可能不一样。
💡
styled_table_html 里的大括号正常只有一个,但是外面套三引号之后,要改为两个大括号,不然Python格式报错。 table {{ font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; width: auto; table-layout: auto; }}
具体代码:
#本来想用read_excel_rows1删除存在空值的最后一行的框线,效果达到了,但是两个宽度不一样的表格放在一起,宽的表格被分成一个个小格子,很丑 def read_excel_rows1(file_path, sheet_name, start_row, end_row): wb = openpyxl.load_workbook(file_path) sheet = wb[sheet_name] # 获取指定行范围的非空数据 rows_data = [] for row_number in range(start_row, end_row + 1): row_data = [''] * sheet.max_column # 初始化一行数据 for cell in sheet[row_number]: if cell.value is not None: col_index = openpyxl.utils.cell.column_index_from_string(cell.coordinate[0]) - 1 # 获取列索引 row_data[col_index] = cell.value if any(row_data): # 如果该行数据非空才添加 rows_data.append(row_data) if rows_data: # 将读取的数据加入邮件正文,格式化为带有表格样式的 HTML email_body = "<table>" # 添加表头,加粗、填充色明亮蓝色 email_body += "<tr style='font-weight: bold; background-color: #2F75B5; color: white;'>" email_body += "<td>" + "</td><td>".join(["{}".format(cell) for cell in rows_data[0]]) + "</td>" email_body += "</tr>" # 添加数据部分,带有框线 for i, row_data in enumerate(rows_data[1:], start=1): email_body += "<tr{}>".format(" class='has-total'" if is_total_row(rows_data, i) else "") email_body += "<td>" + "</td><td>".join(["{}".format(cell) for cell in row_data]) + "</td>" email_body += "</tr>" email_body += "</table>" # 为表格添加样式 styled_table_html = """ <head> <style> table {{ font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; width: auto; table-layout: auto; }} td, th {{ text-align: left; padding: 8px; border: 1px solid black; }} th {{ background-color: #2F75B5; color: white; font-weight: bold; }} tr:nth-child(even) {{ background-color: #f2f2f2; }} tr.has-total {{ border-top: 1px solid black; }} tr.has-total td {{ border-left: none; border-right: none; }} td:first-child {{ border-left: none; }} td:last-child {{ border-right: none; }} tr:first-child td {{ border-top: none; }} tr:last-child td {{ border-bottom: none; }} .hidden {{ display: none; }} </style> </head> <body> {} </body> """.format(email_body) return styled_table_html else: return "" def is_total_row(rows_data, row_index): //配合使用的,可忽略 """ 判断指定索引的行是否为“合计”行,规则是: 如果该行中至少有一个单元格的值包含“合计”子串,则认为该行是“合计”行。 """ for cell in rows_data[row_index]: if isinstance(cell, str) and "合计" in cell: return True return False
 
  1. 直接使用border: 1px solid black 生成框线(table border='0'
这段是目前效果最满意的。
#read_excel_rows2是目前最满意的表格样式,table border='0'说明不需要表格外框线,table border='1'就是要外框线 def read_excel_rows2(file_path,sheet_name, start_row, end_row): wb = openpyxl.load_workbook(file_path) sheet = wb[sheet_name] # 获取指定行范围的非空数据 rows_data = [] for row_number in range(start_row, end_row + 1): row_data = [''] * sheet.max_column # 初始化一行数据 for cell in sheet[row_number]: if cell.value is not None: col_index = openpyxl.utils.cell.column_index_from_string(cell.coordinate[0]) - 1 # 获取列索引 row_data[col_index] = cell.value if any(row_data): # 如果该行数据非空才添加 rows_data.append(row_data) if rows_data: #table border='0'说明不需要表格外框线,table border='1'就是要外框线,有table外框线再加上下面的border会很难看。 email_body = "<table border='0' cellspacing='0' cellpadding='5' style='font-family: Arial, Helvetica, sans-serif;'>" # 添加表头 email_body += "<tr style='font-weight: bold; background-color: #2F75B5; color: white;'>" #email_body += "<td>" + "</td><td>".join(["{}".format(cell) for cell in rows_data[0]]) + "</td>" #"<td style='border: 1px solid black;'>" + "</td><td style='border: 1px solid black;'>".join()才会添加表格的分割线 email_body += "<td style='border: 1px solid black;'>" + "</td><td style='border: 1px solid black;'>".join(["{}".format(cell) for cell in rows_data[0]]) + "</td>" email_body += "</tr>" # 添加数据部分,带有条件判断 for row_data in rows_data[1:]: # 判断当前行是否包含"合计" if "合计" in row_data: # 如果包含"合计",则只添加上框线border-top,很显然border是全框线 email_body += "<tr>" #email_body += "<td>" + "</td><td>".join(["{}".format(cell) for cell in row_data]) + "</td>" email_body += "<td style='border-top: 1px solid black;'>" + "</td><td style='border-top: 1px solid black;'>".join(["{}".format(cell) for cell in row_data]) + "</td>" email_body += "</tr>" else: # 如果不包含"合计",则添加边框 email_body += "<tr>" email_body += "<td style='border: 1px solid black;'>" + "</td><td style='border: 1px solid black;'>".join( ["{}".format(cell) for cell in row_data]) + "</td>" email_body += "</tr>" email_body += "</table>" return email_body else: print("文件指定行为空") logger1.debug("文件指定行为空") sys.exit('11')
 
python读取本地sessionfastapi记录
目录