【PowerShell】 Word 문서의 문자를 유니 코드 정규화

10941 단어 PowerShell

소개



Word 파일에 대해 유니코드 정규화를 수행하는 스크립트 샘플.
  • Windows 10
  • PowerShell v5.1
  • Word 버전은 Office 365

  • 무엇이 있었는지



    있을 때, 계약서의 종류의 문서에는 갱신이 있고, 차이를 체크할 필요가 나왔다.
    제공된 형식은 pdf 이었기 때문에, Word로 변환해, 탭 「교열」→「비교」로부터 비교를 실시했다.

    그러자 확실히 똑같은 문자인데, 변경이 있다고 표시되어 있는 글자가 흔들렸다.

    사쿠라 에디터에 해당 부분을 복사해 보면 문자 코드가 다른 것을 알 수 있었다. 이쪽이라면 외형이 다르기 때문에 알기 쉽다.

    원인으로서는, MacOS로 문서를 작성했을 경우, 사용하는 어플리케이션에 의해 UTF-8에서도 사용하는 코드가 다른 것이 있다고 하는 것이 생각되는 것 같다.
    대응 방법으로서는, 문서 작성원에 문의하는 것이 제일이지만, 모처럼이므로(?) 코드로 어떻게든 해 보았다.

    샘플



    파라미터로 지정된 docx 파일을 정규화한다.
    docx 파일은 Zip 형식이므로 압축을 풀고 내부 word\document.xml 파일을 정규화하고 덮어 씁니다.
    그런 다음 다시 압축하여 새 docx 파일을 만듭니다.
    
    Param($filePathDocx)
    
    Add-Type -AssemblyName System.IO.Compression.FileSystem
    
    # パラメータで指定されたファイルを正規化
    
    # 拡張子チェック
    if ($filePathDocx -eq $null -or -not $filePathDocx.EndsWith(".docx")) {
        Write-Host "[エラー] docxファイルではありません"
        return
    }
    
    # 正規化後ファイルパス
    $filePathDocxOut = $filePathDocx.Replace(".docx", "_正規化.docx")
    
    if (Test-Path $filePathDocxOut) {
        Remove-Item $filePathDocxOut
    }
    
    # docx解凍
    $extractDir = [System.IO.Path]::GetTempPath() + "\word_extract_" + (Get-Date -Format yyyyMMddHHmmss)
    
    [System.IO.Compression.ZipFile]::ExtractToDirectory($filePathDocx, $extractDir)
    
    # document.xmlの正規化
    $docFilePath = "${extractDir}\word\document.xml"
    $tmpFilePath = [System.IO.Path]::GetTempFileName()
    
    [System.IO.File]::Copy($docFilePath, $tmpFilePath, $true)
    
    $reader = $null
    try {
        $reader = New-Object System.IO.StreamReader($tmpFilePath)
    
        $writer = $null
        try {
            $writer = New-Object System.IO.StreamWriter($docFilePath, $false, [System.Text.Encoding]::UTF8)
            $line = $reader.ReadLine()
    
            while ($line -ne $null) {
                $line = $line.Normalize([System.Text.NormalizationForm]::FormKC)
                $writer.WriteLine($line)
    
                $line = $reader.ReadLine()
            }
    
        } finally {
            if ($writer -ne $null) {
                $writer.Close()
            }        
        }
    
    } finally {
        if ($reader -ne $null) {
            $reader.Close()
        }
    }
    
    # 圧縮
    [System.IO.Compression.ZipFile]::CreateFromDirectory($extractDir, $filePathDocxOut)
    
    # 後片付け
    [System.IO.Directory]::Delete($extractDir, $true)
    [System.IO.File]::Delete($tmpFilePath )
    
    Write-Host "done"
    

    좋은 웹페이지 즐겨찾기