去年分享過將 XLS 批次轉成 XLSX 的 PowerShell 小工具,有讀者問到如果是 DOC 轉 DOCX 要怎麼做?

PowerShell 小工具原理是啟動 Windows 上安裝的 Excel 軟體,控制它逐一讀檔,另存新檔,最後再關閉。若想處理 Word 就把 Excel 改成 Word,讀檔、存檔改用 Word 的 API 就可以。有 PowerShell、C# 或 VB 開發經驗,也會查微軟文件的程式老手,用膝蓋都能完成,但對沒相關經驗的人,渴望成功卻不知從何下手,或是一改就壞但無法理解錯在哪裡的無力感,我倒挺能體會。原因是這一兩年跨足自己不熟的 Arduino/ESP 開發板跟 C 語言,重新從菜鳥當起,有類似的體驗。

當然,練好基本功,按步就班是學習所有技能的正途,越級打怪之人也自知理虧,身為老鳥狂酸「先去唸好 XXX 吧 」、「YYY 網路教學很多,請自己爬文,乖」、「ZZZ 是基本常識耶」則是過頭了。對於沒相關經驗卻有動力想完成某些東西,態度也良好的朋友,我通常站在鼓勵的立場(自己走過類似的路,算同理心吧),目標過於崇高,或與能力落差過大,旁人愛莫能助;但若只是舉手之勞,我也想不出不幫的道理。

扯遠了。既然 DOC 轉 DOCX 也在某些人的許願清單上,將上次的程式小改幾行,DOC 轉 DOCX 批次轉換小工具就完成了! 希望它能讓地球某個角落的文件苦手早點下班。

Param(
    [parameter(Mandatory=$true, ValueFromRemainingArguments=$true)]
    [string]
    $docPaths, 
    [parameter(ValueFromPipelineByPropertyName=$true)]
    [switch][bool]
    $replace
)
$ErrorActionPreference = "STOP"
try 
{
    $doc = New-Object -ComObject Word.Application
    $doc.Visible = $true # 顯示 UI,方便使用者了解處理進度、輸入密碼等
    Get-Item $docPaths | ForEach-Object {
        $path = $_.FullName
        Write-Host "開啟 $path..."
        try {
            $doc.Documents.Open($path) | Out-Null
            $savePath =  $savePath = [System.IO.Path]::ChangeExtension($path, ".docx")
            # https://docs.microsoft.com/en-us/office/vba/api/word.wdsaveformat
            # WdSaveFormat.wdFormatXMLDocument = 12
            $doc.ActiveDocument.SaveAs2($savePath, 12)
            $doc.ActiveDocument.Close()
            if ($replace) {
                Remove-Item $path                
            }
        }
        catch {
            Write-Host "發生錯誤 - $path" -ForegroundColor Red
        }
    }
}
finally 
{
    $doc.Quit()
}

實測成功。

[2022-02-12 更新]

貼文後再聽到有人許願,那可以轉 PDF 嗎?很簡單,SaveAs2 的參數由 12 改成 17 就可以了,如何知道是 17?可查微軟文件,裡面有不同格式的對映值。

我知道要求沒寫程式的朋友馬上搞懂這些也太難了,既然對我還是舉手之勞,就隨手附上 Convert-Doc2Pdf.ps1:(來源檔不限 doc,也可以是 docx )

Param(
    [parameter(Mandatory=$true, ValueFromRemainingArguments=$true)]
    [string]
    $docPaths, 
    [parameter(ValueFromPipelineByPropertyName=$true)]
    [switch][bool]
    $replace
)
$ErrorActionPreference = "STOP"
try 
{
    $doc = New-Object -ComObject Word.Application
    $doc.Visible = $true # 顯示 UI,方便使用者了解處理進度、輸入密碼等
    Get-Item $docPaths | ForEach-Object {
        $path = $_.FullName
        Write-Host "開啟 $path..."
        try {
            $doc.Documents.Open($path) | Out-Null
            $savePath = [System.IO.Path]::ChangeExtension($path, ".pdf")
            # https://docs.microsoft.com/en-us/office/vba/api/word.wdsaveformat
            # WdSaveFormat.wdFormatPDF = 17
            $doc.ActiveDocument.SaveAs2($savePath, 17)
            $doc.ActiveDocument.Close()
            if ($replace) {
                Remove-Item $path                
            }
        }
        catch {
            Write-Host "發生錯誤 - $path" -ForegroundColor Red
        }
    }
}
finally 
{
    $doc.Quit()
}

簡單實測 OK,有需要的朋友請自取使用,並鼓勵大家認真考慮花點時間學會 PowerShell,讓你的人生變彩色。

Example of converting .doc to .docx with PowerShell.


Comments

# by mouse

感謝您!!

# by Gary

無意中找到這個教學,太感謝!

# by Kii

不好意思 發現轉換過去的DOCX開啟一樣是相容模式 然後檔案大小也不是正常DOCX的大小 而是跟原本的DOC一樣 這有辦法改進嗎?

# by Jeffrey

to Kii, 建議做些對照測試:轉不同的 .doc、開一個空白 .doc 輸入一行、在不同的電腦上執行看看... 由結果差異來推敲原因。

Post a comment