first commit
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
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>", "<\\/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)
|
||||
Reference in New Issue
Block a user