2012年11月26日月曜日

iText で PDF ファイルの情報 (プロパティ) の指定と暗号化

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();
}

}

0 件のコメント:

コメントを投稿