「PDFBox 1.0」の版間の差分
細 (Gonbe がページ「PDFBox」を「PDFBox 1.0」に移動しました) |
|||
| (同じ利用者による、間の19版が非表示) | |||
| 1行目: | 1行目: | ||
[[Category:Software]] | [[Category:Software]] | ||
| − | + | [http://www.apache.org/ Apache Foundation]のPDF生成ライブラリ。<br> | |
| + | このページは1.8.3準拠で記述しています。<br> | ||
ライセンス | ライセンス | ||
:APL | :APL | ||
本家サイト | 本家サイト | ||
:http://pdfbox.apache.org/ | :http://pdfbox.apache.org/ | ||
| + | |||
| + | = Mavenでの導入 = | ||
| + | 本家にもあるけど、今回はdependencyに以下を記述。 | ||
| + | <pre> | ||
| + | <dependency> | ||
| + | <groupId>org.apache.pdfbox</groupId> | ||
| + | <artifactId>pdfbox</artifactId> | ||
| + | <version>1.8.3</version> | ||
| + | </dependency> | ||
| + | </pre> | ||
| + | = 使い方 = | ||
| + | == PDFページを追加する。 == | ||
| + | 以下のコードで空白のページを追加することができる。<br> | ||
| + | PDRectangleでページサイズを指定できるが、単位がポイントなのに注意(1ポイント=0.353mm) | ||
| + | <pre> | ||
| + | PDDocument doc = new PDDocument(); | ||
| + | PDRectangle rec = new PDRectangle(幅,高さ); | ||
| + | doc.addPage(new Page(rec)); | ||
| + | doc.save("出力先.pdf"); | ||
| + | doc.close(); | ||
| + | </pre> | ||
| + | === 紙のサイズとおおよそのポイント === | ||
| + | {| class="wikitable" style="width: 20em;" | ||
| + | |+ 紙サイズ変換表 | ||
| + | ! サイズ || mm表記 || ポイント表記 | ||
| + | |- | ||
| + | || A3 || 297×427 || 842×1191 | ||
| + | |- | ||
| + | || A4 || 210×297 || 595×842 | ||
| + | |- | ||
| + | || A5 || 148×210 || 420×595 | ||
| + | |- | ||
| + | || B4 || 250×353 || 729×1032 | ||
| + | |- | ||
| + | || B5 || 176×250 || 516×729 | ||
| + | |- | ||
| + | || B6 || 125×176 || 363×516 | ||
| + | |} | ||
| + | |||
| + | == 文字列/図形の描画 == | ||
| + | PDFの文字列や図形はstreamで行う。streamはさまざまなオペレータの集合になっている。イメージ的にはdrawマクロみたいなもの。<br> | ||
| + | streamはページに対し、以下のコードで生成する。 | ||
| + | <pre> | ||
| + | PDPageContentStream stream = new PDPageContentStream(PDDocument, PDPage) | ||
| + | </pre> | ||
| + | 図形や文字列のPDFのオペレータに対応するメソッドがある。<br> | ||
| + | streamは必ずcloseすること。closeしないと描画が行われない。 | ||
| + | === 文字列の出力 === | ||
| + | PDFでの文字列の出力は以下の手順で行う。 | ||
| + | <pre> | ||
| + | PDPageContentStream stream = new PDPageContentStream(PDDocument, PDPage); | ||
| + | stream.beginText() //文字列出力の開始を通知 | ||
| + | stream.setFont(PDFont,フォントサイズ); //フォントとサイズの指定。マルチバイト文字を出力する場合、対応するフォントの指定が必須。 | ||
| + | stream.moveTextPositionByAmount(横位置, 縦位置); //文字列を出力する位置の指定。 | ||
| + | stream.drawString(文字列); //文字列の出力 | ||
| + | stream.endText(); //文字列出力の終了を通知 | ||
| + | </pre> | ||
| + | |||
| + | ==== フォントの指定 ==== | ||
| + | ASCII文字のみであれば組み込みのtype1フォントで用が足りるが、マルチバイト文字を出力することができない。<br> | ||
| + | マルチバイト文字を出力するにはCIDフォントを設定する必要がある。 | ||
| + | <pre> | ||
| + | //日本語文字列であることをしめすPDF辞書を定義 | ||
| + | COSDictionary systeminfo = new COSDictionary(); | ||
| + | systeminfo.setString(COSName.REGISTRY, "Adobe"); | ||
| + | systeminfo.setString(COSName.ORDERING, "Japan1"); | ||
| + | systeminfo.setInt(COSName.SUPPLEMENT, 6); | ||
| + | |||
| + | //フォントの書体を設定 | ||
| + | PDFontDescriptorDictionary fd = new PDFontDescriptorDictionary(); | ||
| + | fd.setFontName("MSゴシック"); //使用するフォント名を指定。フォントの埋め込みはできるのだろうか? | ||
| + | fd.setFlags(4); | ||
| + | fd.setFontBoundingBox(new PDRectangle(new BoundingBox(-500, -300, 1200, 1400))); | ||
| + | fd.setItalicAngle(0); | ||
| + | fd.setAscent(1400); | ||
| + | fd.setDescent(-300); | ||
| + | fd.setCapHeight(700); | ||
| + | fd.setStemV(100); | ||
| + | |||
| + | //日本語CIDフォントを設定する | ||
| + | COSDictionary cid = new COSDictionary(); | ||
| + | cid.setItem(COSName.TYPE, COSName.FONT); | ||
| + | cid.setItem(COSName.SUBTYPE, COSName.CID_FONT_TYPE0); | ||
| + | cid.setItem(COSName.BASE_FONT, COSName.getPDFName("KozGoPr6N-Medium")); //ベースとなるフォント名を指定 | ||
| + | cid.setItem(COSName.CIDSYSTEMINFO, systeminfo); //日本語用のフォントであることを指定 | ||
| + | cid.setItem(COSName.FONT_DESC, fd); //フォントの書体を設定 | ||
| + | |||
| + | //フォント設定 | ||
| + | COSDictionary font = new COSDictionary(); | ||
| + | font.setItem(COSName.TYPE, COSName.FONT); | ||
| + | font.setItem(COSName.SUBTYPE, COSName.TYPE0); | ||
| + | font.setItem(COSName.BASE_FONT, COSName.getPDFName("KozGoPr6N-Medium")); | ||
| + | //文字コードはUCS2にしておく。 | ||
| + | //MS932にする場合、埋め込みで「COSName.ENCODING_90MS_RKSJ_H」という定数が用意されている。 | ||
| + | font.setItem(COSName.ENCODING, COSName.getPDFName("UniJIS-UCS2-H")); | ||
| + | COSArray array = new COSArray(); | ||
| + | array.add(cid); | ||
| + | font.setItem(COSName.DESCENDANT_FONTS, array); | ||
| + | |||
| + | //PDF用type0フォントの生成 | ||
| + | PDFont pdFont = new PDType0Font(font); | ||
| + | |||
| + | //ストリームにフォントと出力サイズをセット | ||
| + | stream.setFont(pdFont, 40); | ||
| + | stream.moveTextPositionByAmount(100, 100); //文字列の出力位置に移動 | ||
| + | //drawStringはStringで受けるのだが、latain1の文字しか受け付けない。 | ||
| + | //文字列をフォントで指定したエンコードのバイト列に変換し、無理やりISO8859-1に変換して出力する必要がある。 | ||
| + | stream.drawString(new String(str.getBytes(Charset.forName("ISO-10646-UCS-2")),"ISO8859-1")); | ||
| + | stream.endText(); | ||
| + | stream.close(); | ||
| + | </pre> | ||
| + | |||
| + | == 日本語フォントの埋め込み(pdfbox 2.0 以後だと普通にフォント埋め込みがサポートされている) == | ||
| + | とりあえず、TTFは読み込む手段をPDFBoxに設定されていたのでIPAexゴシックで試行錯誤中。 | ||
| + | === loadTTFでフォントを読み込む === | ||
| + | <pre> | ||
| + | PDFont pdFont = PDTrueTypeFont.loadTTF(PDDocument, "c:\\windows\\fonts\\ipaexg.ttf"); | ||
| + | </pre> | ||
| + | この方法は例外が出て失敗 | ||
| + | === フォント辞書にFontFile2を設定してみる === | ||
| + | <pre> | ||
| + | PDFontDescriptorDictionary fd = new PDFontDescriptorDictionary(); | ||
| + | PDStream fStream = new PDStream(_document,new FileInputStream("c:\\windows\\fonts\\ipaexg.ttf")); | ||
| + | fd.setFontFile2(fStream); | ||
| + | fd.setFontName(new String("IPAexゴシック".getBytes("MS932"),"ISO8859-1")); //MS932のバイト列に直して書かないと名前がちゃんとしない | ||
| + | </pre> | ||
| + | この方法ではフォントの埋め込みもできているが、文字化けする。<br> | ||
| + | 化けた文字列をコピペでエディタにはるとちゃんとしているので、コードポイントとグリフがずれているっぽい。 | ||
| + | |||
| + | http://blogs.yahoo.co.jp/bardiel_of_may/62498946.html | ||
| + | |||
| + | ここを参考にグリフの確認をしてみる予定。 | ||
| + | |||
| + | === Encoding をいじってみる === | ||
| + | PDFontに設定するEncodingとdrawStringで変換するエンコーディングをいろいろといじってみた。 | ||
| + | {| class="wikitable" style="width: 20em;" | ||
| + | |- | ||
| + | !PDFont||drawString||結果 | ||
| + | |- | ||
| + | |Identity-H||UCS2||表示されない | ||
| + | |- | ||
| + | |Identity-H||MS932||表示されない | ||
| + | |- | ||
| + | |UniJIS-UCS2-H||UCS2||表示されるがグリフとコードポイントがずれる | ||
| + | |- | ||
| + | |90MS_RKSJ_H||MS932||表示されるがグリフとコードポイントがずれる | ||
| + | |} | ||
| + | |||
| + | [[OpenTypeフォント]]からcmapテーブルを引っこ抜いて、to_unicodeを設定するしかないのか? | ||
| + | |||
| + | = 参考にしたサイト = | ||
| + | * http://labs.uchicom.com/pdfbox/ | ||
| + | * http://d.hatena.ne.jp/seuzo/20090403/1238742091 | ||
| + | |||
| + | = コメント = | ||
| + | <comments/> | ||
2024年8月21日 (水) 21:11時点における最新版
Apache FoundationのPDF生成ライブラリ。
このページは1.8.3準拠で記述しています。
ライセンス
- APL
本家サイト
目次
Mavenでの導入
本家にもあるけど、今回はdependencyに以下を記述。
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>1.8.3</version> </dependency>
使い方
PDFページを追加する。
以下のコードで空白のページを追加することができる。
PDRectangleでページサイズを指定できるが、単位がポイントなのに注意(1ポイント=0.353mm)
PDDocument doc = new PDDocument();
PDRectangle rec = new PDRectangle(幅,高さ);
doc.addPage(new Page(rec));
doc.save("出力先.pdf");
doc.close();
紙のサイズとおおよそのポイント
| サイズ | mm表記 | ポイント表記 |
|---|---|---|
| A3 | 297×427 | 842×1191 |
| A4 | 210×297 | 595×842 |
| A5 | 148×210 | 420×595 |
| B4 | 250×353 | 729×1032 |
| B5 | 176×250 | 516×729 |
| B6 | 125×176 | 363×516 |
文字列/図形の描画
PDFの文字列や図形はstreamで行う。streamはさまざまなオペレータの集合になっている。イメージ的にはdrawマクロみたいなもの。
streamはページに対し、以下のコードで生成する。
PDPageContentStream stream = new PDPageContentStream(PDDocument, PDPage)
図形や文字列のPDFのオペレータに対応するメソッドがある。
streamは必ずcloseすること。closeしないと描画が行われない。
文字列の出力
PDFでの文字列の出力は以下の手順で行う。
PDPageContentStream stream = new PDPageContentStream(PDDocument, PDPage); stream.beginText() //文字列出力の開始を通知 stream.setFont(PDFont,フォントサイズ); //フォントとサイズの指定。マルチバイト文字を出力する場合、対応するフォントの指定が必須。 stream.moveTextPositionByAmount(横位置, 縦位置); //文字列を出力する位置の指定。 stream.drawString(文字列); //文字列の出力 stream.endText(); //文字列出力の終了を通知
フォントの指定
ASCII文字のみであれば組み込みのtype1フォントで用が足りるが、マルチバイト文字を出力することができない。
マルチバイト文字を出力するにはCIDフォントを設定する必要がある。
//日本語文字列であることをしめすPDF辞書を定義
COSDictionary systeminfo = new COSDictionary();
systeminfo.setString(COSName.REGISTRY, "Adobe");
systeminfo.setString(COSName.ORDERING, "Japan1");
systeminfo.setInt(COSName.SUPPLEMENT, 6);
//フォントの書体を設定
PDFontDescriptorDictionary fd = new PDFontDescriptorDictionary();
fd.setFontName("MSゴシック"); //使用するフォント名を指定。フォントの埋め込みはできるのだろうか?
fd.setFlags(4);
fd.setFontBoundingBox(new PDRectangle(new BoundingBox(-500, -300, 1200, 1400)));
fd.setItalicAngle(0);
fd.setAscent(1400);
fd.setDescent(-300);
fd.setCapHeight(700);
fd.setStemV(100);
//日本語CIDフォントを設定する
COSDictionary cid = new COSDictionary();
cid.setItem(COSName.TYPE, COSName.FONT);
cid.setItem(COSName.SUBTYPE, COSName.CID_FONT_TYPE0);
cid.setItem(COSName.BASE_FONT, COSName.getPDFName("KozGoPr6N-Medium")); //ベースとなるフォント名を指定
cid.setItem(COSName.CIDSYSTEMINFO, systeminfo); //日本語用のフォントであることを指定
cid.setItem(COSName.FONT_DESC, fd); //フォントの書体を設定
//フォント設定
COSDictionary font = new COSDictionary();
font.setItem(COSName.TYPE, COSName.FONT);
font.setItem(COSName.SUBTYPE, COSName.TYPE0);
font.setItem(COSName.BASE_FONT, COSName.getPDFName("KozGoPr6N-Medium"));
//文字コードはUCS2にしておく。
//MS932にする場合、埋め込みで「COSName.ENCODING_90MS_RKSJ_H」という定数が用意されている。
font.setItem(COSName.ENCODING, COSName.getPDFName("UniJIS-UCS2-H"));
COSArray array = new COSArray();
array.add(cid);
font.setItem(COSName.DESCENDANT_FONTS, array);
//PDF用type0フォントの生成
PDFont pdFont = new PDType0Font(font);
//ストリームにフォントと出力サイズをセット
stream.setFont(pdFont, 40);
stream.moveTextPositionByAmount(100, 100); //文字列の出力位置に移動
//drawStringはStringで受けるのだが、latain1の文字しか受け付けない。
//文字列をフォントで指定したエンコードのバイト列に変換し、無理やりISO8859-1に変換して出力する必要がある。
stream.drawString(new String(str.getBytes(Charset.forName("ISO-10646-UCS-2")),"ISO8859-1"));
stream.endText();
stream.close();
日本語フォントの埋め込み(pdfbox 2.0 以後だと普通にフォント埋め込みがサポートされている)
とりあえず、TTFは読み込む手段をPDFBoxに設定されていたのでIPAexゴシックで試行錯誤中。
loadTTFでフォントを読み込む
PDFont pdFont = PDTrueTypeFont.loadTTF(PDDocument, "c:\\windows\\fonts\\ipaexg.ttf");
この方法は例外が出て失敗
フォント辞書にFontFile2を設定してみる
PDFontDescriptorDictionary fd = new PDFontDescriptorDictionary();
PDStream fStream = new PDStream(_document,new FileInputStream("c:\\windows\\fonts\\ipaexg.ttf"));
fd.setFontFile2(fStream);
fd.setFontName(new String("IPAexゴシック".getBytes("MS932"),"ISO8859-1")); //MS932のバイト列に直して書かないと名前がちゃんとしない
この方法ではフォントの埋め込みもできているが、文字化けする。
化けた文字列をコピペでエディタにはるとちゃんとしているので、コードポイントとグリフがずれているっぽい。
http://blogs.yahoo.co.jp/bardiel_of_may/62498946.html
ここを参考にグリフの確認をしてみる予定。
Encoding をいじってみる
PDFontに設定するEncodingとdrawStringで変換するエンコーディングをいろいろといじってみた。
| PDFont | drawString | 結果 |
|---|---|---|
| Identity-H | UCS2 | 表示されない |
| Identity-H | MS932 | 表示されない |
| UniJIS-UCS2-H | UCS2 | 表示されるがグリフとコードポイントがずれる |
| 90MS_RKSJ_H | MS932 | 表示されるがグリフとコードポイントがずれる |
OpenTypeフォントからcmapテーブルを引っこ抜いて、to_unicodeを設定するしかないのか?