分享

python带格式拆分excel表单,copy库功不可没

 我的人生宝库 2019-12-15

python拆分excel表单,将每个表单生成单独的excel文件,网上这方面的文章很多。但是,有个细节鲜有人讲,那就是如让拆分后表格样式与原表一致,不需拆分后手动设置。我们先看看带格式拆分和不带格式拆分的效果对比。

原表样式:

python带格式拆分excel表单,copy库功不可没

不带格式拆分:

python带格式拆分excel表单,copy库功不可没

带格式拆分效果:

python带格式拆分excel表单,copy库功不可没

对比效果一目了然,那么问题来了,如何实现python带格式拆分表单呢?用copy库是重点:

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

最初,写了个将当前文件夹下的excel文件进行拆分功能。但实际使用时,总是复制生成的exe文件到文件夹,也很麻烦。于是优化为调用文件对话框,选择指定文件的方式,更符合日常习惯。

import tkinter.filedialog as a # 导入调用文件对话框的库import osimport openpyxlimport copyif __name__ == '__main__': ff = a.askopenfilenames(filetypes=[('excel文件', '.xlsx')]) # 限定为只能选.xlsx文件 breakfile(ff) # 调用分解模块进行分解

分解模块代码:


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

其中:if语句为当原表列宽为默认时,值为8.38,但系统显示为0,所以要进行设置,当发现系统显示列宽为0,则将值强制赋值为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

其中:if语句作用同上。

for循环用range(1, s0.max_row+1),若用设置列宽时for循环的

for k, co in enumerate(s0.iter_cols()):,会造成最后一行行高漏设置。


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

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文件后,运行效果:

python带格式拆分excel表单,copy库功不可没

扩展功能:

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

附录完整代码:

import tkinter.filedialog as aimport osimport openpyxlimport copydef 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 = lkdef 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 = hgdef 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)def prfont(fn): for f in fn: wb = openpyxl.load_workbook(f) ws = wb.active fon = ws.cell(2, 3).font print(fon)if __name__ == '__main__': ff = a.askopenfilenames(filetypes=[('excel文件', '.xlsx')]) breakfile(ff)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多