python 使用win32com實現對word文檔批量替換頁眉頁腳


       最近由於工作需要,需要將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()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM