需求描述是:将C列的内容(3,4,5)合并在一起之后,将5,6,7三行合并成一行
效果如下:
2.思路
需求很清晰,简单。但是数据量不是上面这样简单的几行
在原数据中,我们要合并的内容就是E列(对应上述的C列)。
在A列(通话开始时间)中,有些时间单元格是合并单元格,有些不是,只有对于合并单元格的,它对应的E列才需要我们合并。
所以,先找出A列合并的单元格,对于其同行的E列内容进行合并,最后将相应的行合并为一行
-
编码
① 找出合并的单元格。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)
for cell in list:
sheet.unmerge_cells(cell)
i=1
content=sheet['A']
for cell in content:
if cell.value==None:
sheet.delete_rows(i)
else:i+=1
新工作数据输出模式是用excel,大概是每天导出新数据并用excel体现,同时要保留之前的数据。
我来之前,同时写好了许多sql,然后就从Navicat里面复制粘贴到excel中。
我目前在做关于这个的自动化脚本,使用的库是openpyxl,下面说说关于这个的几个小bug。
1- 在 2.5.x版本中,当你合并单元格的时候
使用的是merg...
1.问题
使用Python的openpyxl库操作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(...