Help us understand the problem. What is going on with this article?

Javaで帳票をPDF出力(JasperReport)

More than 3 years have passed since last update.

概要

  • 帳票デザイナはJasper Studioを利用
    • フォントはIPAフォントを利用
    • 帳票デザイナ側でコンパイル
  • コンパイルした帳票定義体を使ってJava経由でPDF出力

インストール

IPAフォントのインストール

Kobito.BINfiV.png

  • 解凍するとipaexg.ttfipaexm.ttfが出てくるので任意の場所に格納
    • システムフォントへのインストールは不要

Jaspersoft Studioのインストール

  • Jaspersoft Studioは単体インストールとEclipseに組み込む方式の2通りがある

    • 単体インストールの場合はここからダウンロードしてインストーラに従えばOK
    • 今回はEclipse組み込みで利用する
  • Eclipseを開き、Help -> Eclipse MarketPlaceを開く

  • Findのところにjasperで検索

  • Jaspersoft Studioのinstallを押す

Kobito.L4u0vb.png

  • あとは流れでインストール。インストール後、eclipse再起動
    • 途中、Calculating requirements and dependencies.で30分とか(もっと?)待たされるけど気長に待つ

Kobito.WRjyvH.png

Jaspersoft Studioにfontの設定

  • preference -> Jaspersoft Studio -> Fonts

  • Addを押して以下のように2つ登録

Kobito.GlJ6jD.png

Kobito.JJG29W.png

レポート作成

projectの作成

  • File -> New -> Other -> JasperReport Project
  • 任意の名前でprojectを作成

    • 今回はデザイナ用のprojectで分けたかったので
    • 既存のjava projectに帳票を作っていくのでもOK
  • Window -> Open Perspective -> Other -> Report Design でJasper用perspectiveを開く

お試しreportの作成

  • project右クリック -> New -> Jasper Report
  • 任意のファイル名.jrxmlを作成
  • 適当なStatic Textを配置して日本語を記入

Kobito.o90mYx.png

  • PDFフォントやPDF Embedded設定は不要

  • 保存するとjasperファイルが出来上がる

データセットの作成

  • CSVファイルを読み込み、プレビューさせるようにする
  • 任意の場所にcsvファイルを作成。今回は以下のように
id, name
1, hoge
2, fuga
  • Project右クリック -> New -> Data Adapter
  • Filenameに任意の名前.xmlを設定してNext
    • 1帳票1Data Adapterの方がわかりやすいので帳票名と合わせたほうがよい
  • Data Adaptersからcsvを選択

Kobito.W2rlTt.png

  • Data Adapterの設定をする

Kobito.8tDv1y.png

  • Report側にData Adapterの設定をする
  • 帳票の何もないところをクリックしてPropertiesを見る
  • ReportタブのDefault Data Adapterを開く

Kobito.QtcVrJ.png

Kobito.J8Fnlf.png

  • これでOutLineとかにFieldsとしてCSVで定義した項目が表示されるのでドラッグアンドドロップで配置

Kobito.RruCVS.png

  • Previewタブを開き、dataadapterの設定をする

Kobito.OMIByc.png

  • ちゃんとpreviewできていることを確認

Kobito.rlfCRy.png

PDF出力Javaモジュールの作成

project作成

  • Gradleを利用して作ってみる
  • New -> Project -> Gradle Project
  • 任意の名前でprojectを作成

Gradle設定

  • Jasperレポート実行に必要な依存ライブラリを定義
  • 一部、mavenCentralにないものもあるのでリポジトリもいくつか追加してる
  • buildしたら実行可能jarを作りたいのでmanifest定義もここでしている
  • jarにまとめた時、bcmailやbctspといった依存ライブラリが悪さをするのでexclude指定している
build.gradle
buildscript {
    repositories {
      mavenCentral artifactUrls: [
        'http://jasperreports.sourceforge.net/maven2',
        'http://jaspersoft.artifactoryonline.com/jaspersoft/third-party-ce-artifacts/'
      ]

      maven {
        url "https://plugins.gradle.org/m2/"
      }
    }
    dependencies {
    }
}

plugins {
  id 'us.kirchmeier.capsule' version '0.10.0'
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'

sourceCompatibility = 1.8

archivesBaseName = 'jasperConverter'

repositories {
    mavenCentral artifactUrls: [
        'http://jasperreports.sourceforge.net/maven2',
        'http://jaspersoft.artifactoryonline.com/jaspersoft/third-party-ce-artifacts/'
    ]
}

configurations {
  all*.exclude module: 'bcmail-jdk14'
  all*.exclude module: 'bctsp-jdk14'
  all*.exclude module: 'bcprov-jdk14'
}

dependencies {
    compile 'commons-collections:commons-collections:3.2'
    compile 'net.sf.jasperreports:jasperreports:6.2.1'
    compile 'com.lowagie:itext:2.1.7'
    testCompile 'junit:junit:4.+'
}

mainClassName = 'sample.Main'

task fatCapsule(type: FatCapsule) {
  applicationClass mainClassName
}

task executableCapsule(type: FatCapsule) {
  applicationClass mainClassName
  reallyExecutable
  archiveName = 'jasperConverter'
}

PDFフォント埋め込み用の設定

  • resources配下に以下の感じでファイルを配置

Kobito.iQKfCW.png

  • resources/font配下にipaフォントのttfを配置
  • jasperreports_extension.propertiesは以下のように記述
jasperreports_extension.properties
net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.font=fonts/font.xml
  • font.xmlは以下のように
    • この時、fontFamilyに指定する名前=レポート側で設定したフォント名であるようにする
    • このフォント名でttfファイルとのひも付けをする
font.xml
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
  <fontFamily name="ipaexg">
    <normal>fonts/ipaexg.ttf</normal>
    <pdfEncoding>Identity-H</pdfEncoding>
    <pdfEmbedded>true</pdfEmbedded>
  </fontFamily>
  <fontFamily name="ipaexm">
    <normal>fonts/ipaexm.ttf</normal>
    <pdfEncoding>Identity-H</pdfEncoding>
    <pdfEmbedded>true</pdfEmbedded>
  </fontFamily>
</fontFamilies>

PDF出力javaメイン処理

  • コマンドラインより起動されるとして
  • パラメータが以下を渡されるものとする

    • 帳票定義体ファイル(*.jasper)のパス
    • 入力するCSVファイルのパス
    • 出力するPDFファイルのパス
  • として記述したもの

package sample.jasperconverter;

import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;

import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRCsvDataSource;

public class Main {

  public static void main(String[] args) throws Exception {
    Map<String, Object> parameters = new HashMap<>();


    if (!validateArgs(args)) {
      System.out.println("parameter error");
      System.exit(9);
    }

    String jasperPath =  args[0];
    String inputFilePath = args[1];
    String outputFilePath = args[2];

    JRCsvDataSource dataSource = new JRCsvDataSource(new FileInputStream(new File(inputFilePath)));
    dataSource.setUseFirstRowAsHeader(true);

    JasperRunManager.runReportToPdfFile(jasperPath, outputFilePath, parameters, dataSource);

  }

  private static boolean validateArgs(String[] args) {

    if (args.length != 3) {
      System.out.println("parameter length error expected 3 but " + args.length);
      return false;
    }


    for(int i=0; i<args.length; i++){
      System.out.println("execute parameter " + i + ":" + args[i]);

      switch(i) {
      case 0:
        // jasper file path
        String jasperpath = args[i];
        if (!isFileExists(jasperpath)) {
          System.out.println("not found jasper file. path:" + jasperpath);
          return false;
        }
        break;

      case 1:
        // input csv file path
        String inputpath = args[i];
        if (!isFileExists(inputpath)) {
          System.out.println("not found input file. path:" + inputpath);
          return false;
        }
        break;

      case 2:
        // output pdf file path
        break;
      }
    }

    return true;
  }

  private static boolean isFileExists(String filepath) {
    return (new File(filepath)).exists();
  }


}


  • これをGradleからfatCapsuleして出来上がったjasperConverter-capsule.jarを実行すればOK
java -jar jasperConverter-capsule.jar ./trial.jasper ./input.csv ./output.pdf

帳票に外部イメージファイルを渡す(2016.3.22追記)

  • ロゴ等のイメージファイルを帳票上表示させたい
  • ファイルは後から置き換えられるように外部リソースにする

デザイナ側

Imageを配置

  • imageをドラッグアンドドロップで配置

  • 画像ファイルの指定ダイアログが出るがとりあえずNo Imageを選択して後で指定させる

Kobito.Co6ahi.png

  • 配置したImageのpropertiesから配置やサイズを指定
  • propertiesのImageタブにあるExpressionに以下のように記述

Kobito.SscycJ.png

  • ここで指定したキー名が帳票実行時のパラメタのキー名と対応する

パラメタの追加

  • Outline -> Parameters右クリック -> Create Parameterを選択

  • 作成したparameterのpropertiesで以下のように設定

Kobito.l3alqp.png

Previewで確認

  • Previewを出そうとするとパラメータlogoを求められるのでここに画像ファイルパスを入力する

Kobito.IzgW5m.png

  • これでプレビューに画像イメージが表示される

Java側

  • parameterにキー名とパスをセットするだけ

  • 抜粋で記載

Map<String, Object> parameters = new HashMap<>();

parameters.put("logo", "path-to-logo.png");

...

JasperRunManager.runReportToPdfFile(jasperPath, outputFilePath, parameters, dataSource);


Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away