ColdFusionカフェテリア
SAMURAIZ

 

| ↑トップへ戻る |

JasperReportsによる帳票出力【後編】

作成日: 2015年2月9日
作成者: アップクロス株式会社 西元貞昭
公開日: 2015年4月8日

■はじめに

アップクロス株式会社の西元です。
後編では、JasperReportsで帳票出力を行うプログラムについて説明していきます。

■サンプル・プログラム

まずは、以下の3つのzipファイルをダウンロードして、開発用PCに展開してください。

帳票出力プログラム一式(JasperToPDF.zip)
JasperToPDF.zipに含まれるファイル一覧:
Client/
  JasperToPdf.jar
Server/
  JasperToPDFServer.jar
  JasperToPDFServer.policy
  lib/
    commons-beanutils-1.8.0.jar
    commons-collections-3.2.1.jar
    commons-digester-2.1.jar
    commons-logging-1.1.1.jar
    ipa_fonts.jar
    iText-2.1.7.js2.jar
    iText-2.1.7-LICENSE.txt
    jasperreports-5.6.1.jar
    jasperreports-fonts-5.6.1.jar
    jaxen-1.1.1.jar
    log4j-1.2.15.jar
帳票出力サンプル一式(JasperToPDF_sample.zip)
JasperToPDF_sample.zipに含まれるファイル一覧:
DB/
  CRE_USER_M.sql
  INS_USER_M.sql
web/
  index.cfm
  get_UsersList.cfm
  UserList.jasper
  UserList.jrxml
  userslist.xml
帳票出力プログラム・ソース一式(JasperToPDF_src.zip)
JasperToPDF_src.zipに含まれるファイル一覧:
build.xml
commons-logging.properties
jasperreports.properties
JasperToPdf.manifest
JasperToPDFServer.manifest
JasperToPDFServer.policy
log4j.properties
lib/
src/
  JasperToPdf.java
  JasperToPdfServer.java
  JasperToPdfServerImpl.java

※帳票出力プログラム・ソース一式には、Javaプログラムのコンパイル&実行に必要なライブラリ(jarファイル)が含まれていません。Javaプログラムを修正したりビルドし直す場合は自身で下記Jarファイルをlibフォルダにコピーしてください。
 ・jasperreports-5.6.1-project.zipに含まれる以下のJarファイル
   jasperreports-5.6.1/lib/*.jar
   jasperreports-5.6.1/dist/*.jar
 ・ipa_fonts.jar ・・・ 前編でiReportからエクスポートしたIPAフォントファイル
 ・cfx.jar ・・・ColdFusionのインストール先フォルダ wwwroot/WEB-INF/lib から取得

■帳票出力プログラムの構成

前編「ColdFusionからJasperReportsを利用する方法」で書いた通り、今回紹介する方法では、JasperReportsライブラリを使って帳票を作成する処理をDaemon(常駐プログラム)として実行し、ColdFusionからJava RMIを使用して帳票作成の処理を依頼します。
Javaで作成するソースファイルは以下の3ファイルです。帳票出力プログラム・ソース一式(JasperToPDF_src.zip)のsrcフォルダにあります。

  • JasperToPdfServer.java ・・・ RMI通信を行うためのインターフェース定義。
  • JasperToPdfServerImpl.java ・・・ 帳票生成処理を行う常駐プログラムの本体。
  • JasperToPdf.java ・・・ ColdFusionアプリからCFXタグで呼び出されるJavaプログラム。

 

いずれも100ステップに満たないコードですので、ソースを読めばすぐに分かるかと思いますが、以下に簡単な説明だけ書いておきます。

 

JasperToPdfServer.java
インターフェースなので、特に処理はありません。RMIでクライアントから呼び出されるdoPrintメソッドの定義があるだけです。

 

JasperToPdfServerImpl.java
JasperToPdfServerImplはJasperToPdfServerインターフェースのdoPrintメソッドを実装しています。また、RMIサーバにもなるためUnicastRemoteObjectを継承しています。
doPrintメソッドで行っている事は、

33行目: JRXmlDataSource jrxmlds = new JRXmlDataSource(xmlFile, selectXPath);
でXMLファイルをXMLデータソースとして読み込み、
35行目: JasperPrint jrprint = JasperFillManager.fillReport(sourceFile, params, jrxmlds);
で、jasperファイルとXMLデータを合成して帳票イメージを作ります。なお、第2引数は使用しないため、34行目で空のHashMapを作って渡しています。その後、
38行目: JasperExportManager.exportReportToPdfFile(jrprint, outputFile);
で帳票イメージをPDFに変換してファイルに保存しています。

mainメソッドは起動時の処理です。
ここでは、RMIサーバとして常駐するためにリモートオブジェクトを生成して、RMIレジストリに登録します。

 

JasperToPdf.java
Java CFXタグとするため、CustomTagインターフェースのprocessRequestメソッドを実装しています。
processRequestメソッドでは、14〜17行目でCFXタグで指定されたパラメータ(属性)を受け取り、値の必須チェックやファイルの存在チェックを行った後で、RMIを使ってJasperToPdfServerのdoPrintメソッドをコールします。

61行目: JasperToPdfServer jasperToPdfServer = (JasperToPdfServer)Naming.lookup("rmi://localhost/JasperToPdfServer");
で、RMIネームサービスからJasperToPdfServerの参照を取得し、
66行目: String ret = jasperToPdfServer.doPrint(strJasperFile, strXmlFile, strSelectPath, strExportType, strOutputFile);
でJasperToPdfServerオブジェクトのdoPrintメソッドをコールしています。
なお、61行目のlookupメソッドの引数を"rmi://localhost/JasperToPdfServer"と書いているため、JasperToPdfServerが同一サーバ上で実行されている必要があります。

mainメソッドはコマンドラインからテスト実行するために書いてあります。CFXタグとしては必要ありません。

 

これらをコンパイルしたクラスファイルのうち、帳票生成Daemon(常駐プログラム)となるJasperToPdfServer.jar
JasperToPdfServer.classとJasperToPdfServerImpl.classで構成され、Java CFXタグの実体となるJasperToPdf.jar
JasperToPdf.classとJasperToPdfServer.classで構成されています。

便宜上、この記事ではJasperToPdfServer.jarとJasperToPdf.jarを合わせて「帳票出力プログラム」と表記しています。

■帳票出力プログラムのインストール・設定

(1) 帳票出力プログラム一式をWebサーバにコピー

  • JasperToPDF.zip内のServerフォルダ以下を全てColdFusionが動作しているWebサーバ上の任意のフォルダにアップロードしてください。例) C:\JasperToPDF\Server
  • JasperToPDF.zip内のClientフォルダにある JasperToPdf.jar をColdFusionのインストール先フォルダ配下の wwwroot/WEB-INF/lib にコピーしてください。その後、ColdFusionサービスを再起動してください。

 

(2) 帳票生成Daemon(常駐プログラム)の実行
Webサーバでコマンドプロンプトを開き、カレントディレクトリを JasperToPDFServer.jar があるフォルダに移動してから、以下のコマンドを実行してください。

java -Djava.security.policy=JasperToPDFServer.policy -jar JasperToPDFServer.jar
コマンドプロンプトに「Start JasperToPDFDaemon.」と表示されれば成功です。

常駐プログラムを終了する際は、このコマンドプロンプト画面で[Ctrl]+[C]を押してください。

 

(3) Java CFXタグの登録
ブラウザを起動し、WebサーバのColdFusion Administratorにログインしてください。
左のメニューから「拡張機能>CFXタグ」を選択して、[Java CFXの登録]ボタンを押してください。

「拡張機能>CFXタグ>Java CFXの管理」画面でCFXタグ名「cfx_JasperToPdf」とクラス名「JasperToPdf」を入力して[送信]ボタンを押してください。
※説明欄は任意入力です。

 

以上で、ColdFusionアプリケーションでcfx_JasperToPdfタグを記述すればJasperReportsの帳票出力が使えるようになります。

cfx_JasperToPdfタグの書式:

<CFX_JASPERTOPDF JASPER="jasperファイルのフルパス名"
          DATA="XMLデータファイルのフルパス名"
          XPATH="XML内の明細レコードを指すXPATH"
          OUT="作成するPDFファイルのフルパス名">

■帳票出力サンプルの概要

今回使用する帳票出力サンプル(JasperToPDF_sample.zip)は、『利用者一覧表出力画面で、性別と都道府県を選択して[印刷]ボタンを押すと、ユーザマスタ(USER_M)テーブルから対象ユーザを抽出して一覧表のPDFファイルを表示する』と言うものです。
※サンプルなのでエラー処理は考慮していません。また、抽出結果が0件の時は空白のPDFが出力されます。

 

ソースファイル構成
JasperToPDF_sample.zipのWebフォルダに以下のファイルがあります。

 

  • index.cfm : 一覧表出力画面を表示します。性別、都道府県を指定して[印刷]ボタンが押されると、./get_UsersList.cfmをリクエストします。
  • get_UsersList.cfm : ユーザマスタ(USER_M)テーブルから対象レコードを抽出してXMLファイルを作り、cfx_JasperToPdfタグで一覧表のPDFファイルを作成します。その後、作成したPDFファイルをレスポンスとしてブラウザに返します。詳細は後述します。
  • UserList.jrxml : iReportで作成する利用者一覧表のレポート定義ファイルです。
  • UserList.jasper : iReportでコンパイルされた利用者一覧表のJasperファイルです。cfx_JasperToPdfタグのJASPER属性でこのファイルのフルパスを指定します。
  • userslist.xml : iReportで利用者一覧表のレポート定義を作成するためのXMLデータソースです。中身はget_UsersList.cfmで作成するXMLファイルと同じXMLタグ構成になっている必要があります。

 

サンプル実行に必要なのは、このうち index.cfm, get_UsersList.cfm, UserList.jasper の3ファイルです。
これら3ファイルをWebサーバのドキュメントルート以下の任意のフォルダに置いてください。(例:C:\www\sample)

■サンプル用のデータ作成

このサンプルを実行するために、データベースに以下のテーブルを作成してください。

テーブル名:USER_M(ユーザマスタ)
列ID 列名称 サイズ NOT NULL 備考
ID ID VARCHAR2 8 Yes Primary Key
NAME 氏名 VARCHAR2 20 Yes
GENDER 性別 VARCHAR2 1 M:男性/F:女性
BIRTH_DATE 生年月日 DATE
ZIP_CD 郵便番号 VARCHAR2 10
STATE 都道府県 VARCHAR2 10
TEL_NO 電話番号 VARCHAR2 20
FAX_NO FAX番号 VARCHAR2 20
MAIL メールーアドレス VARCHAR2 60
REGIST_DATE 登録日 DATE
JasperToPDF_sample.zip 内の DB/CRE_USER_M.sql は、Oracle用のCREATE TABLE文です。DBMSにOracleを使用しているのであれば、sqlplus等でこのスクリプトを実行する事でUSER_Mテーブルを作成できます。

[DB/CRE_USER_M.sql]
DROP TABLE USER_M;
CREATE TABLE USER_M (
    ID                             VARCHAR2(8) NOT NULL,
    NAME                           VARCHAR2(20) NOT NULL,
    GENDER                         VARCHAR2(1),
    BIRTH_DATE                     DATE,
    ZIP_CD                         VARCHAR2(10),
    STATE                          VARCHAR2(10),
    TEL_NO                         VARCHAR2(20),
    FAX_NO                         VARCHAR2(20),
    MAIL                           VARCHAR2(60),
    REGIST_DATE                    DATE,
    CONSTRAINT USER_M_PK PRIMARY KEY (ID) USING INDEX
        TABLESPACE USERS
)
TABLESPACE USERS;

COMMENT ON TABLE  USER_M IS 'ユーザマスタ';
COMMENT ON COLUMN USER_M.ID IS 'ID';
COMMENT ON COLUMN USER_M.NAME IS '氏名';
COMMENT ON COLUMN USER_M.GENDER IS '性別';
COMMENT ON COLUMN USER_M.BIRTH_DATE IS '生年月日';
COMMENT ON COLUMN USER_M.ZIP_CD IS '郵便番号';
COMMENT ON COLUMN USER_M.STATE IS '都道府県';
COMMENT ON COLUMN USER_M.TEL_NO IS '電話番号';
COMMENT ON COLUMN USER_M.FAX_NO IS 'FAX番号';
COMMENT ON COLUMN USER_M.MAIL IS 'メールアドレス';
COMMENT ON COLUMN USER_M.REGIST_DATE IS '登録日';
DB/INS_USER_M.sql はテストデータを100件登録するINSERT文です。USER_Mテーブルを作成したら、このスクリプトを実行してください。

 

※USER_Mテーブルを作成したデータベースにColdFusionから接続するために、ColdFusion Administratorの「データとサービス/データソース」画面でデータソースとして登録しておいてください。

■get_UsersList.cfmについて

get_UsersList.cfm で行っている処理について、簡単に説明します。また、フォルダ名やデータソース名等はご自身のWebサーバの環境に合わせて変更してください。

 

  • 10行目・・・Webサーバに置いたコンパイル済みレポート定義ファイル(UserList.jasper)のファイル名をフルパスで指定します。【環境に合わせて変更してください】
  • 13行目・・・帳票出力処理中に作成される一時ファイルの作成場所(フォルダ)を指定します。【環境に合わせて変更してください】
  • 19〜46行目・・・Formから抽出条件の値を取り出し、cfqueryでSQLを実行します。【環境に合わせて33行目のdatasource名を変更してください】
  • 48〜67行目・・・クエリーからXML文字列を作成します。
  • 70行目・・・作成したXML文字列を一時ファイルに保存します。
  • 73行目・・・cfx_JasperToPdfタグを使って帳票出力を実行します。作成するPDFの保存ファイル名(フルパス)をOUT属性で指定します。
  • 76行目・・・PDF作成後の後始末として、XML一時ファイルを削除します。
  • 78〜80行目・・・作成したPDFファイルをcfheader, cfcontentタグでブラウザに返します。

 

[get_UsersList.cfm]
<cfprocessingdirective pageencoding="MS932">
<cfcontent type="text/html; charset=MS932">
<cfscript>
SetEncoding("url", "MS932");
SetEncoding("form", "MS932");
</cfscript>
<cftry>

<!--- jasperファイルのフルパス --->
<cfset jasperFile = "C:\www\sample\UserList.jasper" >

<!--- XML/PDF一時ファイルの作成フォルダ --->
<cfset tempDir = "C:\temp\" >

<!--- XML&PDFの一時ファイル名を取得 --->
<cfset xmlfile = GetTempFile(tempDir, "XML")>
<cfset pdffile = GetTempFile(tempDir, "PDF")>

<!--- 抽出条件セット(都道府県&性別) --->
<cfset cond = StructNew() >
<cfif isDefined("form.selState") >
	<cfset cond.state = form.selState >
<cfelse>
	<cfset cond.state = "" >
</cfif>
<cfif isDefined("form.selGender") >
	<cfset cond.gender = form.selGender >
<cfelse>
	<cfset cond.gender = "0" >
</cfif>

<!--- DBより帳票に出力するデータを取得 --->
<cfquery name="qry" dataSource="SAMPLE" result="res" >
SELECT ID, NAME, DECODE(GENDER, 'M', '男性', 'F', '女性', '不明') GENDER
     , TO_CHAR(BIRTH_DATE, 'YYYY/MM/DD') BIRTH_DATE
     , ZIP_CD, STATE, TEL_NO, FAX_NO, MAIL
     , TO_CHAR(REGIST_DATE, 'YYYY/MM/DD') REGIST_DATE
     , TRUNC(MONTHS_BETWEEN(SYSDATE, BIRTH_DATE)/12) AGE
FROM USER_M
WHERE (<cfqueryparam value="#cond.gender#" CFSQLType="CF_SQL_VARCHAR"> = '0'
   OR GENDER = <cfqueryparam value="#cond.gender#" CFSQLType="CF_SQL_VARCHAR">)
<cfif cond.state neq "" >
  AND STATE = <cfqueryparam value="#cond.state#" CFSQLType="CF_SQL_VARCHAR">
</cfif>
ORDER BY ID
</cfquery>

<!--- クエリーからXML書式のデータを作成 --->
<cfset wkColumnList = ListToArray(qry.columnList, chr(44), true) >
<cfset xmlStr = '<?xml version="1.0" encoding="Windows-31J"?>#chr(13)#' >
<cfset xmlStr = xmlStr & '<REPORTS>' & chr(13) >
<cfset xmlStr = xmlStr & '<PARAM>' & chr(13) >
<cfset xmlStr = xmlStr & chr(9) & '<SYSDATE>' & xmlformat(DateFormat(Now(), 'yyyy/mm/dd')) & '</SYSDATE>' & chr(13) >
<cfset xmlStr = xmlStr & chr(9) & '<TITLE>' & xmlformat('*** 利用者一覧表 ***') & '</TITLE>' & chr(13) >
<cfset xmlStr = xmlStr & '</PARAM>' & chr(13) >
<cfset xmlStr = xmlStr & '<ROWSET>' & chr(13) >
<cfloop query="qry" >
    <cfset xmlStr = xmlStr & '<ROW num="#qry.currentRow#">' & chr(13) >
        <cfloop index="i" from="1" to="#ArrayLen(wkColumnList)#" >
            <cfset wkColumnName = wkColumnList[i] >
            <cfset wkColumnData = qry[wkColumnName] >
            <cfset xmlStr = xmlStr & chr(9) & '<#wkColumnName#>#xmlformat(wkColumnData)#</#wkColumnName#>' & chr(13) >
        </cfloop>
    <cfset xmlStr = xmlStr & '</ROW>' & chr(13) >
</cfloop>
<cfset xmlStr = xmlStr & '</ROWSET>' & chr(13) >
<cfset xmlStr = xmlStr & '</REPORTS>' >

<!--- XMLデータを一時ファイルに保存 --->
<cffile action="write" file="#xmlfile#" output="#xmlStr#" charset="Windows-31J">

<!--- 帳票作成処理の実行 --->
<CFX_JASPERTOPDF JASPER="#jasperFile#" DATA="#xmlfile#" XPATH="//ROW" OUT="#pdffile#">

<!--- XMLファイルの削除 --->
<cffile action="delete" file="#xmlfile#">

<!--- PDFファイルのダウンロード --->
<cfheader name="Content-Disposition" value="attachment; filename=利用者一覧表.pdf">
<cfcontent type="application/pdf" file="#pdffile#" deletefile="yes">

<cfcatch type="any">
<cfoutput>
<cfdump var="#cfcatch#">
</cfoutput>
</cfcatch>
</cftry>

■出力サンプルの実行

ブラウザを起動して、Webサーバに置いたindex.cfmにアクセスしてください。

例)ドキュメント・ルートが C:\www で、帳票出力サンプルを C:\www\sample フォルダに置いた場合。

http://sever-name/sample/index.cfm
[一覧表出力画面]

[印刷]ボタンを押すと、利用者一覧表のPDFファイルが表示されます。
[利用者一覧表PDF]

■おわりに

今回紹介した帳票出力プログラムはPDFファイルを作成する機能しか持っていませんが、JasperReportsは様々な出力形式に対応しています。JasperPrintServerImpl.javaに手を加える事で、PDF以外の出力形式にも対応できますし、直接プリンタへ出力する事もできるようになります。
また、今回はコマンドプロンプトで常駐プログラムを実行しましたが、Apacheのcommons-daemonを使用するとWindowsサービスとして実行する事も可能になります。
その他、RMIでの受け渡しをファイルパスではなくデータストリームに変更すればColdFusionと帳票作成処理を別サーバに分離する事も出来そうですし、JSON等他のデータソース形式を使えるようにするのも良いかもしれません。
Java開発に慣れている方なら、意外と簡単に作れるのではないかと思います。

 

それと、JasperToPdf.javaはJava CFXタグのサンプルにもなるかと思います。ColdFusionのCFMLとCFScriptだけで実現するのが困難だったり、複雑すぎてパフォーマンス的に難がある処理等はJava CFXタグで実装する事を検討しても良いのではないでしょうか。

ColdFusionの各種情報の配信


最新情報
■2017/6/26
『ColdFusion 実験室』
実験6

■2017/3/27
ColdFusion 2016 対応
インストール セットアップ情報
CFサーバーのインストール
CFビルダーのインストール

■2016/9/20
『ColdFusion 2016 リリース
Enterprise Edition 活用資料』
記事一覧

■2016/3/30
『ColdFusion 実験室』
実験4、実験5

■2015/8/10 〜
『ColdFusion クリニック』
記事一覧(随時更新中)

■2015/4/8
『JasperReportsによる帳票出力』
2. JasperReportsによる帳票出力【後編】

■2015/3/12
アップクロス株式会社
西元 貞昭様
『JasperReportsによる帳票出力』
1. JasperReportsによる帳票出力【前編】


■2015/2/25
『ColdFusionでエクセルを使いこなそう!』
4. 【上級】ColdFusionのエクセル機能を利用したPDF帳票の紹介

ColdFusionトレーニング


ColdFusionユーザーグループ
ColdFusionユーザーグループ
Copyright 2012 Samuraiz Corporation. All Rights Reserved.