基于AWS Lambda与Python处理S3中Excel多工作表的问题求助
解决方案
错误根源
你当前代码里的decode('latin-1')是核心问题——Excel文件是二进制格式,直接解码会破坏文件结构,导致空字节错误。必须用二进制流方式读取,不能做字符串解码。
完整实现步骤
读取S3中的Excel文件(含多工作表)
使用io.BytesIO将S3返回的二进制数据包装成文件流,配合pandas.read_excel的sheet_name=None参数一次性读取所有工作表(返回格式为{工作表名: DataFrame}的字典)。筛选处理每个工作表数据
遍历工作表字典,对每个DataFrame执行你的筛选逻辑。将处理后的数据写入新Excel文件并上传到S3
用pd.ExcelWriter将多个DataFrame写入不同工作表,再将文件流上传到目标S3桶。
完整代码示例
import boto3 import pandas as pd import io def lambda_handler(event, context): # 配置参数 input_bucket = "你的输入存储桶名" output_bucket = "你的输出存储桶名" business_folder = "输入子文件夹路径/" # 注意末尾加/ business_file = "目标Excel文件名.xlsx" output_key = "输出子文件夹路径/处理后文件.xlsx" # 目标文件的S3键 # 初始化S3客户端 s3 = boto3.client('s3') # 读取输入Excel文件 try: # 获取S3对象的二进制数据,不做解码 response = s3.get_object(Bucket=input_bucket, Key=f"{business_folder}{business_file}") excel_data = response['Body'].read() # 包装成BytesIO流 excel_stream = io.BytesIO(excel_data) # 读取所有工作表,返回字典{sheet_name: df} sheets_dict = pd.read_excel(excel_stream, sheet_name=None, engine='openpyxl') except Exception as e: raise Exception(f"读取输入文件失败: {str(e)}") # 处理每个工作表的筛选逻辑(替换成你的实际筛选代码) processed_sheets = {} for sheet_name, df in sheets_dict.items(): # 示例:筛选某列值大于100的行,替换成你的筛选逻辑 filtered_df = df[df['某列名'] > 100] processed_sheets[sheet_name] = filtered_df # 将处理后的数据写入新Excel文件 try: output_stream = io.BytesIO() # 使用xlsxwriter引擎写入多工作表 with pd.ExcelWriter(output_stream, engine='xlsxwriter') as writer: for sheet_name, df in processed_sheets.items(): df.to_excel(writer, sheet_name=sheet_name, index=False) # 将文件流指针移到开头 output_stream.seek(0) # 上传到目标S3桶 s3.put_object( Bucket=output_bucket, Key=output_key, Body=output_stream.getvalue() ) return {"statusCode": 200, "message": "文件处理并上传成功"} except Exception as e: raise Exception(f"写入并上传文件失败: {str(e)}")
注意事项
- Lambda层验证:确保你的层包含
pandas、openpyxl、xlsxwriter,且版本兼容(比如pandas 2.x搭配openpyxl 3.x)。 - S3权限:Lambda执行角色需要具备
S3:GetObject(输入桶)和S3:PutObject(输出桶)的权限。 - 文件路径:S3的键(Key)要注意路径格式,子文件夹路径末尾需加
/,避免路径拼接错误。
内容的提问来源于stack exchange,提问作者cain007
相关产品推荐
相关产品推荐

