convert_to_html
Convert Excel/CSV files to HTML for browser viewing while preserving original styles, colors, and fonts. Supports multi-sheet selection, pagination for large files, and returns structured JSON with conversion details.
Instructions
将Excel/CSV文件转换为可在浏览器中查看的HTML文件。保留原始样式、颜色、字体等格式。支持多工作表文件,可选择特定工作表或转换全部。大文件可使用分页功能。返回结构化JSON,包含成功状态、生成的文件信息和转换摘要。
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | Yes | 源表格文件的绝对路径,支持 .csv, .xlsx, .xls, .xlsb, .xlsm 格式。 | |
| header_rows | No | 【可选】将文件顶部的指定行数视为表头。默认为 1。 | |
| output_path | No | 输出HTML文件的路径。如果留空,将在源文件目录中生成一个同名的 .html 文件。 | |
| page_number | No | 【可选】要查看的页码,从1开始。默认为1。用于浏览大型文件的特定页面。 | |
| page_size | No | 【可选】分页时每页显示的行数。默认为100行。用于控制大型文件转换后HTML的单页大小。 | |
| sheet_name | No | 【可选】要转换的单个工作表的名称。如果留空,将转换文件中的所有工作表。 |
Implementation Reference
- src/models/tools.py:165-235 (handler)MCP tool handler: processes arguments, calls CoreService.convert_to_html, handles errors, and returns structured JSON response as TextContent.async def _handle_convert_to_html(arguments: dict[str, Any], core_service: CoreService) -> list[TextContent]: """处理 convert_to_html 工具调用。""" try: result = core_service.convert_to_html( arguments["file_path"], arguments.get("output_path"), sheet_name=arguments.get("sheet_name"), page_size=arguments.get("page_size"), page_number=arguments.get("page_number"), header_rows=arguments.get("header_rows", 1) ) # 结构化成功响应,便于LLM理解 response = { "success": True, "operation": "convert_to_html", "results": result, "summary": { "files_generated": len(result), "total_size_kb": sum(r.get("file_size_kb", 0) for r in result), "sheets_converted": [r.get("sheet_name") for r in result] } } return [TextContent( type="text", text=json.dumps(response, ensure_ascii=False, indent=2) )] except FileNotFoundError as e: return [TextContent( type="text", text=json.dumps({ "success": False, "error_type": "file_not_found", "error_message": f"文件未找到: {str(e)}", "suggestion": "请检查文件路径是否正确,确保文件存在且可访问。支持的格式: .xlsx, .xls, .xlsb, .xlsm, .csv" }, ensure_ascii=False, indent=2) )] except PermissionError as e: return [TextContent( type="text", text=json.dumps({ "success": False, "error_type": "permission_error", "error_message": f"权限不足: {str(e)}", "suggestion": "请检查文件权限,确保有读取源文件和写入目标目录的权限" }, ensure_ascii=False, indent=2) )] except ValueError as e: return [TextContent( type="text", text=json.dumps({ "success": False, "error_type": "invalid_parameter", "error_message": f"参数错误: {str(e)}", "suggestion": "请检查参数格式,如page_size和page_number应为正整数,sheet_name应为有效的工作表名称" }, ensure_ascii=False, indent=2) )] except Exception as e: return [TextContent( type="text", text=json.dumps({ "success": False, "error_type": "conversion_error", "error_message": f"转换失败: {str(e)}", "suggestion": "请检查文件是否损坏,或尝试使用不同的参数。如果是大文件,建议使用page_size参数进行分页" }, ensure_ascii=False, indent=2) )]
- src/models/tools.py:30-62 (schema)Input schema definition for the convert_to_html tool, specifying parameters like file_path, output_path, sheet_name, pagination options.Tool( name="convert_to_html", description="将Excel/CSV文件转换为可在浏览器中查看的HTML文件。保留原始样式、颜色、字体等格式。支持多工作表文件,可选择特定工作表或转换全部。大文件可使用分页功能。返回结构化JSON,包含成功状态、生成的文件信息和转换摘要。", inputSchema={ "type": "object", "properties": { "file_path": { "type": "string", "description": "源表格文件的绝对路径,支持 .csv, .xlsx, .xls, .xlsb, .xlsm 格式。" }, "output_path": { "type": "string", "description": "输出HTML文件的路径。如果留空,将在源文件目录中生成一个同名的 .html 文件。" }, "sheet_name": { "type": "string", "description": "【可选】要转换的单个工作表的名称。如果留空,将转换文件中的所有工作表。" }, "page_size": { "type": "integer", "description": "【可选】分页时每页显示的行数。默认为100行。用于控制大型文件转换后HTML的单页大小。" }, "page_number": { "type": "integer", "description": "【可选】要查看的页码,从1开始。默认为1。用于浏览大型文件的特定页面。" }, "header_rows": { "type": "integer", "description": "【可选】将文件顶部的指定行数视为表头。默认为 1。" } }, "required": ["file_path"] }
- src/models/tools.py:21-163 (registration)Registration of the MCP tools including list_tools() returning the tool definitions and call_tool() dispatching to specific handlers.def register_tools(server: Server) -> None: """向服务器注册3个核心MCP工具。""" # 初始化核心服务 core_service = CoreService() @server.list_tools() async def handle_list_tools() -> list[Tool]: return [ Tool( name="convert_to_html", description="将Excel/CSV文件转换为可在浏览器中查看的HTML文件。保留原始样式、颜色、字体等格式。支持多工作表文件,可选择特定工作表或转换全部。大文件可使用分页功能。返回结构化JSON,包含成功状态、生成的文件信息和转换摘要。", inputSchema={ "type": "object", "properties": { "file_path": { "type": "string", "description": "源表格文件的绝对路径,支持 .csv, .xlsx, .xls, .xlsb, .xlsm 格式。" }, "output_path": { "type": "string", "description": "输出HTML文件的路径。如果留空,将在源文件目录中生成一个同名的 .html 文件。" }, "sheet_name": { "type": "string", "description": "【可选】要转换的单个工作表的名称。如果留空,将转换文件中的所有工作表。" }, "page_size": { "type": "integer", "description": "【可选】分页时每页显示的行数。默认为100行。用于控制大型文件转换后HTML的单页大小。" }, "page_number": { "type": "integer", "description": "【可选】要查看的页码,从1开始。默认为1。用于浏览大型文件的特定页面。" }, "header_rows": { "type": "integer", "description": "【可选】将文件顶部的指定行数视为表头。默认为 1。" } }, "required": ["file_path"] } ), Tool( name="parse_sheet", description="解析Excel/CSV文件为结构化JSON数据。默认返回文件概览信息(行数、列数、数据类型、前几行预览),避免上下文过载。LLM可通过参数控制是否获取完整数据、样式信息等。适合数据分析和处理,修改后可用apply_changes写回。", inputSchema={ "type": "object", "properties": { "file_path": { "type": "string", "description": "目标表格文件的绝对路径,支持 .csv, .xlsx, .xls, .xlsb, .xlsm 格式。" }, "sheet_name": { "type": "string", "description": "【可选】要解析的工作表名称。如果留空,使用第一个工作表。" }, "range_string": { "type": "string", "description": "【可选】单元格范围,如'A1:D10'。指定范围时会返回该范围的完整数据。" }, "include_full_data": { "type": "boolean", "description": "【可选,默认false】是否返回完整数据。false时只返回概览和预览,true时返回所有行数据。大文件建议先查看概览。" }, "include_styles": { "type": "boolean", "description": "【可选,默认false】是否包含样式信息(字体、颜色、边框等)。样式信息会显著增加数据量。" }, "preview_rows": { "type": "integer", "description": "【可选,默认5】预览行数。当include_full_data为false时,返回前N行作为数据预览。" }, "max_rows": { "type": "integer", "description": "【可选】最大返回行数。用于限制大文件的数据量,超出部分会被截断并提示。" } }, "required": ["file_path"] } ), Tool( name="apply_changes", description="将修改后的数据写回Excel/CSV文件,完成数据编辑闭环。接受parse_sheet返回的JSON格式数据(修改后)。保留原文件格式和样式,默认创建备份文件防止数据丢失。支持添加、删除、修改行和单元格数据。", inputSchema={ "type": "object", "properties": { "file_path": { "type": "string", "description": "需要写回数据的目标文件的绝对路径。" }, "table_model_json": { "type": "object", "description": "从 `parse_sheet` 工具获取并修改后的 TableModel JSON 数据。", "properties": { "sheet_name": {"type": "string"}, "headers": { "type": "array", "items": {"type": "string"} }, "rows": { "type": "array", "items": { "type": "array", "items": {} } } }, "required": ["sheet_name", "headers", "rows"] }, "create_backup": { "type": "boolean", "description": "【可选】是否在写入前创建原始文件的备份。默认为 `true`,以防意外覆盖。" } }, "required": ["file_path", "table_model_json"] } ) ] @server.call_tool() async def handle_call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]: """处理工具调用请求。""" try: if name == "convert_to_html": return await _handle_convert_to_html(arguments, core_service) elif name == "parse_sheet": return await _handle_parse_sheet(arguments, core_service) elif name == "apply_changes": return await _handle_apply_changes(arguments, core_service) else: return [TextContent( type="text", text=f"未知工具: {name}" )] except Exception as e: logger.error(f"工具调用失败 {name}: {e}") return [TextContent( type="text", text=f"错误: {str(e)}" )]
- src/core_service.py:192-261 (helper)Core conversion logic: parses the file, handles pagination, uses HTMLConverter or PaginatedHTMLConverter to generate HTML file(s), returns results.def convert_to_html(self, file_path: str, output_path: str | None = None, sheet_name: str | None = None, page_size: int | None = None, page_number: int | None = None, header_rows: int = 1) -> list[dict[str, Any]]: """ 将表格文件转换为HTML文件。 参数: file_path: 源文件路径 output_path: 输出HTML文件路径,如果为None则生成默认路径 page_size: 分页大小(每页行数),如果为None则不分页 page_number: 页码(从1开始),如果为None则显示第1页 header_rows: 表头行数,默认第一行为表头 返回: 转换结果信息 """ try: # 验证文件存在 path = Path(file_path) if not path.exists(): raise FileNotFoundError(f"文件不存在: {file_path}") # 生成默认输出路径 if output_path is None: output_path = str(path.with_suffix('.html')) # 获取解析器并解析 parser = self.parser_factory.get_parser(file_path) sheets: list[Sheet] = parser.parse(file_path) # Filter sheets if a specific sheet_name is provided sheets_to_convert = sheets if sheet_name: sheets_to_convert = [s for s in sheets if s.name == sheet_name] if not sheets_to_convert: raise ValueError(f"工作表 '{sheet_name}' 在文件中未找到。") # When converting a single sheet from a multi-sheet workbook, # the output file name should reflect the sheet name. if len(sheets_to_convert) == 1 and len(sheets) > 1: output_p = Path(output_path) final_output_path = str(output_p.parent / f"{output_p.stem}-{sheets_to_convert[0].name}{output_p.suffix or '.html'}") else: final_output_path = output_path # 检查是否需要分页处理 (分页仅对第一个符合条件的工作表生效) if page_size is not None and page_size > 0: # 使用分页HTML转换器 from .converters.paginated_html_converter import PaginatedHTMLConverter html_converter = PaginatedHTMLConverter( compact_mode=False, page_size=page_size, page_number=page_number or 1, header_rows=header_rows ) # Paginated converter still works on a single sheet result = html_converter.convert_to_file(sheets_to_convert[0], final_output_path) return [result] # Return as a list else: # 使用标准HTML转换器 html_converter = HTMLConverter(compact_mode=False, header_rows=header_rows) results = html_converter.convert_to_files(sheets_to_convert, final_output_path) return results except Exception as e: logger.error(f"HTML转换失败: {e}") raise