【Excel VBA】シートをパスワード保護付きのPDFで出力する

社内で新しいWebサービスを導入することになりまして、全社員分のアカウントが作成されるのですが、各アカウントごとに初回ログイン用URLにアクセスしてパスワードを設定する必要があります。

初回ログイン用URLは社員ごとにURLがあり、ハッシュ値のようなランダムの文字列が含まれているので口頭で伝えることは不可能で、文書で伝えても入力するには骨が折れます。

アカウントにメールアドレスが登録されていればメールで初回ログイン用URLを送って、社員はリンクをクリックするだけでアクセスできるのですが、全社員がメールアドレスが持っているわけではなく、その場合の初回ログイン用URLの伝達方法を考えなければなりません。

管理者側で各社員ごとの初回ログイン用URLにアクセスしてパスワードを設定し、そのパスワードを伝達するという方法もありますが、社員が1000人近くいるのでその作業をするのも現実的ではありません。

そこで共有ストレージ上に初回ログイン用URLのリンクが記載されたPDFファイルを社員ごとに作成し、それぞれのPDFファイルを各社員がタイムカード打刻に使用しているパスワードで保護すれば手間なく且つ安全に伝えることができると考えました。

今回はExcel VBAを使ってシートをパスワード保護したPDFとして出力する方法を調べて作成した備忘録です。

スポンサーリンク

Excelでパスワード付きPDFにするにはPDFtkが必要

ってなことが会議で議題にあがって解決策を提示したのですが、あとから調べるとExcelでは標準でPDFにパスワードを付けることができないそう。

いっそExcelの暗号化で済まそうかとも考えましたが、どうやらサードパーティのアプリを使えばなんとかなるそうな。

今回はPDFtkというアプリを使います。参考にしたのは下記リンク。

Excelとパスワード付きPDF | すごい改善
こんにちは、すごい改善のAitoです。 さてさて、本日の話題はPDFとパスワードについてです。そ

PDFtkをインストール

インストール版とポータブル版があるのですが、今回は参考サイトにならってポータブル版を使います。

下記リンクにアクセスしてダウンロードします。

PDFTK Builder Enhanced Portable | PortableApps.com
PDFTK Builder is a pdf manipulation utility for Windows with a great array of features including: Collate - allows you t...

ダウンロードリンクがあるのでクリックします。

インストーラーを起動して、あとは肯定的に進めていけばPDFtkのファイル一式が展開されます。

展開したフォルダ内の\App\pdftkbuilder\pdftk.exeをExcel VBAの中で使用します。

フォルダとExcelの準備

フォルダを作成し、その中に下記を準備します。

  • 展開したPDFtkのフォルダ
  • Excelマクロ実行ブック (ここでは「export-password-pdf.xlsm」としています)
  • フォルダ「PDF出力先」
  • フォルダ「PW付PDF出力先」

Excelには、まずシート「リスト」に社員の一覧を作成します。1列目から、

  1. No (社員番号)
  2. 氏名
  3. 生年月日 (今回はこれをパスワードの代わりにします)
  4. 初回ログイン用URL

の順にしています。PDFに載せたい項目を任意で用意します。

もちろんこれはサンプルファイルでして、個人情報テストデータ生成ツールで作成しました。

パスワードについては今回はサンプルで用意するのが面倒だったので、個人情報テストデータ生成ツールで作成できる生年月日をそのまま使うことにしましたが、生年月日は秘密情報ではないので本来はこういった場面でパスワードに使うべきではありません。

実際にはここにタイムカード打刻用パスワードを入力して、社員が各自自身のPDFだけを見られるようにしています。

シート「出力シート」はPDF出力するためのフォーマットを用意します。

何も入力されていませんが、セルA1に「番号: nnnn 氏名 様」、セルA5に初回ログインURLのリンクが入力された状態でPDF出力されます。

出力結果

VBAのコードよりも先に出力結果をば。

「PW付PDF出力先」のフォルダ内に、「nnnn(番号)_氏名.pdf」のPDFが作成されました。

これを共有ストレージに入れて、各社員が自身のPDFを探して開きます。

開くとパスワード入力画面が出ますので、自身のパスワード (今回のサンプルでいえば生年月日) を入力します。

開くと初回ログインURLのリンクが表示されるので、クリックしてアクセスします。

VBA

Sub PW付PDF出力()
    Dim userListArray As Variant
    Dim userNumber As String
    Dim userName As String
    Dim loginUrl As String
    Dim password As String
    
    Dim EXPORT_PATH As String: EXPORT_PATH = ThisWorkbook.Path & "\PDF出力先"
    Dim pdfPath As String
    Dim SECURE_EXPORT_PATH As String: SECURE_EXPORT_PATH = ThisWorkbook.Path & "\PW付PDF出力先"
    Dim securePdfPath As String
    
    Dim pdftkPath As String: pdftkPath = """C:\Users\hoge\PDFTKBuilderPortable\App\pdftkbuilder\pdftk.exe"""   'pdftk.exeの絶対パスを指定
    Dim inputFile As String
    Dim outputFile As String
    
    Dim objWSH As Object, objwExec As Object, Result As String
    Dim cmd As String
    
    With Worksheets("リスト")
        userListArray = .Range(.Cells(2, 1), .Cells(.Cells(Rows.Count, 1).End(xlUp).Row, .Cells(1, Columns.Count).End(xlToLeft).Column)).Value
    End With
    
    For i = 1 To UBound(userListArray, 1)
        With Worksheets("出力シート")
            .Cells(1, 1).ClearContents
            .Cells(5, 1).Clear
            
            userNumber = userListArray(i, 1)
            userName = userListArray(i, 2)
            password = userListArray(i, 3)
            loginUrl = userListArray(i, 4)
            
            .Cells(1, 1).Value = "番号: " & userNumber & " " & userName & " 様"
            .Cells(5, 1).Hyperlinks.Add anchor:=.Cells(5, 1), Address:=loginUrl, TextToDisplay:=loginUrl
            
            pdfPath = EXPORT_PATH & "\" & userNumber & "_" & userName
            
            .ExportAsFixedFormat Type:=xlTypePDF, _
                Filename:=pdfPath, _
                Quality:=xlQualityStandard, _
                IncludeDocProperties:=True, _
                IgnorePrintAreas:=False, _
                OpenAfterPublish:=False
            
            'PDFtkでパスワード保護
            Set objWSH = CreateObject("WScript.Shell")
            
            inputFile = Chr(34) + pdfPath + ".pdf" + Chr(34)
            outputFile = Chr(34) + SECURE_EXPORT_PATH + "\" & userNumber & "_" & userName & ".pdf" + Chr(34)
            
            cmd = "%ComSpec% /c " + Chr(34) + pdftkPath + " " + inputFile + " output " + outputFile + " user_pw " + password + Chr(34)
            
            Set objwExec = objWSH.Exec(cmd)
                
            Do While objwExec.Status = 0
                DoEvents
            Loop
            
        End With
    Next i
    
End Sub

流れとしては、2次元配列に格納した社員リストを走査して、出力用シートに入力したものを一旦普通のPDFファイルに出力、そのPDFファイルに対してシェルで呼び出したPDFtkを使ってパスワードをつけて再出力します。つまりパスワードが付いているPDFとそうでないPDFの2種類ができあがります。

13行目はpdftk.exeの場所を絶対パスで指定しています。これはシェルで呼び出す時に使用します。

今回はマクロ実行ブックと同じフォルダ内にポータブル版を入れたので、ThisWorkbook.Pathを使って記述を簡略化できそうではありましたが、なぜかうまくいかなかったのでこの書き方です。おそらくダブルクォートの付き方が変だっただけだと思うのでちゃんとやればできそうですが、面倒くさくなって追求しませんでした。

コメント

コメントする前にお読みください

迷惑コメント防止のために初回のコメント投稿は承認制のため、投稿が反映されるまで少し時間がかかります。もちろん荒らしは承認しません。

教えて君やクレクレ君に対しては回答しませんのでご了承ください。