将Excel大表按某列单元格的值拆分成小表(openpyxl)

原文:Python应用: 将Excel大表按某列单元格的值拆分成小表

有时候需要将Excel大表,按某列单元格的值拆分成许多个小表。

如把年度总表按月份拆分成小表,把所有账户的流水表拆成单个账户的流水表,诸如此类。

如果是数据库倒也方便,但对Excel来说,当工作量大的时候,这无疑是件折磨人的事情。

于是尝试用Python写了一段代码,因为还在学习中,写得很糙,但调试后,感觉还能用。

生成的小表单元格格式完全是“素颜”,待有空再完善吧。

---------------------------------------------------------------------------------------------------------------------------


代码如下:

#!python3

# -*- coding:utf-8 -*-

# 将Excel大表按某列单元格的值拆分成小表

# 1. 首行为字段名(表头)

# 2. 表中不能有合并的单元格

# By Zero, 2023/3/22

import openpyxl

from openpyxl.utils import get_column_letter

def copyrow(sheet,rownum,fname):

    f=openpyxl.load_workbook(fname)

    if rownum==1:

        rownum2=1

    else:

        rownum2=f._sheets[0].max_row+1

        

    for col in range(1,sheet.max_column+1):

        n=get_column_letter(col)

        

        i='%s%d'%(n,rownum)#大表单元格编号

        cell1=sheet[i].value

        j='%s%d'%(n,rownum2)#小表单元格编号

        f._sheets[0][j].value=cell1

    f.save(fname)

    f.close

    return()

    

#Excel所在绝对路径

fPath='E:\\py3\\myapp\\'    

#Excel文件名

fName='test.xlsx'                  

wb=openpyxl.load_workbook(fPath+fName) 

sheet=wb['Sheet1'] #将要拆分的大表

#首行(标题行)

xh=[]

print('序号  字段(表头)\n---------------------')

for i in range(1,sheet.max_column+1):

    c=sheet.cell(1,i).value

    xh.append([i,c])

    print(i,c)

    

while True:

    x=input('\n请输入字段的序号:')

    if x.isdecimal():

        if int(x)   in range(1,sheet.max_column+1):

            break

        else:

            print('\nERROR :输入的数字超范围,请正确输入!')    

    else:

        print('\nERROR :输入的不是数字,请正确输入!')

sliceWord=xh[int(x)-1][1]   #要拆分的列

print ('\n将按字段  '+sliceWord+'  进行拆分表………………\n\n')

pieces=[]   #小表表名列表

for row in range(2,sheet.max_row +1):

    c=sheet.cell(row,int(x)).value

    if c=='#N/A' or c==None:        #处理空值或无效值

        c='NA'

    fname=fPath+'out_'+sliceWord+'_'+c+'.xlsx' #小表表名

    if c not in pieces:

        pieces.append(c)

        openpyxl.Workbook().save(fname)

        copyrow(sheet,1,fname)#复制首行(表头)

        

    copyrow(sheet,row,fname)#复制行到小表

    print ('复制第 '+str(row)+' 行到 '+fname)

print('\n-------------------拆分表已完成!-------------------')

补充:在之后的实战中,发现openpyxl模块在处理 Excel行数超过1w 的时候就力不从心了,速度会越来越慢,甚至半天不动。做了优化(参见官方文档Optimised Modes,打开文件时为只读模式)但效果甚微。

查阅了许多资料,说这就是openpyxl的短板,每次读取数据都要从首行首列开始,逐个单元格地读,意味着离单元格A1越远,花费的时间就越长。

有文章说,在遍历excel时,用ws.cell.value来遍历单元格的值速度慢,用ws.rows来遍历单元格速度更快(文见解决openpyxl读取数据量较大的excel时速度缓慢的问题_openpyxl写入excel多行非常慢_酱酱小可爱的博客-CSDN博客)。试了一下,处理6w行时,还是不尽人意。

后来又查阅了一些资料,做了一些对比,发现在处理大表时,还是用xlrd 和xlwt配合效果好一些。修改后的代码见:将Excel大表按某列单元格的值拆分成小表(xlrd与xlwt)_dlmyang的博客-CSDN博客

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值