真正的行删除
想用python实现excel的手动行删除,但是pandas库只支持不带格式地读取数据和写入数据,它的基础库xlwt和xlrd也是这样,因此查到的教程一旦使用这两种库,都是读取源文件把清理后的数据写入一个新文件。他们都不能实现覆写源文件,而且输出都是默认不带格式的。
日常处理别人做的excel表,基本是带有格式的,如果这张表处理完还需要保留原来的格式,尤其是合并单元格,那就相当麻烦。
目前我找到的能直接修改excel源文件的只有两个库,win32com和openpyxl,win32com是以调用VBA的方式实现操作,尽管这种间接的方式听起来很麻烦,但很有用。openpyxl自带load_workbook方法实现修改文件,就是它的官方文档有的东西藏得太深了,只讲了一些比较基础的东西,要找特定的功能时就比较抓狂。
对比条件
分别删除第2,3行,对比行删除效果。
示例表格
合并单元格的特性
合并单元格并不是把几个单元格真正合并成一个,它只是为这个区域覆盖了一个伪格式,然后选择了左上角第一个单元格的数据作为这个区域的值。openpyxl在删除行的时候不会删除这个伪格式,但win32com可以实现手动操作时的效果。
win32com
删除第三行
import win32com,win32api
xlApp = win32com.client.Dispatch('Excel.Application')
xlBook = xlApp.Workbooks.Open(r'E:\工作文件汇总\program_for_excel\sample2.xlsx')
xlApp.ActiveWorkbook.Sheets(1).Rows(3).Delete() #Rows就是删除行,这里是删除第三行
xlBook.Save()
xlApp.quit()
删除后
由于外框线是分配到每个单元格的格式,删除第三行就等于把第三行连带的框线一起删除掉。所以23行的合并单元格下框线没有了,而234行的合并单元格,由于第三行只有左右框线,所以删除后对上下框线没有影响。
第二行
合并单元格引用的是左上角单元格的数据,第二行删除后引用的数据没有了,但是剩余合并单元格仍然保留。这就好像切豆腐一样,切了一刀剩下的不会四分五裂,还会保留方正的外形。
注意,如果要删除合并单元格所在的所有行,如果是从数据行(左上角第一个单元格所在的行)删除,那么语句里的行数就不要变。比如我要删除23行的合并单元格,就只要把一条语句执行两次。
xlApp.ActiveWorkbook.Sheets(1).Rows(2).Delete()
xlApp.ActiveWorkbook.Sheets(1).Rows(2).Delete()
因为删除一行后,后面的数据动态顶替之前的行。
openpyxl
删除第二行
import openpyxl
dg = openpyxl.load_workbook('sample2.xlsx')
sheet_obj = dg.active
sheet_obj.delete_rows(2)
dg.save('sample3.xlsx')
可以看到openpyxl行删除不能破坏合并单元格的格式,而且合并单元格是覆盖在标砖单元格上的。
把合并单元格解开
其实就变成类似win32com处理后的表格了
删除第3行同理,就不演示了
行删除方法
openpyxl的行删除方法在它的源代码那里有
补充一下,搜索delete_rows