跳转至

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()  # 快速克隆

下一步