InMemoryWorkbook 内存工作簿¶
本页面详细介绍如何使用InMemoryWorkbook进行完全基于内存的Excel处理,适合高性能场景和Web应用。
概述¶
InMemoryWorkbook是完全基于内存的Excel工作簿类,所有操作都在内存中完成,无需写入临时文件,提供高性能的数据处理能力。
主要特性¶
- ✅ 完全内存操作 - 无需临时文件
- ✅ 字节级操作 - 支持
from_bytes()和to_bytes() - ✅ 流式处理 -
to_stream()返回BytesIO流 - ✅ 模板支持 -
from_template()直接渲染模板 - ✅ 工作簿合并 -
merge_with()合并多个工作簿 - ✅ 克隆功能 -
clone()快速复制工作簿 - ✅ 内存管理 - 自动内存优化和清理
基本用法¶
创建内存工作簿¶
from symphra_excel.memory_ops import InMemoryWorkbook
# 创建新的内存工作簿
wb = InMemoryWorkbook()
# 获取或创建工作表
sheet = wb.create_worksheet("数据表")
# 设置数据
sheet.set_cell_value("A1", "姓名")
sheet.set_cell_value("B1", "年龄")
sheet.set_cell_value("A2", "张三")
sheet.set_cell_value("B2", 25)
print(f"工作表名称: {wb.get_sheet_names()}")
转换为字节数据¶
# 获取Excel文件的字节数据
excel_bytes = wb.to_bytes()
print(f"文件大小: {len(excel_bytes)} 字节")
# 保存到文件
with open("output.xlsx", "wb") as f:
f.write(excel_bytes)
从字节数据加载¶
# 从字节数据创建新的内存工作簿
wb2 = InMemoryWorkbook.from_bytes(excel_bytes)
# 验证数据
sheet2 = wb2.get_worksheet("数据表")
if sheet2:
value = sheet2.get_cell_value("A2")
print(f"读取的值: {value}")
使用上下文管理器¶
from symphra_excel.memory_ops import InMemoryWorkbook
# 自动清理资源
with InMemoryWorkbook() as wb:
sheet = wb.create_worksheet("临时数据")
sheet.set_cell_value("A1", "临时内容")
data = wb.to_bytes()
# wb.cleanup() 会自动调用
完整示例¶
示例1: 基础内存操作¶
from symphra_excel.memory_ops import InMemoryWorkbook
def create_product_catalog():
"""创建产品目录并返回字节数据"""
wb = InMemoryWorkbook()
# 创建工作表
sheet = wb.create_worksheet("产品目录")
# 设置表头
headers = ["产品ID", "产品名称", "价格", "库存"]
for col, header in enumerate(headers, start=1):
sheet.set_cell_value(f"{chr(64+col)}1", header)
# 添加产品数据
products = [
["P001", "笔记本电脑", 5999.99, 50],
["P002", "无线鼠标", 89.99, 200],
["P003", "机械键盘", 299.99, 100],
]
for row_idx, product in enumerate(products, start=2):
for col_idx, value in enumerate(product, start=1):
cell = f"{chr(64+col_idx)}{row_idx}"
sheet.set_cell_value(cell, value)
# 返回字节数据
return wb.to_bytes()
# 使用
excel_data = create_product_catalog()
print(f"生成了 {len(excel_data)} 字节的Excel数据")
# 保存到文件
with open("产品目录.xlsx", "wb") as f:
f.write(excel_data)
示例2: 工作簿合并¶
from symphra_excel.memory_ops import InMemoryWorkbook
def merge_excel_files():
"""合并多个Excel文件"""
# 创建第一个工作簿
wb1 = InMemoryWorkbook()
sheet1 = wb1.create_worksheet("销售数据")
sheet1.set_cell_value("A1", "日期")
sheet1.set_cell_value("B1", "销售额")
sheet1.set_cell_value("A2", "2024-01-01")
sheet1.set_cell_value("B2", 10000)
# 创建第二个工作簿
wb2 = InMemoryWorkbook()
sheet2 = wb2.create_worksheet("销售数据")
sheet2.set_cell_value("A1", "日期")
sheet2.set_cell_value("B1", "销售额")
sheet2.set_cell_value("A2", "2024-01-02")
sheet2.set_cell_value("B2", 15000)
# 合并工作簿
merged = wb1.merge_with(wb2, merge_strategy="append")
# 保存合并后的数据
return merged.to_bytes()
# 使用
merged_data = merge_excel_files()
print("工作簿合并完成")
示例3: 模板渲染¶
from symphra_excel.memory_ops import InMemoryWorkbook
def render_invoice_template():
"""从模板渲染发票"""
# 首先创建模板文件
from symphra_excel import Workbook
template_wb = Workbook()
template_sheet = template_wb.create_worksheet("发票")
template_sheet.set_cell_value("A1", "发票号码: {{ invoice_no }}")
template_sheet.set_cell_value("A2", "日期: {{ date }}")
template_sheet.set_cell_value("A3", "客户: {{ customer_name }}")
template_sheet.set_cell_value("A5", "金额: {{ amount }}")
template_wb.save("invoice_template.xlsx")
# 使用InMemoryWorkbook从模板渲染
context = {
"invoice_no": "INV-2024-001",
"date": "2024-11-02",
"customer_name": "ABC公司",
"amount": "¥10,000.00"
}
wb = InMemoryWorkbook.from_template("invoice_template.xlsx", context)
return wb.to_bytes()
# 使用
invoice_data = render_invoice_template()
with open("发票_2024-001.xlsx", "wb") as f:
f.write(invoice_data)
示例4: 流式处理¶
import io
from symphra_excel.memory_ops import InMemoryWorkbook
def process_stream():
"""处理内存流"""
wb = InMemoryWorkbook()
sheet = wb.create_worksheet("数据")
# 添加一些数据
sheet.set_cell_value("A1", "测试数据")
# 转换为流
stream = wb.to_stream()
print(f"流大小: {stream.getbuffer().nbytes} 字节")
# 从流重新读取
stream.seek(0)
wb2 = InMemoryWorkbook.from_bytes(stream.read())
return wb2
# 使用
processed_wb = process_stream()
InMemoryTemplateWorkbook¶
专门用于模板渲染的内存工作簿:
from symphra_excel.memory_ops import InMemoryTemplateWorkbook
# 加载模板
wb = InMemoryTemplateWorkbook("template.xlsx")
# 渲染数据
context = {
"title": "月度报告",
"date": "2024-11-02",
"total_sales": 100000
}
wb.render(context)
# 获取字节数据
data = wb.to_bytes()
# 获取模板变量(检查模板中有哪些占位符)
variables = wb.get_template_variables()
print(f"模板变量: {variables}")
# 渲染特定工作表
wb.render_worksheet("Sheet1", {"key": "value"})
内存优化¶
InMemoryWorkbook集成了内存管理器:
from symphra_excel.memory_ops import InMemoryWorkbook
from symphra_excel.utils.memory_manager import MemoryStrategy
# 使用自定义内存策略
wb = InMemoryWorkbook()
# 获取内存使用情况
memory_info = wb.get_memory_usage()
print(f"内存使用: {memory_info}")
# 手动优化内存
optimization_result = wb.optimize_memory()
print(f"优化结果: {optimization_result}")
完整操作列表¶
工作簿操作¶
# 创建工作表
sheet = wb.create_worksheet("新工作表")
# 获取工作表
sheet = wb.get_worksheet("工作表名")
# 删除工作表
success = wb.delete_worksheet("工作表名")
# 获取所有工作表名称
names = wb.get_sheet_names()
数据操作¶
# 设置单元格值
sheet.set_cell_value("A1", "值")
sheet.set_cell_value("B2", 123)
sheet.set_cell_value("C3", True)
# 批量设置范围值
data = [
["A", "B", "C"],
[1, 2, 3],
[4, 5, 6]
]
sheet.set_range_values("A1:C3", data)
# 获取单元格值
value = sheet.get_cell_value("A1")
# 获取范围值
values = sheet.get_range_values("A1:C3")
最佳实践¶
✅ 推荐做法¶
from symphra_excel.memory_ops import InMemoryWorkbook
from symphra_excel.utils.format_fix import fix_xlsx
# 1. 使用上下文管理器自动清理
with InMemoryWorkbook() as wb:
sheet = wb.create_worksheet("数据")
# ... 处理数据 ...
data = wb.to_bytes()
# 2. 修复格式(如果需要)
with open("temp.xlsx", "wb") as f:
f.write(data)
fix_xlsx("temp.xlsx")
# 3. 检查模板变量
wb = InMemoryTemplateWorkbook("template.xlsx")
variables = wb.get_template_variables()
print(f"模板需要的变量: {variables}")
❌ 避免的做法¶
# 1. 不清理大对象
wb = InMemoryWorkbook()
# ... 处理大量数据 ...
# 缺少 wb.cleanup() 或上下文管理器
# 2. 频繁创建小工作簿
for i in range(1000):
wb = InMemoryWorkbook() # 效率低
# ...
# 3. 不检查工作表是否存在
sheet = wb.get_worksheet("不存在的工作表")
if sheet is None: # 应该检查!
# ...
性能优化¶
批量操作¶
# 高效:批量设置
data = [[f"值{i}-{j}" for j in range(10)] for i in range(1000)]
sheet.set_range_values("A1:J1000", data)
# 低效:逐个设置
for i in range(1000):
for j in range(10):
cell = f"{chr(65+j)}{i+1}"
sheet.set_cell_value(cell, f"值{i}-{j}")
内存管理¶
# 及时优化内存
wb = InMemoryWorkbook()
# ... 处理大量数据 ...
wb.optimize_memory()
# 使用克隆而不是重新创建
wb1 = InMemoryWorkbook()
# ... 设置数据 ...
wb2 = wb1.clone() # 快速克隆