title_parttitle_parttitle_part
静岡県浜松市であれこれソフトを開発している A.K.I Software のブログです。日々の開発日記やサーバー・セキュリティ関連の話題なども掲載。
<< 2018/06 >>123456789101112131415161718192021222324252627282930
Powered by BLOM Delphi で PDF を出力してみる
小さくも大きくも閉じたりもしません
15/12/26 04:35 / その他のソフト

2週間程前から、PDF出力用のライブラリ(VCL)を今更のように作成しています。

PDF関連のツールは今ではフリーでも沢山ありまして、普段 PrimoPDF などを使わせて頂いているのですが、いくつか気になる点がありまして

1)Excel で作成したファイルを PDF にすると線種が細かく反映できない(Excel 自体に罫線の種類が沢山無いので)

2)日本語フォントのサイズが少し違う気がするというか切れることがある。

無料で使わせて頂いているソフトに文句を言うのは筋違いですし、そもそも Excel に線種が少ないのもしょうがないので、どうにかしたいなと思っていたので、心機一転作ることにしました。

実は過去に3度程トライしたことがありまして、最初の時(多分、PDF 自体がリリースされた頃)リファレンスが英語でどうにもなりませんと早々と諦め。
2度目は、PDF の日本語訳が販売された頃で、買おうと思ったのですが、妙に高いので断念(^-^;
3度目は、英語リファレンスを頑張って読もう!と思ったら、最初の頃に比べてページ数が増えている感じがして、やっぱり断念 orz

今回4度目の正直!って事で、いきなりリファレンスでなんとかしようとしないで PDF のフォーマットから調べてみようと検索していみると、横浜工文社様のサイトに「手書きPDF入門」なるページを発見。(トップページからリンクを探したのですが、現在リンクが張られていないようですのでリンクは控えます。「手書きPDF」で検索するとすぐに出てきます。)

一通り眺めて見ると、何度かリファレンスを読んでいるので、割とすぐに「実際にどうすれば良いか」というのが理解できました。

いや、Adobe の PDF リファレンスはリファレンスですのでしょうがないのですが、前説というか「これはこういうものだ」的な説明が長いんですよ・・・

私の開発スタイルとしては、とりあえず動くものを作って、そこから追加していくタイプですので(PMail Server2 も元はと言えば、メールを送信したい>基本的な SMTP のコマンドを覚える>逆をすればサーバーになるよね>作ってみようか!から始まっていますので。RFC とかを読むようになったのは一通り出来上がってからです)ベースになるものがあると早いのです。

あと、元々本業の方でアプリケーションから印刷する為の簡易スクリプトがありまして(使ったことありませんが、Delphi だと QuickReport みたいな帳票ツールのようなライブラリです)もう 10年以上前から継ぎ足して開発をしているのです。

photo


こんな奴です。いわゆる外部には公開していない社内ツールなので作りは適当です。

photo


こんな感じのスクリプトで指示をします。
スクリプト自体は手書きできるレベルで単純なものなので(仕事で必要になった機能を追加していくだけ)これと組み合わせることにします。

えーと、その前に、PDF の構造なんですが上記の手書きPDF入門の二番煎じになるのですが、おさらいも含めて説明しますと。

1)ヘッダーとして ファイルの先頭に %PDF1-4 とかがあります。PDF のバージョンを指しています。

2)最後は %%EOF で終わります。

3)1と2の間にオブジェクトを配置します。

オブジェクトとは PDF の構造を示す為のもので

A B obj
いろいろとオブジェクト
endobj

という構成になっています。

A B は A が IDとしての数値、B は世代番号らしいのですが 0 以外みたことありませんので基本的には

1 0 obj
endobj

2 0 obj
endobj

3 0 obj
endobj

のようになります。

んで、オブジェクトの中に
a)PDF の構造(しおりとかルートとか)
b)フォントなどの情報
c)コンテンツデータ(文章とか画像とか)
を入れる必要があります。

各オブジェクトは ID によって参照されるような仕組みになっていますので

2 0 obj
画像とかのリソースデータとか。
endobj

3 0 obj
コンテンツデータ
endobj

4 0 obj
/Type/Page/Parent 1 0 R
/Resources 2 0 R
/Contents 3 0 R
endobj

となっていると「4 0 オブジェクトには、3つのデータが指定されていて、/Type/Page/Parent は 1 0 オブジェクト、リソースは 2 0 オブジェクト、コンテンツは 3 0 オブジェクトです」みたいになります。

リソースは端折って、コンテンツは実際の出力するテキストなどを入れておくのですが、元々 PostScript というプリンター用のコマンドを PDF 用にしたものが使われています。

BT
0.0 0.0 0.0 rg
/F1 12.7 Tf
1 0 0 1 1 2 Tm
(Hello) Tj
ET

こんなんです。

BT は BeginText
rg は色を rgb で指定
Tf はフォントの指定とサイズの設定
Tm はテキストを出力する場所を指定
Tj はテキストを実際に出力する
ET は EndText

というような感じになります。(単位は基本的にインチです)

PDF手書き入門にもっと詳しく書かれていますので、そちらをどうぞ(笑)

とりあえず PDF を出力できるようになったら、後は、細々と足りない箇所を埋めていくだけです。

面倒臭いのは日本語フォント関連ですね。
(うちは)基本的に Windows プラットフォームのみを前提としていますので、TrueType フォントを使います。

TrueTypeフォントの情報自体は、GetOutlineTextMetrics() API で取得できますので、これでフォント情報を構成します。

しかし、API でフォント情報を取得しただけでは足りないので、PDF のリファレンスを読みながら出力したいフォントは「こういう名前で、文字コード(PDF的に言うと CID ってのがありまして、これで指定します。文字コードというよりはコードページに近いかな?)はこれです。フォントが無かった場合は、こんな感じで出力して下さい。」のを作ります。

この辺りは考えてもわかるはずのない所ですので、素直にリファレンス見るしかありません。
(90ms-RKSJ-H は、こういう意味ですよーってのは単純に読まないとわかりませんので)

とりあえず CID に関しては、5078.Adobe-Japan1-6.pdf 辺りのファイルに、PDF のリファレンス自体は 1.7 が最新のようですので、pdf_reference_1-7.pdf 辺りを検索すればダウンロードが可能です(英語版は無料でダウンロードできます)

1.7 リファレンスは PDF で約31M、ページ数で 1,300ページ越えのサイズですが、全部じっくり読む必要な無く、それこそ PDF の検索機能で気になる単語で検索すればヒットします。

で、話は最初に戻りまして、元々あるオレオレ帳票ツールに PDF の出力ライブラリを組み合わせましたので、

photo


このように出力が可能となりました。
(最初の画像がオレオレ帳票ツールで、上の画像がそこから PDF に出力したものを Acrobat reader DC で表示しているものです。
一部線画オプションを換えたので角がRのボックスなどは違いますので、基本的にプリンターに印刷するものと同じものを PDF に自力で出力できるようになりました。

こーゆーのを作っておくと、いつかどっかで役にたつ日が来るもんです(来ない可能性の方が遥かに高いですが)

[更新日付:2015/12/26 04:35:16]
トラックバックを見る(0)
Log Link [http://akisoftware.com/cgi-bin/blom.exe?akisoft+sl+4bba0eedc4e85cd69367b3a0aed5d0875ca4353b]
TB Link [http://akisoftware.com/cgi-bin/blom.exe?akisoft+tb+4bba0eedc4e85cd69367b3a0aed5d0875ca4353b]

記事へのコメント

名前 : H.Matsuda (2016/05/18 15:19:45)

yahagiさん

>だけど、楽しいです。時間みて再挑戦してみます。

わかりますー、例え使わなくても楽しいですよね。
こういう物を作るのは。

文字が出るようになる>楽しい!
線がかけるようになる>楽しい!

のように1個づつ完成していく過程が楽しいです。

オープンソースで手軽に出力も有りだと思いますが、プログラマとしてはやっぱり自前で処理したいですね。

名前 : yahagi (2016/05/18 10:35:00)

これいいですね。同じような意図と経験をしていました。
「こーゆーのを作っておくと、いつかどっかで役にたつ日が来るもんです(来ない可能性の方が遥かに高いですが)」
というのも。
だけど、楽しいです。時間みて再挑戦してみます。

名前
コメントキー
 
コメントする時はキーを正確に入力して下さい
コメント
アドレスを含んだコメントはできません
© 2008-10 A.K.I Software all rights reserved.