138 lines
4.8 KiB
Python
138 lines
4.8 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
|
||
import sys
|
||
import os
|
||
import xlrd
|
||
import xlwt
|
||
import shutil
|
||
|
||
def parse_args():
|
||
if len(sys.argv) < 2:
|
||
print("Usage: python3 xxx.py xxx.xls [-name sheetName]")
|
||
sys.exit(1)
|
||
file_path = sys.argv[1]
|
||
sheet_name = None
|
||
if '-name' in sys.argv:
|
||
idx = sys.argv.index('-name')
|
||
if idx + 1 < len(sys.argv):
|
||
sheet_name = sys.argv[idx + 1]
|
||
else:
|
||
print("Error: -name 参数后需跟 sheet 名称")
|
||
sys.exit(1)
|
||
if not os.path.exists(file_path):
|
||
print(f"文件 {file_path} 不存在")
|
||
sys.exit(1)
|
||
return file_path, sheet_name
|
||
|
||
def find_header_indices(sheet):
|
||
header = [str(sheet.cell_value(0, col)).strip() for col in range(sheet.ncols)]
|
||
try:
|
||
bits_col = header.index('Bits')
|
||
offset_col = header.index('OffsetAddress')
|
||
regname_col = header.index('RegName')
|
||
offsetwidth_col = header.index('OffsetWidth')
|
||
except ValueError as e:
|
||
print(f"表头缺失: {e}")
|
||
sys.exit(1)
|
||
return bits_col, offset_col, regname_col, offsetwidth_col
|
||
|
||
def process_sheet(sheet, wb, sheet_name):
|
||
bits_col, offset_col, regname_col, offsetwidth_col = find_header_indices(sheet)
|
||
ws = wb.add_sheet(sheet_name)
|
||
# 复制表头
|
||
for col in range(sheet.ncols):
|
||
ws.write(0, col, sheet.cell_value(0, col))
|
||
|
||
offset = 0
|
||
reg_idx = 0
|
||
row = 1
|
||
while row < sheet.nrows:
|
||
bits_start_cell = str(sheet.cell_value(row, bits_col)).strip()
|
||
# 匹配 '31' 或 '[31:' 开头
|
||
if bits_start_cell == '31.0' or bits_start_cell.startswith('[31:'):
|
||
print(f"Processing row {row+1}: Bits = {bits_start_cell}")
|
||
# replace OffsetAddress
|
||
offset_str = f"0x{offset:02X}"
|
||
ws.write(row, offset_col, offset_str)
|
||
# replace RegName
|
||
reg_str = f"reg_{reg_idx:02X}"
|
||
ws.write(row, regname_col, reg_str)
|
||
# 校验
|
||
if offset // 4 != reg_idx:
|
||
print(f"[Check] OffsetAddress {offset_str} 与 RegName {reg_str} 不匹配")
|
||
# Bits列刷新
|
||
offset += 4
|
||
reg_idx += 1
|
||
|
||
bits_sum = 0
|
||
left = 31
|
||
start_row = row
|
||
# one Bits row starts and ends
|
||
while row < sheet.nrows:
|
||
# 复制其他列
|
||
for col in range(sheet.ncols):
|
||
if col in (bits_col, offset_col, regname_col):
|
||
continue
|
||
ws.write(row, col, sheet.cell_value(row, col))
|
||
|
||
width = (sheet.cell_value(row, offsetwidth_col))
|
||
if width is None or width == '':
|
||
ws.write(row, bits_col, sheet.cell_value(row, bits_col))
|
||
bits_cell = str(sheet.cell_value(row, bits_col)).strip()
|
||
row += 1
|
||
if bits_cell.endswith('0]'):
|
||
print(f"Bits cell ends with 0, breaking at row {row}")
|
||
break
|
||
else:
|
||
continue
|
||
|
||
if int(width) < 0 or int(width) > 32:
|
||
raise ValueError(f"OffsetWidth {width} 不在 0-32 范围内")
|
||
|
||
width = int(width)
|
||
right = left - width + 1
|
||
if left == right:
|
||
bits_str = f"[{left}]"
|
||
else:
|
||
bits_str = f"[{left}:{right}]"
|
||
|
||
ws.write(row, bits_col, bits_str)
|
||
|
||
bits_sum += width
|
||
|
||
left = right - 1
|
||
# next row
|
||
bits_end_cell = str(sheet.cell_value(row, bits_col)).strip()
|
||
if bits_end_cell == '0' or bits_start_cell.endswith('0]') or right == 0:
|
||
row += 1
|
||
print(f"The 0 is bits_end_cell")
|
||
break
|
||
row += 1
|
||
|
||
if bits_sum != 32:
|
||
print(f"[Warning] {sheet_name} 第{start_row+1}行起 OffsetWidth 累加为{bits_sum},应为32")
|
||
else:
|
||
# 其他行保持原样
|
||
ws.write(row, offset_col, sheet.cell_value(row, offset_col))
|
||
ws.write(row, regname_col, sheet.cell_value(row, regname_col))
|
||
ws.write(row, bits_col, sheet.cell_value(row, bits_col))
|
||
row += 1
|
||
|
||
def main():
|
||
file_path, sheet_name = parse_args()
|
||
# 先备份原文件
|
||
shutil.copyfile(file_path, file_path + ".bak")
|
||
book = xlrd.open_workbook(file_path)
|
||
wb = xlwt.Workbook()
|
||
sheets = [sheet_name] if sheet_name else book.sheet_names()
|
||
print(sheets)
|
||
for name in sheets:
|
||
sheet = book.sheet_by_name(name)
|
||
process_sheet(sheet, wb, name)
|
||
# 覆盖原文件
|
||
wb.save(file_path)
|
||
print(f"已刷新并覆盖原文件: {file_path},原文件已备份为: {file_path}.bak")
|
||
|
||
if __name__ == "__main__":
|
||
main() |