真正的行删除

想用python实现excel的手动行删除,但是pandas库只支持不带格式地读取数据和写入数据,它的基础库xlwt和xlrd也是这样,因此查到的教程一旦使用这两种库,都是读取源文件把清理后的数据写入一个新文件。他们都不能实现覆写源文件,而且输出都是默认不带格式的。

日常处理别人做的excel表,基本是带有格式的,如果这张表处理完还需要保留原来的格式,尤其是合并单元格,那就相当麻烦。

目前我找到的能直接修改excel源文件的只有两个库,win32com和openpyxl,win32com是以调用VBA的方式实现操作,尽管这种间接的方式听起来很麻烦,但很有用。openpyxl自带load_workbook方法实现修改文件,就是它的官方文档有的东西藏得太深了,只讲了一些比较基础的东西,要找特定的功能时就比较抓狂。

对比条件

分别删除第2,3行,对比行删除效果。

示例表格

image.png

合并单元格的特性

合并单元格并不是把几个单元格真正合并成一个,它只是为这个区域覆盖了一个伪格式,然后选择了左上角第一个单元格的数据作为这个区域的值。openpyxl在删除行的时候不会删除这个伪格式,但win32com可以实现手动操作时的效果。

win32com

删除第三行

  1. import win32com,win32api
  2. xlApp = win32com.client.Dispatch('Excel.Application')
  3. xlBook = xlApp.Workbooks.Open(r'E:\工作文件汇总\program_for_excel\sample2.xlsx')
  4. xlApp.ActiveWorkbook.Sheets(1).Rows(3).Delete() #Rows就是删除行,这里是删除第三行
  5. xlBook.Save()
  6. xlApp.quit()

删除后
image.png
由于外框线是分配到每个单元格的格式,删除第三行就等于把第三行连带的框线一起删除掉。所以23行的合并单元格下框线没有了,而234行的合并单元格,由于第三行只有左右框线,所以删除后对上下框线没有影响。

第二行

image.png

合并单元格引用的是左上角单元格的数据,第二行删除后引用的数据没有了,但是剩余合并单元格仍然保留。这就好像切豆腐一样,切了一刀剩下的不会四分五裂,还会保留方正的外形。

注意,如果要删除合并单元格所在的所有行,如果是从数据行(左上角第一个单元格所在的行)删除,那么语句里的行数就不要变。比如我要删除23行的合并单元格,就只要把一条语句执行两次。

  1. xlApp.ActiveWorkbook.Sheets(1).Rows(2).Delete()
  2. xlApp.ActiveWorkbook.Sheets(1).Rows(2).Delete()

因为删除一行后,后面的数据动态顶替之前的行。

openpyxl

删除第二行

  1. import openpyxl
  2. dg = openpyxl.load_workbook('sample2.xlsx')
  3. sheet_obj = dg.active
  4. sheet_obj.delete_rows(2)
  5. dg.save('sample3.xlsx')

image.png

可以看到openpyxl行删除不能破坏合并单元格的格式,而且合并单元格是覆盖在标砖单元格上的。

把合并单元格解开

image.png
其实就变成类似win32com处理后的表格了

删除第3行同理,就不演示了

行删除方法

openpyxl的行删除方法在它的源代码那里有
补充一下,搜索delete_rows