zhimoe

Captain your own Ship.


  • 首页

  • 归档

  • 编程

  • 翻译

  • 随想

  • 关于

  • 搜索

使用OpenPyXL read_only write-only模式读写excel大文件

时间: 2023-05-07   |   分类: 编程   | 字数: 1047 字 | 阅读: 3分钟

使用python OpenPyXL读写excel大文件时,有专门的read_only write-only模式来提升读写效率。

openpyxl read_only mode

from openpyxl import load_workbook
wb = load_workbook(filename='large_file.xlsx', read_only=True)
ws = wb['big_data']

# min_col&max_col: 只处理B列, min_row=2: 从第二行开始, 只读取值
col_index_B = openpyxl.utils.column_index_from_string('B') 
for cell_value in ws.iter_rows(min_row=2, min_col=col_index_B, max_col=col_index_B, values_only=True):
    print(cell_value)

# Close the workbook after reading
wb.close()

只读取第一行的错误

如果你的excel文件是通过第三方软件(数据库客户端)或者代码生成的,很容易遇到一个问题就是上面的ws.iter_rows或ws.rows遍历只会读取第一行。 这是因为read only模式在load_workbook时只读取了文件的元信息,在遍历时也依赖worksheet的元信息,很多非office生成的excel没有正确设置元信息。 你可以通过ws.calculate_dimension()检查excel行列信息,如果返回的是A1:A1等与实际大小不一致的情况,可以通过ws.reset_dimensions()来重置ws的max_row and max_column属性。
注意,ws.reset_dimensions()会读取整个文件,效率会降低到非read_only模式一样。

哎,这个坑花了一下午的排查,就是不认真看一下文档

openpyxl write_only mode

  1. 确保安装了lxml openpyxl两个库
  2. 使用write_only写大数据
from openpyxl import Workbook
wb = Workbook(write_only=True)
ws = wb.create_sheet()

# now we'll fill it with 100 rows x 200 columns
for irow in range(100):
    ws.append(['%d' % i for i in range(200)])
   
# save the file
wb.save('new_big_file.xlsx') # doctest: +SKIP

官方文档

openpyxl Optimised Modes

openpyxl vs xlsxwriter

  1. 两个常用功能和性能上差别不大,部分样式设置有差别。
  2. pandas支持两个,可以通过engine参数切换。

使用polars

polars是使用rust语言编写的DataFrame库,基于arrow格式,提供rust、python、nodejs三种编程语言接口。 目前polars支持读取整个excel文件,但是写文件不行,只能通过转换成pandas的df再处理。本地测试一下polars读取整个excel文件,速度大约是pandas普通模式的两倍,内存使用是pandas的2/3,这个性能和内存,感觉在python领域希望不大,看rust那边的发展了。

polars的API一般是尽可能和pandas保持一致,所以使用起来也比较简单,遇到API缺失的,可以直接转换成pandas的df使用df.to_pandas()

import pandas as pd
import polars as pl  # read_excel还需要xlsx2csv lib

df = pl.read_excel(
    "test.xlsx",
    sheet_id=1,
    xlsx2csv_options={"skip_empty_lines": True},
    read_csv_options={"has_header": True},
)
print(f'{type(df)=}')  # class 'polars.dataframe.frame.DataFrame'
print(f'{df.shape=}')
print(f'{df.head()=}')
for cell in df['Courses']:
    print(f'{cell=}')

polars的输出格式比pandas的好看多了,使用了box-drawing相关的unicode字符打印表格,不过需要编程字体支持才能对齐。

#code# #python#

文章: 使用OpenPyXL read_only write-only模式读写excel大文件 by zhimoe

声明: 本博客文章除特别声明外,均采用 CC BY-NC-SA 3.0许可协议,转载请注明出处!

创作不易,打赏作者 ^_^
WeChat Pay

微信打赏

Alipay

支付宝打赏

Kotlin Coroutine
  • 文章目录
  • 站点概览
zhimoe

zhimoe

Captain your own Ship.

68 日志
4 分类
42 标签
GitHub ZhiHu
书签
  • 可视化学习Git
  • 艺术绘画博物馆
  • RustCheatsheet
  • 谷歌机器学习课程
标签云
  • Code
  • Java
  • Scala
  • Python
  • Rust
  • Qq空间
  • Spring
  • 并发
  • Docker
  • Git
    • openpyxl read_only mode
    • openpyxl write_only mode
    • 官方文档
    • openpyxl vs xlsxwriter
    • 使用polars
© 2016 - 2023 zhimoe
0%