自動化處理大量 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 的寫法。