python按某列拆分excel表格_python带格式拆分excel表单,copy库完美搞定

python拆分excel表单,生成单独的excel文件,网上这方面的文章很多。但大多只讲主功能如何实现,让拆分后的表保持和原表单一致的格式,则鲜有人讲。本文通过调用copy库,完美实现带格式拆分表单,过程说明如下:

我们先看看带格式拆分和普通拆分的效果对比

原表样式:

bde746b9276e4ae49dc69be88fb6f3a0

普通拆分效果:

8037237a-c713-4c9d-a247-bc25f3008ce5

带格式拆分效果:

d7f82683-1aa0-4850-9803-edbcca541950

很显然,带格式拆分才是我们真正想要的。那么问题来了,如何实现呢?我们用一个案例说明如下,文末有完整代码。

调用选择文件对话框,选择要拆分的文件

通过调用tkinter.filedialog库,实现弹出选择文件对话框,选择指定文件进行拆分的操作,符合日常习惯。

import tkinter.filedialog as a # 导入调用文件对话框的库

import os

import openpyxl

import copy

if __name__ == "__main__":

ff = a.askopenfilenames(filetypes=[('excel文件', '.xlsx')]) # 限定为只能选.xlsx文件

breakfile(ff) # 调用分解模块进行分解

注:可一次选多个文件批量拆分。其中:askopenfilenames,最后的“s”字符不能漏,不然就只能选单个文件拆分。

分解模块代码:

def breakfile(fn):

g = os.path.split(fn[0])[0]

for gg in fn:

g1 = os.path.splitext(os.path.split(gg)[1])[0]

wb = openpyxl.load_workbook(gg)

if len(wb._sheets) > 1:

for sht in wb._sheets:

wb1 = openpyxl.Workbook()

ws1 = wb1._sheets[0]

copyfile(sht, ws1)

f1 = os.path.join(g, g1 + '-' + sht.title + '.xlsx')

wb1.save(f1)

其中:save语句不能忘,不然看不到结果。结果保存在被拆分文件相同路径文件夹内。

复制写入单元格

def copyfile(sht, sht1):

colwidth(sht, sht1)

rowheight(sht, sht1)

copycell(sht, sht1)

for merg in sht.merged_cells:

sht1.merge_cells(str(merg))

其中:for循环语句为根据原表合并单元格区域,将新表也设置相应的合并单元格。

根据原表设置新表列宽

def colwidth(s0, s1):

for k, co in enumerate(s0.iter_cols()):

k = chr(k+97).upper()

lk = s0.column_dimensions[k].width

if lk == 0:

lk = 8.38

s1.column_dimensions[k].width = lk

注意:此处有坑。

lk = s0.column_dimensions[k].width , 获得原表单某列列宽。

当某列为默认列宽8.38时,lk得到的结果不是8.38,而是0。

s1.column_dimensions[k].width = lk ,将新表单某列列宽设置为与原表对应列宽相同,

当lk为0时,会导致新表所有列列宽都是默认值8.38,而不是只影响当前列列宽。

所以,为了避开这个坑,我们提前用if语句对lk进行判断,

将lk=0的情况,强行设置为lk=8.38

,这样,新表的列宽才能与原表对应上。

根据原表设置新表行高

def rowheight(s0, s1):

for i in range(1, s0.max_row+1):

hg = s0.row_dimensions[i].height

if hg == 0:

hg = 15

s1.row_dimensions[i].height = hg

注意:

0=15的逻辑和设置列宽时0=8.38的逻辑相同。

for循环用for i in range(1, s0.max_row+1):

若用for i, row in enumerate(s0.iter_rows()):,会造成最后一行行高漏设置。

根据原表设置新表单元格值和格式

def copycell(s0, s1):

for i, row in enumerate(s0.iter_rows()):

for j, cell in enumerate(row):

s1.cell(i+1, j+1, cell.value)

s1.cell(i+1, j+1).number_format = cell.number_format

s1.cell(i+1, j+1).alignment = copy.copy(cell.alignment)

s1.cell(i+1, j+1).font = copy.copy(cell.font)

s1.cell(i+1, j+1).border = copy.copy(cell.border)

s1.cell(i+1, j+1).fill = copy.copy(cell.fill)

其中:s1.cell(i+1, j+1, cell.value):设置单元格值一致

s1.cell(i+1, j+1).number_format = cell.number_format:设置数据格式一致

s1.cell(i+1, j+1).alignment = copy.copy(cell.alignment):设置对齐方式一致

s1.cell(i+1, j+1).font = copy.copy(cell.font):设置字体一致

s1.cell(i+1, j+1).border = copy.copy(cell.border):设置表框线条一致

s1.cell(i+1, j+1).fill = copy.copy(cell.fill):设置单元格填充色一致

前面两项,

值和数据格式不需用copy库,直接赋值即可。但其他字体、对齐方式、线框、颜色等不能直接赋值,要用copy

才行。网上也查到过用copy代码的文章,可惜的是,没说全,我依葫芦画瓢写出来不行。原因就是前面必须提前导入copy库,所以第一段代码里就有import copy语句。

生成exe文件后,运行效果:

eccc6ff66cf7491ca0c2750db8977ae8

扩展功能:

根据该方法,可实现根据某个表格样式,批量设置多个表格样式的功能。

附录完整代码:

import tkinter.filedialog as a

import os

import openpyxl

import copy

def colwidth(s0, s1):

for k, co in enumerate(s0.iter_cols()):

k = chr(k+97).upper()

lk = s0.column_dimensions[k].width

if lk == 0:

lk = 8.38

s1.column_dimensions[k].width = lk

def rowheight(s0, s1):

for i in range(1, s0.max_row+1):

hg = s0.row_dimensions[i].height

if hg == 0:

hg = 15

s1.row_dimensions[i].height = hg

def copycell(s0, s1):

for i, row in enumerate(s0.iter_rows()):

for j, cell in enumerate(row):

s1.cell(i+1, j+1, cell.value)

s1.cell(i+1, j+1).number_format = cell.number_format

s1.cell(i+1, j+1).alignment = copy.copy(cell.alignment)

s1.cell(i+1, j+1).font = copy.copy(cell.font)

s1.cell(i+1, j+1).border = copy.copy(cell.border)

s1.cell(i+1, j+1).fill = copy.copy(cell.fill)

def copyfile(sht, sht1):

colwidth(sht, sht1)

rowheight(sht, sht1)

copycell(sht, sht1)

for merg in sht.merged_cells:

sht1.merge_cells(str(merg))

def breakfile(fn):

g = os.path.split(fn[0])[0]

for gg in fn:

g1 = os.path.splitext(os.path.split(gg)[1])[0]

wb = openpyxl.load_workbook(gg)

if len(wb._sheets) > 1:

for sht in wb._sheets:

wb1 = openpyxl.Workbook()

ws1 = wb1._sheets[0]

copyfile(sht, ws1)

f1 = os.path.join(g, g1 + '-' + sht.title + '.xlsx')

wb1.save(f1)

if __name__ == "__main__":

ff = a.askopenfilenames(filetypes=[('excel文件', '.xlsx')])

breakfile(ff)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值