优化Azure Function App的Python代码:实现Excel分列功能
CSV转XLSX日期列左对齐问题修复方案(Azure Function + Python)
问题描述
使用Azure Function实现CSV转XLSX功能时,转换后的StartDate与LeaveDate列数据呈左对齐状态,说明这两列被识别为文本格式而非日期格式,需要实现类似Excel「分列」的效果,将文本格式的日期转为真正的日期类型。
现有代码问题分析
当前代码中,虽然将CSV中的日期转为了datetime类型,但随后又通过strftime转成了字符串格式写入Excel。此时单元格存储的是文本内容,即使设置了日期格式,Excel也无法将其识别为日期,导致左对齐。
修复方案
核心思路:保留日期的datetime类型,直接写入Excel并应用日期格式,让Excel识别为日期类型。
修改步骤
- 删除字符串转换步骤:移除将
datetime转成字符串的两行代码,让DataFrame中这两列保持datetime类型。 - 优化写入逻辑:在写入单元格时,对日期类型的字段使用
write_datetime方法,确保Excel识别为日期;或者直接使用pandas的to_excel方法简化写入流程(更高效)。 - 动态定位日期列:避免硬编码列位置(如H:I),通过列名获取列索引,增强代码通用性。
修改后的完整代码
import azure.functions as func import logging from azure.storage.blob import BlobServiceClient import os import pandas as pd import xlsxwriter import io from io import BytesIO import numpy as np app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS) @app.route(route="http_trigger") def http_trigger(req: func.HttpRequest) -> func.HttpResponse: logging.info('Python HTTP trigger function processed a request.') connect_str = os.environ["AzureWebJobsStorage"] blob_service_client = BlobServiceClient.from_connection_string(connect_str) container_name_input = "input" container_name_output = "output" # 获取容器和Blob名称(可根据本地测试需求修改) container_name = req.params.get('container') blob_name = req.params.get('name') blob_client_input = blob_service_client.get_blob_client(container=container_name, blob=blob_name) blob_content = blob_client_input.download_blob().readall() # 读取CSV内容 try: df = pd.read_csv(io.BytesIO(blob_content)) except UnicodeDecodeError: df = pd.read_csv(io.BytesIO(blob_content), encoding='utf-16') # 将日期列转为datetime类型 df['StartDate'] = pd.to_datetime(df['StartDate'], format='%d/%m/%Y') df['LeaveDate'] = pd.to_datetime(df['LeaveDate'], format='%d/%m/%Y') output = BytesIO() workbook = xlsxwriter.Workbook(output, {'remove_timezone': True}) worksheet = workbook.add_worksheet('Sheet1') # 写入表头 for col_num, col_name in enumerate(df.columns): worksheet.write(0, col_num, col_name) # 获取日期列索引 date_cols = ['StartDate', 'LeaveDate'] date_col_indices = [df.columns.get_loc(col) for col in date_cols] date_format = workbook.add_format({'num_format': 'dd/mm/yyyy'}) # 写入数据行,日期列用write_datetime方法 for row_num, row_data in enumerate(df.itertuples(index=False), start=1): for col_num, value in enumerate(row_data): if col_num in date_col_indices: worksheet.write_datetime(row_num, col_num, value, date_format) else: worksheet.write(row_num, col_num, value) workbook.close() # 上传转换后的XLSX文件 output_blob_name = blob_name.replace('.csv', '.xlsx') excel_blob_client = blob_service_client.get_blob_client(container=container_name_output, blob=output_blob_name) excel_blob_client.upload_blob(output.getvalue()) # 删除源CSV文件 blob_client_input.delete_blob() return func.HttpResponse(f"CSV文件已转换为XLSX:{output_blob_name},源CSV文件已删除。")
简化版方案(使用pandas to_excel)
如果不需要复杂的自定义格式,可直接用pandas的to_excel方法,代码更简洁:
# 替换原有的workbook创建、写入部分 output = BytesIO() with pd.ExcelWriter(output, engine='xlsxwriter') as writer: df.to_excel(writer, sheet_name='Sheet1', index=False) workbook = writer.book worksheet = writer.sheets['Sheet1'] date_format = workbook.add_format({'num_format': 'dd/mm/yyyy'}) # 为日期列设置格式 for col in ['StartDate', 'LeaveDate']: col_idx = df.columns.get_loc(col) worksheet.set_column(col_idx, col_idx, None, date_format) # 后续上传Blob、删除源文件逻辑不变
效果说明
修改后,Excel中的StartDate和LeaveDate列会以日期类型存储,自动右对齐,并且可以正常使用Excel的日期筛选、计算等功能,达到与「分列」操作相同的效果。
内容的提问来源于stack exchange,提问作者Ross Sutherland
相关产品推荐
相关产品推荐

