如何在EC2 Linux环境下从Amazon S3读取XLS文件并转换为XLSX后保存回S3
可行的S3 XLS转XLSX解决方案(Linux EC2环境)
我之前刚好处理过类似的企业级需求,完全符合你提出的「不落地本地文件」「仅Linux兼容」约束,给你两个靠谱的方案:
方案一:Python内存流式处理(推荐集成到现有应用)
这个方案全程在内存中完成转换,无需将文件保存到EC2本地磁盘,依赖的库都是跨平台的Linux友好型。
所需依赖
先安装必要的Python包:
pip install boto3 xlrd==1.2.0 openpyxl python-dotenv
boto3:AWS官方SDK,用于操作S3存储桶xlrd==1.2.0:注意要指定1.x版本,因为2.0+不再支持读取XLS格式文件openpyxl:用于创建和写入XLSX格式文件
完整代码示例
import boto3 from io import BytesIO import xlrd from openpyxl import Workbook def convert_xls_to_xlsx_in_s3(bucket_name, source_key, target_key): # 初始化S3客户端 s3 = boto3.client('s3') # 从S3读取XLS文件到内存BytesIO对象 response = s3.get_object(Bucket=bucket_name, Key=source_key) xls_file = BytesIO(response['Body'].read()) # 用xlrd解析XLS文件 xls_workbook = xlrd.open_workbook(file_contents=xls_file.getvalue()) # 创建新的XLSX工作簿 xlsx_workbook = Workbook() # 遍历XLS的每个工作表,复制到XLSX中 for sheet_idx in range(xls_workbook.nsheets): xls_sheet = xls_workbook.sheet_by_index(sheet_idx) # 如果是第一个工作表,用默认创建的,否则新建 if sheet_idx == 0: xlsx_sheet = xlsx_workbook.active xlsx_sheet.title = xls_sheet.name else: xlsx_sheet = xlsx_workbook.create_sheet(title=xls_sheet.name) # 逐行复制数据 for row_idx in range(xls_sheet.nrows): row_data = xls_sheet.row_values(row_idx) xlsx_sheet.append(row_data) # 将XLSX文件写入内存BytesIO对象 xlsx_file = BytesIO() xlsx_workbook.save(xlsx_file) xlsx_file.seek(0) # 重置文件指针到开头 # 上传转换后的XLSX文件回S3 s3.put_object( Bucket=bucket_name, Key=target_key, Body=xlsx_file ) print(f"转换完成:s3://{bucket_name}/{source_key} -> s3://{bucket_name}/{target_key}") # 调用示例 if __name__ == "__main__": BUCKET = "your-bucket-name" SOURCE_XLS_KEY = "path/to/source/file.xls" TARGET_XLSX_KEY = "path/to/target/file.xlsx" convert_xls_to_xlsx_in_s3(BUCKET, SOURCE_XLS_KEY, TARGET_XLSX_KEY)
注意事项
- 对于超大文件(比如几十GB),内存流式处理可能会占用较多EC2内存,这种情况可以考虑分块读取/写入,或者结合EC2的临时存储优化
- 如果XLS文件包含复杂样式、公式或宏,xlrd/openpyxl可能无法完全保留,这种情况可以看方案二
方案二:LibreOffice Headless模式(适合复杂格式文件)
如果你的XLS文件有复杂的格式、公式或宏,Python库可能处理不好,可以用Linux下的LibreOffice无头模式来转换,仅使用EC2的临时目录(/tmp)存储临时文件,转换完成后立即删除,符合企业对“不落地持久化本地文件”的要求。
步骤
- 在EC2 Linux实例上安装LibreOffice:
# 以Amazon Linux 2为例 sudo amazon-linux-extras install libreoffice # 或者Ubuntu/Debian sudo apt-get install libreoffice --no-install-recommends
- 编写Shell脚本(结合AWS CLI):
#!/bin/bash BUCKET="your-bucket-name" SOURCE_KEY="path/to/source/file.xls" TARGET_KEY="path/to/target/file.xlsx" TEMP_DIR="/tmp/s3-convert" # 创建临时目录 mkdir -p $TEMP_DIR cd $TEMP_DIR # 下载XLS到临时目录 aws s3 cp s3://$BUCKET/$SOURCE_KEY ./source.xls # 用LibreOffice无头模式转换 libreoffice --headless --convert-to xlsx ./source.xls --outdir ./ # 上传转换后的XLSX回S3 aws s3 cp ./source.xlsx s3://$BUCKET/$TARGET_KEY # 清理临时文件 rm -rf $TEMP_DIR echo "转换完成:s3://$BUCKET/$SOURCE_KEY -> s3://$BUCKET/$TARGET_KEY"
优缺点
- 优点:完美支持复杂格式、公式和宏,转换准确率高
- 缺点:需要安装LibreOffice,依赖较大;临时文件会短暂存放在/tmp目录(重启EC2后自动清除)
内容的提问来源于stack exchange,提问作者Dwight schrute
相关产品推荐
相关产品推荐

