Files
Extract_reqs/json_to_excel.py
2026-02-03 22:48:22 +08:00

203 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
将需求JSON文件转换为Excel格式
"""
import json
import argparse
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter
def parse_requirements_from_json(json_data, parent_section=""):
"""
递归解析JSON提取所有需求
Args:
json_data: JSON数据章节或子章节
parent_section: 父章节路径
Returns:
需求列表
"""
requirements = []
if isinstance(json_data, dict):
# 提取章节信息
section_info = json_data.get("章节信息", {})
section_number = section_info.get("章节编号", "")
section_title = section_info.get("章节标题", "")
section_level = section_info.get("章节级别", "")
current_section = f"{section_number} {section_title}".strip() if section_number else section_title
# 提取需求列表
req_list = json_data.get("需求列表", [])
for req in req_list:
req_data = {
"章节编号": section_number,
"章节标题": section_title,
"章节级别": section_level,
"章节完整路径": current_section,
"需求类型": req.get("需求类型", ""),
"需求编号": req.get("需求编号", ""),
"需求描述": req.get("需求描述", ""),
"接口名称": req.get("接口名称", ""),
"接口类型": req.get("接口类型", ""),
"来源": req.get("来源", ""),
"目的地": req.get("目的地", "")
}
requirements.append(req_data)
# 递归处理子章节
subsections = json_data.get("子章节", {})
for subsection_name, subsection_data in subsections.items():
sub_reqs = parse_requirements_from_json(subsection_data, current_section)
requirements.extend(sub_reqs)
return requirements
def create_excel(json_file, output_file):
"""
将JSON文件转换为Excel
Args:
json_file: 输入的JSON文件路径
output_file: 输出的Excel文件路径
"""
# 读取JSON文件
with open(json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
# 创建工作簿
wb = Workbook()
# 创建元数据工作表
ws_meta = wb.active
ws_meta.title = "文档元数据"
metadata = data.get("文档元数据", {})
ws_meta['A1'] = "文档标题"
ws_meta['B1'] = metadata.get("标题", "")
ws_meta['A2'] = "生成时间"
ws_meta['B2'] = metadata.get("生成时间", "")
ws_meta['A3'] = "总需求数"
ws_meta['B3'] = metadata.get("总需求数", 0)
# 需求类型统计
stats = metadata.get("需求类型统计", {})
row = 5
ws_meta['A5'] = "需求类型统计"
ws_meta['A5'].font = Font(bold=True)
for req_type, count in stats.items():
row += 1
ws_meta[f'A{row}'] = req_type
ws_meta[f'B{row}'] = count
# 设置元数据工作表样式
for row in ws_meta.iter_rows(min_row=1, max_row=row, min_col=1, max_col=1):
for cell in row:
cell.font = Font(bold=True)
cell.fill = PatternFill(start_color="CCE5FF", end_color="CCE5FF", fill_type="solid")
# 创建需求列表工作表
ws_reqs = wb.create_sheet(title="需求列表")
# 定义表头(按用户要求的顺序)
headers = [
"章节编号", "章节标题", "需求类型", "需求编号", "需求描述",
"接口名称", "接口类型", "来源", "目的地"
]
# 写入表头
for col, header in enumerate(headers, 1):
cell = ws_reqs.cell(row=1, column=col, value=header)
cell.font = Font(bold=True, size=11, color="FFFFFF")
cell.fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
cell.alignment = Alignment(horizontal="center", vertical="center")
# 解析所有需求
all_requirements = []
need_content = data.get("需求内容", {})
for section_name, section_data in need_content.items():
reqs = parse_requirements_from_json(section_data)
all_requirements.extend(reqs)
# 写入需求数据
for row_idx, req in enumerate(all_requirements, 2):
for col_idx, header in enumerate(headers, 1):
# 获取字段值,如果字段不存在或为空字符串,则为空
value = req.get(header, "")
if value is None:
value = ""
cell = ws_reqs.cell(row=row_idx, column=col_idx, value=value)
cell.alignment = Alignment(horizontal="left", vertical="top", wrap_text=True)
# 根据需求类型设置颜色
if header == "需求类型" and value:
if value == "接口需求":
cell.fill = PatternFill(start_color="FFF2CC", end_color="FFF2CC", fill_type="solid")
elif value == "功能需求":
cell.fill = PatternFill(start_color="E2EFDA", end_color="E2EFDA", fill_type="solid")
else:
cell.fill = PatternFill(start_color="FCE4D6", end_color="FCE4D6", fill_type="solid")
# 设置列宽
column_widths = {
'A': 12, # 章节编号
'B': 25, # 章节标题
'C': 12, # 需求类型
'D': 18, # 需求编号
'E': 80, # 需求描述
'F': 25, # 接口名称
'G': 25, # 接口类型
'H': 25, # 来源
'I': 25 # 目的地
}
for col, width in column_widths.items():
ws_reqs.column_dimensions[col].width = width
# 设置所有单元格边框
thin_border = Border(
left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin')
)
for row in ws_reqs.iter_rows(min_row=1, max_row=len(all_requirements)+1, min_col=1, max_col=len(headers)):
for cell in row:
cell.border = thin_border
# 冻结首行
ws_reqs.freeze_panes = "A2"
# 保存Excel文件
wb.save(output_file)
print(f"成功将 {len(all_requirements)} 条需求导出到 Excel 文件: {output_file}")
print(f"工作表: '文档元数据' - 包含文档基本信息和统计")
print(f"工作表: '需求列表' - 包含所有需求的详细信息")
def main():
parser = argparse.ArgumentParser(description='将需求JSON文件转换为Excel格式')
parser.add_argument('-i', '--input', required=True, help='输入的JSON文件路径')
parser.add_argument('-o', '--output', required=True, help='输出的Excel文件路径')
args = parser.parse_args()
try:
create_excel(args.input, args.output)
except Exception as e:
print(f"转换失败: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()