import json import os from openpyxl import load_workbook from openpyxl.utils import get_column_letter, column_index_from_string def xlsx_to_spreadsheet_data(xlsx_path): wb = load_workbook(xlsx_path, data_only=True) ws = wb.active rows = {} max_row = ws.max_row or 0 max_col = ws.max_column or 0 for r in range(1, max_row + 1): row_key = r - 1 cells = {} for c in range(1, max_col + 1): cell = ws.cell(row=r, column=c) if cell.value is not None: val = cell.value if not isinstance(val, str): val = str(val) cells[str(c - 1)] = {"text": val} if cells: rows[str(row_key)] = {"cells": cells} rows["len"] = max_row merges = [] for merged_range in ws.merged_cells.ranges: min_row, min_col, max_row2, max_col2 = ( merged_range.min_row, merged_range.min_col, merged_range.max_row, merged_range.max_col, ) ri = min_row - 1 ci = min_col - 1 rs = max_row2 - min_row cs = max_col2 - min_col range_str = f"{get_column_letter(min_col)}{min_row}:{get_column_letter(max_col2)}{max_row2}" merges.append(range_str) row_key = str(ri) if row_key not in rows: rows[row_key] = {"cells": {}} cell_key = str(ci) if cell_key not in rows[row_key]["cells"]: rows[row_key]["cells"][cell_key] = {} rows[row_key]["cells"][cell_key]["merge"] = [rs, cs] sheet_name = ws.title if ws.title else "Sheet1" cols = {} for col_letter, dim in ws.column_dimensions.items(): if dim.width: ci = column_index_from_string(col_letter) - 1 px = max(60, int(dim.width * 8)) cols[str(ci)] = {"width": px} result = { "name": sheet_name, "rows": rows, "merges": merges, } if cols: result["cols"] = cols return result def generate_sheet(xlsx_path, output_html_path=None, template_path=None): if template_path is None: template_path = os.path.join(os.path.dirname(__file__), "sheet.html") data = xlsx_to_spreadsheet_data(xlsx_path) data_json = json.dumps(data, ensure_ascii=False, indent=2) data_json = data_json.replace("", "<\\/script>") with open(template_path, "r", encoding="utf-8") as f: html = f.read() html = html.replace("{{DATA}}", data_json) if output_html_path is None: output_html_path = xlsx_path.rsplit(".", 1)[0] + ".html" with open(output_html_path, "w", encoding="utf-8") as f: f.write(html) print(f"HTML saved to: {output_html_path}") return output_html_path if __name__ == "__main__": import sys src = sys.argv[1] if len(sys.argv) > 1 else "111.xlsx" generate_sheet(src)