C#でiText7を使う
C#でiText7
を使ってPDFファイルのパスワード設定と解除をやってみました。
巷ではiTextSharp
の情報は見かけるのですが、JavaではなくC#のiText7
の記事が少ないと思い書いてみました。
iText7
はiTextSharp
の後継版で、.NET6と組み合わせればMacでも使えます。
と言うことで、今回の動作確認は以下の環境で行いました。
- macOS Ventura 13.2
- .NET6
- Visual Studio for Mac 17.6 Preview
- iText7 7.2.5
iText7
は「NuGetパッケージの管理」でインストールしておきます。
パスワードを設定する
まずは、パスワードがかかっていないPDFファイルを用意します。そして、それをホームディレクトリに置きます。以下、Macで試したのでファイルパスはMac用ですが、Windowsでもファイルパスを適切に書き換えれば問題なく動作します。
設定するパスワードは、文字列からバイト配列に変換する必要があります。
using iText.Kernel.Pdf;
public void ProtectPdf()
{
// 以下は各自のホームディレクトリのパスに変えてください
string targetPdfPath = "/Users/mackohei/hoge.pdf";
// 以下で作業用一時ファイルのパスを生成
string tmpPdfPath = GenerateRandomPath(targetPdfPath);
using (FileStream stream = new(tmpPdfPath, FileMode.Create, FileAccess.Write, FileShare.None))
using (PdfReader pdfReader = new(targetPdfPath))
using (PdfWriter pdfWriter = new(stream, new WriterProperties()
// 以下でパスワードとパーミッションの設定をする
// パスワードは文字列からバイト配列に変換する
.SetStandardEncryption(Encoding.Default.GetBytes("password"), Encoding.Default.GetBytes("password"),
EncryptionConstants.ALLOW_PRINTING | EncryptionConstants.ALLOW_COPY,
EncryptionConstants.STANDARD_ENCRYPTION_128)))
{
// 以下でパスワード付きPDFファイルを生成
var pdfDoc = new PdfDocument(pdfReader, pdfWriter);
pdfDoc.Close();
}
// 元ファイルを一時ファイルに置き換える
File.Delete(targetPdfPath);
File.Move(tmpPdfPath, targetPdfPath);
}
パスワード設定した作業用の一時ファイルを作成し、それを元ファイルと置き換えます。
一時ファイルの完成はPdfDocument
生成時に行われます。元ファイルの内容を読み込んだPdfReader
の内容を一時ファイルのPdfWriter
に書き込む感じです。
一時ファイルのパスは以下の関数で作成しました。(これは一時ファイルのファイル名の重複を避けるためのもので、今回の記事のテーマとは直接関係ありません)
public static string GenerateRandomPath(string originalPath)
{
string dirName = Path.GetDirectoryName(originalPath) ?? "/";
string extension = Path.GetExtension(originalPath);
string randomPath;
Random random = new();
do
{
randomPath = random.NextInt64(1, 9999999999).ToString("D10");
randomPath = dirName + "/" + randomPath + extension;
}
while (File.Exists(randomPath));
return randomPath;
}
以下にSetStandardEncryption
メソッドのリファレンスを貼っておきます。
パスワードを解除する
パスワード解除も、基本的にパスワード設定と同様の流れです。
ポイントは、PdfReader
生成時にパスワード解除が必要なところです。バイト配列に変換したパスワードを渡すことでエラー無く読み込めます。
public void UnprotectPdf()
{
// 以下は各自のホームディレクトリのパスに変えてください
string targetPdfPath = "/Users/mackohei/hoge.pdf";
// 以下で作業用一時ファイルのパスを生成
string tmpPdfPath = GenerateRandomPath(targetPdfPath);
// 以下で文字列のパスワードをバイト配列にエンコード
byte[] bytePassword = System.Text.Encoding.Default.GetBytes("password");
using (FileStream stream = new(tmpPdfPath, FileMode.Create, FileAccess.Write, FileShare.None))
// 以下で読み込み用PDFリーダーにバイト配列を渡す
using (PdfReader pdfReader = new(targetPdfPath, new ReaderProperties().SetPassword(bytePassword)))
using (PdfWriter pdfWriter = new(stream))
{
// 以下でパスワードを除いたPDFファイルを生成
PdfDocument pdfDoc = new(pdfReader, pdfWriter);
pdfDoc.Close();
}
// 元ファイルを一時ファイルに置き換える
File.Delete(targetPdfPath);
File.Move(tmpPdfPath, targetPdfPath);
}
当然ですが、パスワードが対象のPDFファイルに設定されているものと一致しなければエラーとなります。
チュートリアルやリファレンスなど
以上、iText7
は色々と簡単にPDF加工ができて便利なライブラリだと思います
皆さんも機会があったら、以下などを参考に試してみてください