まず、bouncycastle.org - latest releases から暗号化に必要な bcprov-jdk15-137.jar をダウンロードしてクラスパスに含める。
サンプルソースコード(PdfMoreInfoSample.java)
PDFのプロパティ指定と暗号化のサンプル。
import java.io.*;
import java.util.*;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;
public class PdfMoreInfoSample {
public static void main(String[] args) {
try {
// 適当にPDFデータを作る
byte[] pdfdata = createPdfData("hello");
// PDFデータのプロパティを表示
HashMap moreinfo = getMoreInfo(pdfdata);
for (Iterator it = moreinfo.keySet().iterator(); it.hasNext();) {
Object key = it.next();
Object val = moreinfo.get(key);
System.out.println(key + "=" + val);
// 以下のようなデータが出力される
// ModDate=D:20070401010203+09'00'
// Producer=iText 2.0.4 (by lowagie.com)
// CreationDate=D:20070401010203+09'00'
}
// PDFのプロパティ情報を構築
// 値には文字列しか入れられない(ClassCastExceptionが発生したり)
HashMap addedMoreInfo = new HashMap();
// 文書のタイトル
addedMoreInfo.put(new String("Title"), "the Title");
// 著者
addedMoreInfo.put("Author", "the Author");
// PDF文書の主題
addedMoreInfo.put("Subject", "the Subject");
// キーワード
addedMoreInfo.put("Keywords", "the Keywords");
// リソースを作成したツール名称
addedMoreInfo.put("Creator", "the Creator");
// PDF文書を作成したツール名称(iTextのドキュメントには変更しないことが推奨されていた)
// PdfDocument クラスのソースコード(version 2.0.4)には
// "you can not change the name of the producer" とあるが……
addedMoreInfo.put("Producer", "the Producer");
// PDF文書の作成日
// PdfDocument クラスのソースコード(version 2.0.4)には
// "you can not set the creation date, only reset it" とあるが……
addedMoreInfo.put("CreationDate", "2011/11/11 11:11:11");
// PdfDate クラスを使う必要はない(むしろイマイチよくない)
// Calendar cdcal = Calendar.getInstance();
// cdcal.set(2011, Calendar.APRIL, 5, 6, 7, 8);
// PdfDate cd = new PdfDate(cdcal);
// addedMoreInfo.put("CreationDate", cd.getW3CDate());
// 実は、日時以外も設定可能
// addedMoreInfo.put("CreationDate", "abcde");
// PDF文書の最終修正日
addedMoreInfo.put("ModDate", "2012/12/12 12:12:12");
// PDFデータにプロパティとPDFのバージョンを設定
pdfdata = setMoreInfo(pdfdata, addedMoreInfo, PdfWriter.VERSION_1_2);
// パスワード制限は最後に設定すること
// setMoreInfo で制限が解除されてしまう
pdfdata = setEncryption(pdfdata, "hogehoge");
// PDFをファイルへ出力
out(pdfdata, "20070802_moreinfo.pdf");
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] createPdfData(String text) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, baos);
document.open();
Paragraph p = new Paragraph(text);
document.add(p);
writer.close();
document.close();
byte[] pdf = baos.toByteArray();
return pdf;
}
static HashMap getMoreInfo(byte[] pdfdata) throws Exception {
PdfReader reader = new PdfReader(pdfdata);
HashMap baseInfo = reader.getInfo();
reader.close();
return baseInfo;
}
// PDF文書プロパティ指定
static byte[] setMoreInfo(byte[] pdfdata, HashMap info, char version) throws Exception {
PdfReader reader = new PdfReader(pdfdata);
HashMap baseInfo = reader.getInfo();
baseInfo.putAll(info);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// PdfStamper には setThumbnail とか setTransition とかおもしろそうなメソッドが用意されている
PdfStamper pdfStamper = new PdfStamper(reader, baos, version);
pdfStamper.setMoreInfo(baseInfo);
pdfStamper.close();
reader.close();
return baos.toByteArray();
}
// 暗号化
static byte[] setEncryption(byte[] pdfdata, String password)
throws Exception {
PdfReader reader = new PdfReader(pdfdata);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper pdfStamper = new PdfStamper(reader, baos);
// 印刷だけ許可&パスワード設定
pdfStamper.setEncryption(true, null, password, PdfWriter.AllowPrinting);
pdfStamper.close();
reader.close();
return baos.toByteArray();
}
private static void out(byte[] pdfdata, String file) throws Exception {
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
os.write(pdfdata);
os.flush();
}
}
出力したPDFファイル → 20070802_moreinfo.pdf
このPDFファイルを Adobe Reader で開いて、メニューから [ファイル] -> [プロパティ] -> [セキュリティ]タブにて、「印刷」だけ許可されるようになっているのが確認できる。
また、[ファイル] -> [プロパティ] -> [概要]タブにて、プロパティ情報がソースコードで指定されているものになっているのが確認できる。
PDFファイルの情報(プロパティ)
「文書のプロパティ(Document Properties)」の項目についてメモ。
この情報は Adobe Reader ならば [ファイル] -> [文書のプロパティ] からみることできる。
日本語版用語(英語版用語) : 値のサンプル日本語版 : 値のサンプル英語版
という感じで項目を羅列してみた。
英語版での表記は Google で画像検索してみつけたものを転記。
概要(Description)
------------------------------------------------------------------------------
ファイル(File) : test.pdf
タイトル(Title) : The test
作成者(Author) : Test Man
サブタイトル(Subject): for test
キーワード(Keywords): test, pdf, acrobat
作成日時(Created): 2007/04/01 01:02:03 : 4/01/2007 01:02:03 AM
更新日時(Modified) : 2007/04/01 01:02:03 : 4/01/2007 01:02:03 AM
アプリケーション(Application): Adobe Page Maker 7.0
------------------------------------------------------------------------------
詳細情報(Advanced)
------------------------------------------------------------------------------
PDF変換(PDF Producer): iText 1.4 (by lowagie.com)
PDFのバージョン(PDF Version): 1.4 (Acrobat 5.x)
場所(Location): C:\test\
ファイルサイズ(File Size): 2.32MB (2,430,581バイト) : 513.88 KB (526,212 Bytes)
用紙サイズ(Page Size) : 297 x 210 mm : 8.50 x 11.00 in
タグ付きPDF(Tagged PDF) : いいえ : No
ページ数(Number of Pages) : 1 : 2
Web表示用に最適化: いいえ : Yes
------------------------------------------------------------------------------
Ref. セマンティック・ウェブのコンシェルジュ - XMP(Extensible Metadata Platform) -Adobeが提唱する文書情報規格
tags: zlashdot Java Java PDF iText
Posted by NI-Lab. (@nilab)