python 使用win32com实现对

发布时间:2019-05-24 21:54:08编辑:auto阅读(2660)

           最近由于工作需要,需要将70个word文件的页眉页脚全部进行修改,在想到这个无聊/重复/没有任何技术含量的工作时,我的内心是相当奔溃的。就在我接近奔溃的时候我突然想到完全可以用python脚本来实现这样无聊的工作,确定目标后我便开始在网上寻找有没有造好的轮子,但是结果让我有点儿失望。关于python操作页眉页脚的文章屈指可数,仅存在的几篇也都是片段代码,仅仅可以参考而已,于是我便决定自己是实现批量替换页眉页脚的脚本。

      经过搜集资料发现,python可以通过win32com以及docx扩展包来实现对word的操作,但是经过实际操作发现docx对文件页眉页脚的处理不是很理想,于是我最终决定使用win32com来实现此功能。

      使用的模块确定下来后就是思路的问题,小小的记录一下:

      1、替换页眉页脚可以分成两个部分来实现,一个是针对单个文件的处理,另一个是针对文件夹下所有文件的处理,为了分别对此两种情况进行不同的处理使用if判断语句来让程序进入不同的逻辑。

      2、针对文件夹下所有文件需要处理的情况,则使用python的内置模块os将文件夹下所有doc文件的绝对绝对路径拼接出来,以便实现对每一个文件的操作。对于单个文件的处理则不需要这样来做,只需要将文件的决定路径确定下来即可。

      3、在确定了文件的路径之后便开始进行对word的操作,在进行测试过程中发现这里存在一个很大的坑,那就是word分节符的存在,分节符将整个word文档分成了若干部分,每个部分的页眉和页脚是独立的,在这个地方绕了我好几个小时。最终经过查资料发现section就是word的中每一个部分的对象,使用它便可以分别定位到每一个部分,解决了这个问题后剩下的逻辑便一气呵成。

      接下来直接上代码:

    import win32com,os,sys,re 

    from win32com.client import Dispatch, constants

    import os,time

    class Change_file_footer_header():
    '''批量更改word文件的页眉页脚'''

      def __init__( self ):

        self.file_or_files = input('请选择需要修改文件或者文件夹 only 代表只修改一个文件 many 代表修改文件夹下的所有文件 :')
        self.method = input( '请选择需要更改的类型 1 代表页眉,2代表页脚:')
        self.path = input( '请输入需要更改文件的目录名称:')
        self.old_name = input( '请输入需要更替换的名称:')
        self.new_name = input( '请输入替换的名称:')

      def change_header( self ,path ,file ):
        ''' 更改文件的页眉 '''

        w = win32com.client.Dispatch('Word.Application')
        w.Visible = 0
        w.DisplayAlerts = 0

        doc = w.Documents.Open( path )
        a = w.ActiveDocument.Sections
        n = 0
        for i in range( len(a) ):

          name = w.ActiveDocument.Sections[i].Headers[0]
          old_name = str(name)
          print( old_name )

          if self.old_name in old_name:
            new_name = old_name.replace( self.old_name,self.new_name )
            print( new_name )
            w.ActiveDocument.Sections[i].Headers[0].Range.Find.ClearFormatting()
            w.ActiveDocument.Sections[i].Headers[0].Range.Find.Replacement.ClearFormatting()
            w.ActiveDocument.Sections[i].Headers[0].Range.Find.Execute( self.old_name, False, False, False, False, False, False, 1, False, self.new_name, 2 )
          n = n+1
        doc.Close()
        create_time = time.strftime('%Y/%m/%d:%H/%M/%S', time.localtime(time.time()))
        text = '{} : {}文件====总共替换了{}个页眉'.format(create_time, file, n)
        self.log(text)

      def change_footer( self ,path ,file ):
      ''' 更改文件的页脚 '''

        w = win32com.client.Dispatch('Word.Application')
        w.Visible = 0
        w.DisplayAlerts = 0

        doc = w.Documents.Open( path )
        a = w.ActiveDocument.Sections
        n = 0
        for i in range( len(a) ):

          name = w.ActiveDocument.Sections[i].Footers[0]
          old_name = str(name)
          print( old_name )

          if  self.old_name in old_name:
            new_name = old_name.replace( self.old_name,self.new_name )
            print( new_name )
            w.ActiveDocument.Sections[i].Footers[0].Range.Find.ClearFormatting()
            w.ActiveDocument.Sections[i].Footers[0].Range.Find.Replacement.ClearFormatting()
            w.ActiveDocument.Sections[i].Footers[0].Range.Find.Execute( self.old_name, False, False, False, False, False, False, 1, False, self.new_name, 2)
            n = n+1
        doc.Close()
        create_time = time.strftime('%Y/%m/%d:%H/%M/%S',time.localtime(time.time()))
        text = '{} : {}文件====总共替换了{}个页脚'.format( create_time,file, n)
        self.log(text)

      def change_file_header( self ):
        ''' 循环遍历所输入的文件夹 '''

        for root, dirs, files in os.walk( self.path ):

        for i in files:
          if i.split('.')[1] == 'docx' or i.split('.')[1] == 'doc':
          print( '更改文件的名称',i )
          file_path = os.path.join( root,i )
          self.change_header( file_path ,i )
          #time.sleep( 1 )

      def change_file_footer( self ):
      ''' 循环遍历所需要修改页脚的文件夹 '''

        for root, dirs, files in os.walk( self.path ):

          for i in files:
            if i.split('.')[1] == 'docx' or i.split('.')[1] == 'doc':
              print( '更改文件的名称',i )
                 file_path = os.path.join( root,i )
                   self.change_footer( file_path ,i )

      def log(self,text):
        '''输出日志模块'''
        file_name = './' + time.strftime('%Y%m%d%H',time.localtime(time.time())) + '.' + 'txt'
        with open( file_name,"a+" ) as f:
          f.write( text )
          f.write( '\n' )

      def run( self ):

         if self.file_or_files == 'only':
          file_name = self.path.split( '\\' )[ -1 ]
          if self.method == '1':
            self.change_header( self.path ,file_name )
          elif self.method == '2':
            self.change_footer( self.path,file_name )

        elif self.file_or_files == 'many':
          if self.method == '1':
            self.change_file_header()
          elif self.method == '2':
            self.change_file_footer()

        else:
          print( '请输入正确的选择 only或者 many' )

    if __name__ == '__main__':
      Change_file_name = Change_file_footer_header()
      Change_file_name.run()

关键字