Skip to main content
Glama

MCP Sheet Parser

by yuqie6
MIT License
3
  • Apple
cell_converter.py5.6 kB
from datetime import datetime as dt, timedelta from src.models.table_model import Cell, RichTextFragment from src.utils.html_utils import escape_html, create_html_element from src.utils.color_utils import format_color # 数字格式映射常量 NUMBER_FORMAT_MAP = { "General": lambda v: str(v), "0": lambda v: f"{v:.0f}" if isinstance(v, (int, float)) else str(v), "0.0": lambda v: f"{v:.1f}" if isinstance(v, (int, float)) else str(v), "0.00": lambda v: f"{v:.2f}" if isinstance(v, (int, float)) else str(v), "#,##0": lambda v: f"{v:,.0f}" if isinstance(v, (int, float)) else str(v), "#,##0.0": lambda v: f"{v:,.1f}" if isinstance(v, (int, float)) else str(v), "#,##0.00": lambda v: f"{v:,.2f}" if isinstance(v, (int, float)) else str(v), "0%": lambda v: f"{v:.0%}" if isinstance(v, (int, float)) else str(v), "0.0%": lambda v: f"{v:.1%}" if isinstance(v, (int, float)) else str(v), "0.00%": lambda v: f"{v:.2%}" if isinstance(v, (int, float)) else str(v), } # 日期格式映射常量 DATE_FORMAT_MAP = { "yyyy-mm-dd": "%Y-%m-%d", "mm/dd/yyyy": "%m/%d/%Y", "dd/mm/yyyy": "%d/%m/%Y", "yyyy/mm/dd": "%Y/%m/%d", "mm-dd-yyyy": "%m-%d-%Y", "dd-mm-yyyy": "%d-%m-%Y", } def format_chinese_date(date_obj: dt, format_str: str) -> str: """格式化中文日期。""" if 'yyyy"年"m"月"d"日"' in format_str: return f"{date_obj.year}年{date_obj.month}月{date_obj.day}日" elif 'm"月"d"日"' in format_str: return f"{date_obj.month}月{date_obj.day}日" else: return f"{date_obj.month}月{date_obj.day}日" class CellConverter: """处理单元格的 HTML 内容生成。""" def __init__(self, style_converter): self.style_converter = style_converter def convert(self, cell: Cell) -> str: """ 将 Cell 对象转换为 HTML 表现形式。 """ if isinstance(cell.value, list): return self._format_rich_text(cell.value) if cell.value is None: return "" if cell.style and cell.style.number_format: try: return self._apply_number_format(cell.value, cell.style.number_format) except Exception: pass if isinstance(cell.value, float): return f"{cell.value:.2f}".rstrip('0').rstrip('.') if not cell.value.is_integer() else str(int(cell.value)) return str(cell.value) def _format_rich_text(self, fragments: list[RichTextFragment]) -> str: """ 将富文本片段格式化为单一 HTML 字符串。 """ return "".join(self._format_rich_text_fragment(f) for f in fragments) def _format_rich_text_fragment(self, fragment: RichTextFragment) -> str: """ 将单个富文本片段格式化为带样式的 HTML span。 """ style = fragment.style inline_styles = {} if style.font_name: inline_styles['font-family'] = self.style_converter._format_font_family(style.font_name) if style.font_size: inline_styles['font-size'] = self.style_converter._format_font_size(style.font_size) if style.font_color: inline_styles['color'] = format_color(style.font_color, is_font_color=True) if style.bold: inline_styles['font-weight'] = 'bold' if style.italic: inline_styles['font-style'] = 'italic' if style.underline: inline_styles['text-decoration'] = 'underline' return create_html_element('span', escape_html(fragment.text), inline_styles=inline_styles) def _apply_number_format(self, value, number_format: str) -> str: """ 对值应用数字格式。 """ if not number_format: return str(value) if number_format in NUMBER_FORMAT_MAP: return NUMBER_FORMAT_MAP[number_format](value) if isinstance(value, (int, float)) and ("月" in number_format and "日" in number_format): try: # 使用更精确的Excel日期转换,避免精度损失 from decimal import Decimal excel_epoch = dt(1899, 12, 30) # 使用Decimal保持精度,然后转换为timedelta days_decimal = Decimal(str(value)) days_int = int(days_decimal) microseconds = int((days_decimal - days_int) * 86400 * 1000000) date_obj = excel_epoch + timedelta(days=days_int, microseconds=microseconds) return format_chinese_date(date_obj, number_format) except Exception: pass if isinstance(value, dt): if "月" in number_format and "日" in number_format: return format_chinese_date(value, number_format) if "yyyy" in number_format.lower() or "mm" in number_format.lower() or "dd" in number_format.lower(): format_lower = number_format.lower() for excel_fmt, formatter in DATE_FORMAT_MAP.items(): if excel_fmt in format_lower: return value.strftime(str(formatter)) return value.strftime("%Y-%m-%d") if isinstance(value, (int, float)) and "%" in number_format: return f"{value * 100:.1f}%" if isinstance(value, (int, float)) and "," in number_format: return f"{value:,.2f}" return str(value)

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yuqie6/MCP-Sheet-Parser-cot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server