自動化處理大量 Word 檔案之字數統計

大家都知道,Microsoft Word 有個字數統計的功能,而這個功能對眾多青年學子而言非常重要,因為在寫作業或者是報告的時候,字數統計可以讓學生判斷到底還需不需要繼續鬼扯下去……不過今天 DR 並不打算分享鬼扯的奧義,而是要談談最近 DR 所碰到的問題(之一),以及解決的過程。

 

這個問題簡而言之便是要統計很多個 Word 檔案(*.doc、*.docx)加起來的總字數,如果檔案很少是可以一個個開來看,但如果有很多個檔案,弄到死人事小,耗費精力延誤時程事大,於是 DR 就著手研究怎麼樣才可以一次性的把所有檔案的字數統計抓出來。一開始 DR 嘗試使用 Microsoft 官方所提供的 Dsofile.dll,這個元件可以在不需安裝 Microsoft Office 的情況下讀取、編輯 Office 檔案的屬性資料,所以就參考官方的範例,利用 Dsofile.dll 寫了一支 VB .NET 程式,以下程式碼非常直覺,懂 VB 的人都看得懂:


Module Module1
    Sub Main()
        Dim dirCurrent As String = System.IO.Directory.GetCurrentDirectory
        Dim fileList As String() = System.IO.Directory.GetFiles(dirCurrent)
        Dim fileName As String
        Dim shortName As String
        Dim extension As String
        Dim docFile As DSOFile.OleDocumentProperties = New DSOFile.OleDocumentProperties
        Dim result As String

        Console.WriteLine("Filename,Words,Characters")

        For Each fileName In fileList
            extension = System.IO.Path.GetExtension(fileName)
            shortName = System.IO.Path.GetFileName(fileName)

            If (extension = ".doc") Or (extension = ".docx") Then
                docFile.Open(fileName, False, DSOFile.dsoFileOpenOptions.dsoOptionDefault)
                result = String.Join(",", shortName, docFile.SummaryProperties.WordCount, docFile.SummaryProperties.CharacterCount)
                Console.WriteLine(result)
                docFile.Close()
            End If

        Next

        'Console.WriteLine("Press any key to exit.")
        'Console.ReadKey()
    End Sub

End Module
  

然而這支程式的執行結果有很大的問題,就是字數統計不精確,對於亞洲文字更是毫無辨識能力,這並不是程式碼的問題,而是 Dsofile.dll 本身的問題,一時之間,DR 也沒有想到其它的解決方式。後來 DR 在寫別的程式時,從 O'Reilly 的 Python Cookbook 一書中查到使用 Python 藉由 COM 去呼叫 Word 的方法,於是 DR 轉而研究這個方法,又寫了一支 Python 程式,程式碼同樣也是非常直覺,懂 Python 的人都看得懂:

import os, sys
import win32com.client
 
#Set 1 to enable debug mode:
DEBUG = 0
 
appdir = os.path.abspath(os.path.dirname(sys.argv[0]))
os.chdir(appdir)
 
file_input = "doc"
wordapp = win32com.client.gencache.EnsureDispatch("Word.Application")
wordapp.Visible = False
 
print "Filename,Words,Characters,Pages"
 
for fn in os.listdir(file_input):
    if fn.endswith(".doc") or fn.endswith(".docx"):
       docfile = os.path.abspath(os.path.join(appdir,file_input,fn))
       wordapp.Documents.Open(docfile)
       words = wordapp.ActiveDocument.ComputeStatistics(0)
       chars = wordapp.ActiveDocument.ComputeStatistics(3)
       pages = wordapp.ActiveDocument.ComputeStatistics(2)
       wordapp.ActiveDocument.Close()
       wordapp.Quit()
       line = fn + "," + str(words) + "," + str(chars) + "," + str(pages)
       print line
 
if DEBUG == 1:
   print "\nPress 'Enter' to exit."
   raw_input()
   

這支程式就很合用,可以輸出跟直接用 Word 開出來完全一致的字數統計(因為其實是呼叫 Word 來處理),接著把輸出結果倒進試算表就可以很輕鬆的算出總字數。COM 的方法可以用在很多種程式語言上,包含 VB .NET,不過既然已經用 Python 寫出來了,DR 就沒有回頭去研究 VB .NET 的寫法。

 

分類: