SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Javaの標準機能だけで実現する帳票印刷

Javaの標準機能だけで印刷する際の用紙のサイズや向き、余白の指定

Javaの標準機能だけで実現する帳票印刷 第2回


実行結果:PrinterJobでの印刷の評価

 図はプリンタはCanon MP493で葉書に横置き(紙送りは常に長辺方向)で印刷したものをスキャンし、左上の部分を示しました。WindowsとLinuxの両方を出します。

 交点の座標は実測で1mm以内の精度になります。このプリンタは葉書の場合に後部トレイの用紙ガイドを中央に寄せるタイプで、精度が出にくくなっています。A4ならば0.5mm以内の精度が出ます。

 0.1mmの精度でないのは、プリンタの用紙セット位置や紙送りの精度の問題で全体がずれているからです。描画された文字や線の相対的な印字位置の精度は指示通りになりますから、全体をシフトして印字位置を微調整するとピタリと合わせることができます。この微調整をGUIで行う方法も連載の中で解説する予定です。

 まず、Windows 10の印字例です。

印刷例/SomethingPrintable01.javaの印字結果
印刷例/SomethingPrintable01.javaの印字結果

 上部にx=0から目盛りを印字しています。LANDSCAPEなのでB = 10.4fの部分が左余白になって、11mmから目盛り線が見えています。指示通りです。

 目盛線を印字した部分で、太さが違うものが見受けられるのが気になるところです。プリンタにより細い線で太さに差が出ることはたまにあります。印刷指示の場所が解像度の都合上ドットとドットの間だった場合に、線の間隔が等間隔であることを犠牲にしてどちらかのドットで近似する場合と、両方のドットに半分の濃さの線を引いて遠目には同じ線があるように見せかける方法があります。後者はアンチエイリアスでは有効な方法ですが、線の場合は太い線に見えてしまうことがあります。最近はプリンタの精度が上がったので、後者に決め打ちされて逆に調整することが難しくなったように感じます。

 次はLinuxの場合です。

印刷例/SomethingPrintable01.javaの印字結果
印刷例/SomethingPrintable01.javaの印字結果

 11mmから目盛り線が見えているところは同じです。全体が左にシフトしているように見えますが、LinuxとCanon MP493の組み合わせの場合、紙送り方向に2~3mmずれます。用紙の大きさによりますが、用紙が同じであればズレは固定されるので全体をシフトして印字すれば解消できます。職場のプリンタを含めいろいろなプリンタを扱いましたが、ここまでズレが大きいのはこれだけです。

 0のフォントが気になります。物理的なフォント名を指定するとPC依存になりますし、Serif, Sans-Serifなどの名前ではJavaの設定に依存します。Linuxでは(Windowsも同じだと思いますが)日本語のフォントと英数のフォントが異なり日本語の文字にまじる英数字と英数だけからなる文字の英数字が違うことがあります。これはまた後で考えてみることにします。

ここまででできること既知の問題点

 プリンタの検索と選択については次回に扱いますが、要求することが次の条件の範囲であれば、プリンタの検索機能は使わなくても間に合います。

 条件:

  • 用紙のサイズがA3、A4などのA系列またはB4、B5などのJISのB系列、または葉書、往復はがきの範囲にある。
  • デフォルトのプリンタのトレイ(用紙カセット)のどれかにその用紙が用意されている。
  • または印刷ダイアログで選択できるプリンタのトレイに、その用紙が用意されていて、ダイアログでの手動選択でも構わない。

 Windowsの場合は、この条件に合致すれば問題はなく印刷できます。

 残念ながらLinuxの場合は必ずデフォルトのトレイの用紙を使おうとするという不具合があります。

 Linux側がDebian 9、プリンタがEPSON PX-1700FおよびCanon MP436の組み合わせでの確認だけですが、プリンタへトレイの切り替えの指示ができません。プリンタごとにデフォルトになっているトレイの用紙を使って画像を拡大・縮小して用紙に合わせてしまったり、印字が乱れたりします。

 Java以外のアプリケーションソフト、例えばLibreOfficeなどからの印刷では、用紙サイズの設定に合わせてトレイを自動で切り替えてくれますから、OSやプリンタドライバの問題ではなく、Javaに問題があるのだと推測できます。

 これはCUPSなどを使って、同じプリンタを複数登録をしておき、それぞれに異なる用紙をデフォルト用紙サイズに設定し、印刷時に異なるプリンタとして選択することで問題なく印刷できます。

 もう一つの問題は、WindowsでもLinuxでも共通の問題です。JIS規格の封筒がMediaSizeNameに登録されていないことです。

 定形郵便の最大サイズである長形3号、A4を折らずに入れる角形2号、それよりちょっと小さい角形20号、結婚式などの案内状によく使われる洋形1号、それよりちょっと小さいけど葉書は入る洋形2号などJISの封筒は20ぐらいあるのですがMediaSizeNameにはありません。

 この問題の一部は印刷サービスAPIのPrintServiceインターフェースのメソッドを使って解決できます。その方法は次回にプリンタの検索に合わせて解説しますが、封筒の印刷であれば正確な位置合わせを要求されないことが多いと思われますので、近いサイズの用紙を指定してプリンタをごまかすことも可能ですし、角形20号や洋形2号などのように欧米規格の用紙サイズに同じ大きさのものがある場合もありますから流用できるかもしれません。

 しかし、同じサイズの用紙を探す中で、MediaSizeNameに登録されていないJIS封筒が、MediaSizeに登録されているのを発見して混乱することになるかもしれません。 MediaSizeNameに登録されている用紙の実際のサイズはMediaSizeの方に書いてあるからです。 次の節ではMediaSizeに登録されていても使えないことを説明します。

MediaSizeNameとMediaSizeの不一致

 用紙サイズの指定はMediaSizeNameクラスの定数フィールドにあるものを使いますが、実際のサイズはMediaSizeNameクラスには登録されていません。MediaSizeNameから得られるMediaSizeのインスタンスから調べます。

 MediaSizeNameクラスの定数フィールドの値の型はMediaSizeNameですが、実際には整数値で、その整数値をkeyにしてMediaSizeから実際の用紙サイズを得る仕組みになっています。

 この仕組みから考えるとMediaSizeNameのフィールド定数の登録数とMediaSizeのフィールド定数の登録数は同じであるのが自然です。しかし、MediaSizeNameに登録されているのは73個で、MediaSizeは94個です。

 比較したものが次の表です。MediaSizeはISOとかJISとか、元になった規格によって5つのネストされたクラスに分けて登録されています。MediaSizeNameではその分類はなく、まとまって一つになっています。次の表ではMediaSizeに合わせて分類し、対応するものをまとめて比較してあります。

 Java 8とJava 12で確認して同一です。

  MediaSizeName登録数 MediaSize登録数 内容
共通 5 Engineering 5 ANSI規格のDrawing Sizes
27 ISO 27 国際規格(A,B,C系列用紙)
11 JIS 11 JIS規格(B系列用紙)
16 NA 16 北米規格(リーガル,レター,封筒)
11 Other 11 日本の葉書,タブロイド,エグゼクティブなど
片方 3 ISO   国際規格のC0,C1,C2
  JIS 24 JIS規格の封筒(長3,角2,洋1など)
73 94  

 とりあえず問題なのはJIS規格の封筒で、長形1~4号、30号、40号、角形0~8号、20号、角形A4、洋形1~7号の24種類がMediaSizeに登録されているのに、MediaSizeNameにないので、指定できない状況にあります。

 ちなみに現在の封筒のJIS規格(JIS S 5502:2014)は18種類に減っています。JISに示された読み方は長形(なががた)、角形(かくがた)、洋形(ようがた)ですが、MediaSizeのフィールド名は"CHOU"、"KAKU"、"YOU"になっています。

 繰り返しになりますが、MediaSizeというクラスは直接MediaSizeはAttributeSetに加えることができません。先に紹介した「Java印刷サービスAPIユーザー・ガイド」に1か所だけ、MediaSizeのインスタンスをaddする例が載っていますがこれは間違いです。

 この不一致についてMediaSizeとMediaSizeNameの対応という表にまとめています。

 ただし、全く同じサイズが別名で登録されているものも多く、MediaSizeの短辺の降順でソートで短辺の大きい順にソートして調査しています。

 その中から、JIS規格の封筒と同じ、または差がわずかで代用できそうなものをピックアップしておきます。

規格 幅(X) 長さ(Y) あって欲しいがない
MediaSizeName
代用できる
MediaSizeName
差(mm)
角形20号 229 324 JIS_KAKU_20 ISO_C4 0
角形6号 162 229 JIS_KAKU_6 ISO_C5 0
長形2号 119 277 JIS_CHOU_2 NA_NUMBER_12_ENVELOPE 1.65, 2.4
洋形2号 114 162 JIS_YOU_2 ISO_C6 0
洋形6号 98 190 JIS_YOU_6 MONARCH_ENVELOPE 0.298, 0.5
洋形7号 92 165 JIS_YOU_7 PERSONAL_ENVELOPE 0.075, 0.1

 ただし、これはjavax.print.attribute.standardパッケージ内でサイズが一致しているということだけです。個々のプリンタで使えるかどうかはプリンタ(ドライバ)によります。

 この不一致が、2002年に作られた時からそのままで、2019年のver12でも変わっていないということは、間違いなのではなく、何か理由があってこうしているのかもしれません。調べていくとMedisSizeNameにLANDSCAPEが含まれていたり、のりしろの部分を考慮して紙送りの向きを変更したりしています。いろいろと細かなところまでコントロールしようとする日本側の要求に、じゃあ決めないでおくから後は勝手にしてくれということで途中で止まってしまったのではないかと推測しています。

 とにかく、対応していない用紙を使う必要がある時は、ここまでの知識では不足します。

 次回、「プリンタの検索と選択」に進みますが、その中でプリンタ(ドライバ)から対応可能な用紙サイズを取得することを試みます。長形3号封筒なども指定できるようになります。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Javaの標準機能だけで実現する帳票印刷連載記事一覧

もっと読む

この記事の著者

安達 順一(アダチ ジュンイチ)

私立高校に理科・情報の教員として勤めていました。Linuxサーバー/クライアントの授業システムを作り、移動プロファイルで運用していました。教員用にもLinuxサーバーを用意し成績処理プログラムを書きました。情報の学校設定科目ではウェブページ制作とjavaのプログラミングの初歩の授業を作りました。情報...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/11670 2019/10/24 21:58

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー