feat: Excel导入支持自定义列映射+智能列名检测
- 上传后自动读取Excel列名,下拉框选择映射 - 智能匹配: 科目/编码→kpi_code, 期间→period, 金额→actual_value - 支持统一期间(文件无期间列时) - 后端接受 kpi_col/period_col/value_col/default_period 参数
This commit is contained in:
+18
-8
@@ -15,14 +15,24 @@ router = APIRouter(prefix="/api/cma/data", tags=["数据对接"],
|
||||
)
|
||||
|
||||
@router.post("/import-excel")
|
||||
async def import_excel(file: UploadFile = File(...), db: Session = Depends(get_db)):
|
||||
async def import_excel(file: UploadFile = File(...),
|
||||
kpi_col: str = Query("kpi_code", description="Excel中KPI编码列名"),
|
||||
period_col: str = Query("period", description="Excel中期间列名"),
|
||||
value_col: str = Query("actual_value", description="Excel中实际值列名"),
|
||||
default_period: str = Query(None, description="如文件无期间列,统一使用此值"),
|
||||
db: Session = Depends(get_db)):
|
||||
content = await file.read()
|
||||
df = pd.read_excel(io.BytesIO(content))
|
||||
|
||||
required = ["kpi_code", "period", "actual_value"]
|
||||
if not all(c in df.columns for c in required):
|
||||
raise HTTPException(400, f"Excel必须包含列: {required}")
|
||||
|
||||
required = [kpi_col, value_col]
|
||||
if not default_period:
|
||||
required.append(period_col)
|
||||
|
||||
missing = [c for c in required if c not in df.columns]
|
||||
if missing:
|
||||
raise HTTPException(400,
|
||||
f"Excel缺少列: {missing}。当前文件列: {list(df.columns)}")
|
||||
|
||||
if len(df) == 0:
|
||||
raise HTTPException(400, "Excel文件为空,没有数据行")
|
||||
|
||||
@@ -33,9 +43,9 @@ async def import_excel(file: UploadFile = File(...), db: Session = Depends(get_d
|
||||
count = 0
|
||||
skipped = []
|
||||
for idx, row in df.iterrows():
|
||||
kpi_code = str(row.get("kpi_code", "")).strip()
|
||||
period = str(row.get("period", "")).strip()
|
||||
value = row.get("actual_value")
|
||||
kpi_code = str(row.get(kpi_col, "")).strip()
|
||||
period = str(row.get(period_col, default_period or "")).strip() if period_col in df.columns else (default_period or "").strip()
|
||||
value = row.get(value_col)
|
||||
|
||||
if not kpi_code or not period or pd.isna(value):
|
||||
skipped.append(f"第{idx+2}行: 缺少必填字段")
|
||||
|
||||
Reference in New Issue
Block a user