相关文章推荐
乐观的签字笔  ·  Java ...·  10 月前    · 
非常酷的红茶  ·  关于Copy On Write Array ...·  1 年前    · 
悲伤的大熊猫  ·  Qt + WindowsAPI ...·  1 年前    · 

需求描述是:将C列的内容(3,4,5)合并在一起之后,将5,6,7三行合并成一行
效果如下:
在这里插入图片描述
2.思路
需求很清晰,简单。但是数据量不是上面这样简单的几行
在这里插入图片描述
在原数据中,我们要合并的内容就是E列(对应上述的C列)。
在A列(通话开始时间)中,有些时间单元格是合并单元格,有些不是,只有对于合并单元格的,它对应的E列才需要我们合并。

所以,先找出A列合并的单元格,对于其同行的E列内容进行合并,最后将相应的行合并为一行

  1. 编码
    ① 找出合并的单元格。excel的合并单元格中, 只有单元格的第一行内容是不为空的,其余行内容为空 。所以直观思路是遍历A列的单元格,如果行内容为空,就开始记录行数,直到遇到下一个不为空的内容。之间记录的行数就是合并单元格的行数范围。

但是这样有些“呆”。openpyxl给我们提供了现成的方法:

sheet.merged_cells

该方法会返回一个列表,包含了所有合并单元格的范围。我们print输出sheet.merged_cells,结果如下:
在这里插入图片描述
以第一项为例,“A4:A9”,表明A列第四行到第九行是合并单元格。至此第一个目标实现

②将E列的内容合并。
首先我们需要获取合并单元格的行范围,方便后续操作。很简单的一个字符串处理,不赘述。

for crange in sheet.merged_cells:
    cells=str(crange)
    if cells[0]!='A':
        break
    index=cells.find(':')
    start=cells[1:index]
    end=cells[index+2:]

合并单元格,openpyxl给我们提供的方法是sheet.merge_cells('start:end')
但是该方法操作,不等同于合并单元格内容。也就是说,会将若干行单元格合并,同时内容只保留第一行的
所以我们需要遍历start to end,先将每一行内容保存到一起,然后合并单元格后,将内容存回去。

    content=""
    area=sheet[f'E{start}:E{end}']
    for i in area:
        for j in i:
            if(j.value!=None):
                content+=(j.value+'\n')
    sheet.merge_cells(f'E{start}:E{end}')
    sheet['E'+f'{start}'].value=content

③将多行合并成一行。
以最开始那张图为例,6/7行是冗余的,我们希望将5,6,7行合并成一行。

最直接的想法是删掉5,6,7行。我们也这样做了。
代码很简单,

sheet.delete_rows(idx=int(start)+1,amount=int(end)-int(start))

但是效果是错的。会发现,有很多单元格莫名其妙地被删掉了,似乎没有任何规律可循

分析之后,结论是:在初始的for循环当中:

for crange in sheet.merged_cells:

**这里的merged_cells的内容是一次生成的,不是每次取出一个crange的时候,就去run一遍sheet.merged_cells,更新一遍。**比如这个list的内容是[1 2 3],那么这个for循环就相当于一个指针在遍历list的内容。

问题就在这里,我们每次取出一个单元格,del掉多余的行之后,后面的行是会顺位补上去的。,也就导致,后面那些合并单元格,其位置会变化。
比如A4:A9是一个合并单元格。A10:A11是一个合并单元格。
将5-9行多余的删去后,10-11行顺位上填充,变成了A5-A6.但是我们的merged_cells并没有变化,所以删的时候还是删的11行,这就导致很多行被莫名其妙删掉。

另外一个问题是由于我们AB,C,D等列的对应内容是合并单元格,所以如果想要del掉多余的列的话,只会del掉E列(5-9)行,(此时我们E列还没有合并的情况下。)
也就是对于A4:A9,直接del 5-9行,ABCD列的行内容不会被删,但是E列的会被删。于是就出现了E列内容错位的问题。

如何规避以上问题?

将E列内容合并后,将所有合并单元格拆解。
然后遍历每一行,如果单元格内容为空,则del掉。

list=[]
for crange in sheet.merged_cells:
    cells=str(crange)
    list.append(cells)
#print(list)
for cell in list:
    sheet.unmerge_cells(cell)
i=1
content=sheet['A']
for cell in content:
    #print(cell.value)
    if cell.value==None:
        sheet.delete_rows(i)
    else:i+=1
新工作数据输出模式是用excel,大概是每天导出新数据并用excel体现,同要保留之前的数据。
我来之前,同写好了许多sql,然后就从Navicat里面复制粘贴到excel中。
我目前在做关于这个的自动化脚本,使用的openpyxl,下面说说关于这个的几个小bug。
1- 在 2.5.x版本中,当你合并单元格的候
使用的是merg...
				
1.问题 使用Pythonopenpyxl操作Excel数据文件,数据格式是float类型,在处理过程中数据都很正常,结果保存之后数据格式变成了间格式:date.time。 一直以为是Python代码写得有问题,找了很多资料都无法解决。 直到详细地看了每操作一次之后,数据格式的变化,发现在writer.save()保存之前数据格式都是保持float格式,保存之后直接变成date.time格式。 于是判断会不会是Excel本身的问题,直到找到一篇资料:excel表格保存之后再次打开全部变成日期
import openpyxl as xl from openpyxl.worksheet.worksheet import Worksheet from openpyxl.cell import MergedCell from openpyxl import Workbook, load_workbook from openpyxl.cell import MergedCell from openpyxl.worksheet.cell_range import CellRange def cell_.
openpyxl处理.xlsx合并单元格数据 一、之前学过xlrd处理.xls格式的excel数据,想着excel使用.xlsx格式比较多,所以用openpyxl做一个处理.xlsx格式的excel数据(仅供参考) 二、思路:(我这里只展示一个表单的情况) 1.读取excel文件 2.获取表单里面单元格数据(包含普通单元格、合并单元格) 3.将单元格数据用字典形式存在列表中 1.读取excel文件: 1.1、首先下载第三方openpyxl,进入doc使用命令pip install openpy
心得:今天下班比较晚,但还是想把自己学到得东西,给记录下来,供自己和大家参考学习,加油。 今天写一篇关于对excel数据存储,数据读取的用法,学会了这个模块,处理数据会变得更加便捷,来一起看看怎么用吧: 1.导入模块 2.实例化对象 3.操纵表格,读或者写 4.保存表格 写入数据 看一个简单的例子: import openpyxl #导入模块 wb=openpyxl.Workbook(...