Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

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

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

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2019/05/09 11:00

 Javaで好みの用紙に自由に文字や線を印刷したいと思ったことはありませんか。Java SEの機能だけを使った帳票印刷の方法を解説します。筆者は教員として学校の成績一覧表、通知表、宛名印刷などのプログラムを書いてきました。もちろん罫線を含めて印刷できますが、すでに印刷された罫線に合わせて文字を入れることもできます。データの量に合わせて表の行数を変えたり、行の高さを変えることもできます。文字列の均等割付や右寄せ、枠に入り切らない時のフォントのサイズ調整や自動改行をさせることもできます。請求書や伝票なども思い通りにレイアウトでき、後の仕様変更にもすぐに対応できます。

目次

はじめに

 やっていることは極めて単純で印字位置をmmで指示して文字列を描き、線を引くだけです。複雑なレイアウトでも実現できるという見通しを持つことができます。

 最近はライブラリやツールが出てきているようですが、筆者はよく知りません。ただ、今までの経験からこの手のツールは使えるようになるまでに、かなりの勉強が必要で、自分の仕事に使えるかどうかの見通しを前もってつけることはなかなか難しいものです。また後々対応できない要求が持ち上がったりします。

 加えて、ツールのバージョン管理や自分の作るプログラムに同梱して配布できるかどうかの制約も考える必要があります。オリジナルの言語の機能だけでできるなら、それに越したことはありません。

 F-BASICでやっていた帳票印刷をUnicode対応にして、ついでにOSの制約からも自由になろうと考えだしたのが2014年ごろでした。Javaで帳票印刷をする方法を書籍やWebで調べたものの情報は少なく、最初に見つけたのが、ここで紹介するPrintableなクラスをPrinterJobまたはDocPrintJobで印刷する方法でした。JPanelに文字を描いたり線を引いたりすることはよくやっていたのですが、72dpiでは解像度が足りないと思っていたのです。Graphics2Dを使ってfloatで位置や長さを指定すれば解像度は十分だと分かってから一気に作業が進みました。文字列や線を描く方法はF-BASICでやっていたものとほとんど同じだったので好都合でした。今後使用する言語が変わっても使える技法だと思います。

 印字位置をmmで指示するというと面倒だと敬遠されることも多いのですが、値を変数に入れ、forで少しずつ増加させながら繰り返すなどということをするので、思いの外面倒ではありません。データをどのように保存してどのように読み出すかを考える方がよほど大変です。

 雛形をコピーして文字列や線の部分を書き換えるだけで試せますから、ぜひお試しください。

この連載で説明する内容

 用紙の縁からの位置や幅・高さをmmで指定して文字や線を描きます。原理的には0.01mmの差も指定可能ですが、現実的には0.1mm程度で十分でしょう。フォントの種類や大きさ、線の太さ、線の種類、色も指定できます。

文字列と直線の印刷例:文字、四角形、直線の基本的な印字
文字列と直線の印刷例:文字、四角形、直線の基本的な印字

 均等割付のための小さなクラスを作れば文字間隔の指定が楽になります。もちろん均等割付本来の役割である文字数が異なっても幅を揃える機能も使えます。文字数が多い場合はそれを感知して自動で小さめのフォントを使ったり2行に分けたりするようにプログラムできます。均等割付けの他、指定幅内でセンタリングや右寄せも可能です。

 追い出し禁則の禁則処理ができます。句読点の場合1つ前の文字を次の行に追い出して調整します。

通知表の印刷例:文字列の均等割付、縦書き、追い出し禁則、罫線で表作成
通知表の印刷例:文字列の均等割付、縦書き、追い出し禁則、罫線で表作成

 プレビューを簡単に作成できます。次の例は宛名印刷です。住所など1行に入り切らなければ、まず空白のある所で改行を試みます。それでも入らない時は、郡、市、丁目などの後で改行を試み、指定の高さに入るようにします。自動で行うので、うまく行っているか24人の宛名を1つずつ確認している図です。

 郵便番号のように既存の枠に合わせて描く場合、印字位置を印刷時に微調整できるようにする方法も紹介します。

葉書宛名の印刷例:あふれる時の自動改行、プレビューと印刷位置の微調整
葉書宛名の印刷例:あふれる時の自動改行、プレビューと印刷位置の微調整

 用紙の大きさも指定できます。A4、A3、葉書、長3封筒(定形郵便の最大)などを例に紹介します。Portrait(縦置)とlandscape(横置)のそれぞれで横書き、縦書きが可能です。

 縦書きの場合、半角の数字も全角の数字も1つずつ漢数字に置き換えることで違和感のない縦書きが可能です。

用紙の向きの指定:用紙の向きと、横書き縦書き
用紙の向きの指定:用紙の向きと、横書き縦書き

 封筒に印刷するときには封の部分が後ろになるように紙送りをするとトラブルが少なくなります。この場合、文字を逆さまに印字しなければなりません。全体を180度回転するように指示することで、簡単に実現できます。

封筒のための180度回転印刷:封筒は底の向きに送る
封筒のための180度回転印刷:封筒は底の向きに送る

対象読者

  • Javaで簡単なプログラムを作れる方。
  • 帳票印刷を内製化しようとしている方。
  • 自分の使うプログラムは自由に作りたいと思っている方。

必要な環境

  • Windows、Mac、Linuxなど、Java 8以上が使える環境。
  • OS上のなんらかのソフトウェアでプリンタが使えるようになっていること。

 Javaの印刷の仕組みはJava 6からほとんど変わっておらず、Java 12でもAPI Documentationを見る限りでは同様に使えるはずです。

 今回の解説の元になったシステムは、プログラム作成がLinux(Debian)上のOpenJDK 7で、実行は主にWindows上でOracleから配布されているJava 7で行いました。それぞれのOSでごく一般的に使われているJavaですが、大きな差はありませんでした。

 解説にあたって、Linux(Debian9)上のOpenJDK 8で作成と動作テストを行い、Windowsでも確認をする予定です。

第1回で説明すること

 文字列、四角、直線を指定場所に印刷するための最も簡単な例を示します。下図のように位置を指定します。赤い+が指定された位置です。

文字列、四角、直線の印刷位置の指定方法:赤で示した+印が指定の印刷位置
文字列、四角、直線の印刷位置の指定方法:赤で示した+印が指定の印刷位置

 文字列はベースラインの開始点をfloat値で指定します。四角は左上の座標と幅・高さをfloat値で、直線は開始点と終了点の座標を指定します。

 フォントの種類とサイズ、線の太さや色の指定も取り扱います。

 印刷の手順は、Printableなクラスでページを作り、PrinterJobクラスを使って印刷するという方法を採用します。

 プリンタの選択や用紙のサイズや向きの指定は次回以降に説明することにし、今回はデフォルトのプリンタのデフォルトの用紙に印刷します。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

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

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

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5