2GB内存服务器下低内存占用CSV转XLSX的实现方案咨询
低内存占用CSV转XLSX实现方案
核心逻辑为放弃全量加载数据到内存的模式,采用分块读取+流式写入的方式完成转换,2GB内存服务器可轻松处理GB级别的CSV文件。
方案一:分块读取+流式写入(需数据处理场景)
如果转换过程中需要对数据做清洗、格式调整等操作,可搭配pandas分块读取+XlsxWriter常量内存模式实现:
- 每次仅读取固定行数的CSV数据到内存处理,处理完成后立即写入Excel
- XlsxWriter的
constant_memory模式会实时将内容写入磁盘/流,不会缓存全量Excel结构到内存
示例代码:
import pandas as pd import xlsxwriter # 可根据实际内存调整分块大小,2GB内存建议设置为10000~50000行 CHUNK_SIZE = 10000 INPUT_CSV_PATH = "source.csv" OUTPUT_XLSX_PATH = "query_set.xlsx" # 初始化支持低内存写入的工作簿 workbook = xlsxwriter.Workbook(OUTPUT_XLSX_PATH, {"constant_memory": True}) worksheet = workbook.add_worksheet() current_row = 0 for chunk in pd.read_csv(INPUT_CSV_PATH, chunksize=CHUNK_SIZE): # 第一块写入表头 if current_row == 0: for col_idx, col_name in enumerate(chunk.columns): worksheet.write(current_row, col_idx, col_name) current_row += 1 # 写入当前块所有行数据 for _, row in chunk.iterrows(): for col_idx, value in enumerate(row): worksheet.write(current_row, col_idx, value) current_row += 1 workbook.close()
方案二:纯流式转换(无数据处理场景,内存占用最低)
如果仅需格式转换无需额外数据处理,可直接用Python原生csv库逐行读取写入,内存占用可稳定控制在100MB以内:
import csv import xlsxwriter INPUT_CSV_PATH = "source.csv" OUTPUT_XLSX_PATH = "query_set.xlsx" workbook = xlsxwriter.Workbook(OUTPUT_XLSX_PATH, {"constant_memory": True}) worksheet = workbook.add_worksheet() with open(INPUT_CSV_PATH, "r", encoding="utf-8") as csv_file: csv_reader = csv.reader(csv_file) for row_idx, row in enumerate(csv_reader): for col_idx, value in enumerate(row): worksheet.write(row_idx, col_idx, value) workbook.close()
S3上传优化
如果不需要本地留存XLSX文件,可直接将内容写入内存字节流上传S3,避免本地磁盘IO开销,示例片段:
from io import BytesIO import boto3 output_stream = BytesIO() # 初始化工作簿时传入字节流 workbook = xlsxwriter.Workbook(output_stream, {"constant_memory": True}) # 此处省略写入逻辑,和上述方案一致 workbook.close() # 重置字节流指针到起始位置 output_stream.seek(0) # 上传到S3 s3_client = boto3.client("s3") s3_client.upload_fileobj(output_stream, "你的S3桶名", "目标文件路径/query_set.xlsx")
关键注意事项
- 禁止直接使用
pandas.DataFrame.to_excel处理大数据,该方法默认会将全量DataFrame和生成的Excel结构全部加载到内存,2GB内存下处理超过500MB的CSV就大概率出现OOM - 若使用openpyxl替代XlsxWriter,可开启
write_only=True模式实现同样的流式写入效果
内容的提问来源于stack exchange,提问作者Birat Bade Shrestha
相关产品推荐
相关产品推荐

