使用xlwings拆分excel并调用outlook进行邮件发送

14 篇文章 0 订阅

写这段代码的起因是因为公司要下发一个销售日报表,但是由于不同部门的销售区域老总看到的只能是自己区域的数据,每个工作簿有10多个工作表,如果靠手工来做工作量极大,因此,有迫切的需求要对报表做一些自动化操作,并能自动发送邮件。在做到以上的基础上,还要顾及美观。
表格的截图如下:
可以看到这个表格处理的几个关键点:
1、有组合,要取消组合,目前python还没法实现(我没找到办法),所以必须要调用VBA
2、有隐藏的sheet,其实是3级组合,要展示出来
3、要根据2级组合里的区域,分别发给对应的区域
4、要保留原格式
在这里插入图片描述

import xlwings as xw
import win32com.client as win32

 程序运行的时候不显示在前端,也不新建Excel窗口
app = xw.App(visible=False,add_book=False)



ywb = ["浙江部","河南部","KA部","黑龙江部","广西部","江西部","海南部","广东部"]
for i in range(0,len(ywb)):  # 这是循环的开始,读取业务部的数量,每个业务部作为一个最大的循环
    # print(i)
    iw = app.books.open(r'E:\Documnet\工作\07_数据分析\临时文件\副本.xlsm')
    sheet_count = iw.sheets.count # 读取整个工作簿的sheet数量


   # 由于源文件里还有很多隐藏的工作表不可以下发给各区域,而所有文件格式都#是一样,因此这里定义了一个函数sheet_names(),
    用来读取第一个“全品项销额”在工作表中的位置,并以此作为下发给区域的第一个表格

    def first_sheet():
        for ii in range(0, sheet_count):
            if iw.sheets[ii].name == "全品项销额":
                return ii
    # break # 写代码的时候测试用,阶段性中断程序
    # range左闭右开,所以需要需要页面总数+1,与python计数序列从0开始的习惯不同,xlwings的行列计数都是从1开始,下面会用到
    for sht in range(first_sheet(),sheet_count+1): # 开始对每个页面做循环
        oldsht = iw.sheets(sht)
        # print(oldsht.name)
        rownumber = oldsht.range('A10000').end('up').row
        # 另一个写法是rownumber  = oldsht.used_range.last_cell.row
        # print(rownumber)
        # 由于暂无法实现先复制再粘贴,所以我用的是直接在源文件里改动,然后另存为的办法
        # 以下这个循环是先从最后一行往上找,直到找到对应的单元格,rownumber和1表示范围, -1表示每次循环的step
        for r1 in range(rownumber,1,-1):
            # print(oldsht.cells(r,2).value)
            # print(oldsht.cells(r,2).value)
            # print(ywb[i])
            if oldsht.cells(r1,2).value == ywb[i]:
                # 可以用range直接表示行或者列,但是无论是行还是列都应以文本形式出现,字母指代列,数字指代行
                oldsht.range(str(r1+1) + ':' + str(500)).delete()
                break
        # 由于目标业务部的上方还有可能有其他的业务部,因此,还需要从上往下再删一次
        print('阶段一完成')
        while i != 0:
            for r2 in range(5,rownumber):
                if oldsht.cells(r2,2).value == ywb[i-1]:
                    oldsht.range('5'+':'+str(r2)).delete()
                    break
            break
        print('阶段二完成')
        #----以上就是把不需要的行都删除了
        #-----以下是调用宏,把原有的组合取消,并取消隐藏的行,宏代码如下:
        '''
        Sub ungroup()
        Rows("3:150").ClearOutline
        Rows("3:150").EntireRow.Hidden = False
        Range("B5").Select
        End Sub
        '''
        oldsht.activate()
        ungroup = iw.macro('ungroup')
        ungroup()
        #-----然后下面的循环是把多余的sheet删除,一共有多少个sheet,就删多少次
    for iii in range(0,first_sheet()):
            iw.sheets[0].delete()
    # -----多余sheet删除完毕
    # 最后让第一个sheet成为active sheet
    iw.sheets[0].activate()

    # 由于试了很多办法,都没有简便的办法先将sheet带格式复制出来再粘贴,只好反其道而行之,直接在源文件
    # 中做改变,然后将改变后的源文件另存为并关闭
    iw.save(r'E:\Documnet\工作\07_数据分析\临时文件\test' + '\\' + ywb[i] + '.xlsm')
    iw.close()
    # 到这里改造基本完成,但问题是由于源工作簿中有宏,所以必须另存为xlsm格式,xlwings暂时没找到直接另存为xlsx的办法
    # 因此只能用win32com模块调用excel本身的saveas接口进行另存为操作,正好发邮件也得用到win32com
    # --------------以下是另存为xlsx
    xlApp = win32.DispatchEx("Excel.Application")
    xlApp.Visible = True
    xlApp.DisplayAlerts = 0
    xlBook = xlApp.Workbooks.Open(r'E:\Documnet\工作\07_数据分析\临时文件\test' + '\\' + ywb[i] + '.xlsm', False)
    xlBook.SaveAs(r'E:\Documnet\工作\07_数据分析\临时文件\test' + '\\' + ywb[i] + '.xlsx', FileFormat=51)
    #上面的FileFormat是调用了Excel本身的SaveAs接口,51就是xlsx的代码
    xlBook.Close(False)
    xlApp.Quit()
    # -------------另存为结束
    #---------以上是获取工作簿并进行操作,以下是进行邮件操作,用到的模块为win32----------#
    outlook = win32.Dispatch('Outlook.Application')
    Mail_Item = outlook.CreateItem(0)
    Mail_Item.Recipients.Add('zhuce@cuixiaoyuan.cn')
    # 应先在邮箱通讯录中建立邮件组,直接输入邮件组名字可以发送
    Mail_Item.Subject = 'zhuce@cuixiaoyuan.cn'
    Mail_Item.BodyFormat = 2
    Mail_Item.HtmlBody = '''
                         Hello Guys,<br/>
                         &nbsp;&nbsp;&nbsp;&nbsp;This a Mail send by Jerry'''
    Mail_Item.Attachments.Add(r'E:\Documnet\工作\07_数据分析\临时文件\test' + '\\' + ywb[i] + '.xlsx')
    Mail_Item.Save()
    #------------邮件发送完成----------------------------------------------------------#
    print(ywb[i]+'完成')
    app.quit()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

White_Mountain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值