Ruby から JasperReports でPDF帳票を出す(PDF出力処理をサーバ化)
Railsをpassengerで動かしている時に、RJBでJavaのライブラリJasperReportsを呼び出そうとすると
うまくいかなかった。
なので、一つの解決法としてJasperReportsの呼び出し部分をRailsとは切り離す仕組みとしてDRubyを採用する。
サンプルは別途リンクを張りますが、ここでは主要なソースのみ書き出します。
まずは、実際にPDFを作成する部分から
gen/WritePdf.java:
package gendosu;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
import java.util.List;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRPrintPage;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.util.JRLoader;
public class WritePdf {
private String _hostName = "localhost";
private String _databaseName = "jasper_report_on_rails_development";
private String _userName = "root";
private String _password = "root";
public WritePdf(String hostName, String databaseName, String userName, String password) {
_hostName = hostName;
_databaseName = databaseName;
_userName = userName;
_password = password;
}
public void runTest(String jasperName, String jasperName2, String pdfName, HashMap paramMap){
Connection con = null;
try {
con = getConnection();
List pages = null;
OutputStream outstream = null;
// メインになる帳票を取得
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperName, paramMap, con);
// 追加する帳票を取得
JasperPrint jasperPrint2 = JasperFillManager.fillReport(jasperName2, paramMap, con);
// 追加する帳票をメイン帳票に追加
pages = jasperPrint2.getPages();
for(JRPrintPage page : pages ){
jasperPrint.addPage(page);
}
// 帳票をPDFファイルに出力
JasperExportManager.exportReportToPdfFile(jasperPrint, pdfName);
} catch (JRException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeConnection(con);
}
}
private Connection getConnection(){
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String jdbcValue = String.format("jdbc:mysql://%s/%s", _hostName, _databaseName);
con = DriverManager.getConnection(jdbcValue, _userName, _password);
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
private void closeConnection(Connection con){
try {
con.close();
} catch (Exception e) {
}
}
}
このJavaのメソッド「runTest」をrubyから呼び出します。
つづいて、この「runTest」を呼び出すrubyソース
create_pdf.rb:
require 'rubygems'
require 'drb/drb'
require 'rjb'
require 'erb'
require 'yaml'
CURRENT_PATH = File.dirname(File.expand_path(__FILE__))
classpaths = Dir.glob( File.join(CURRENT_PATH, 'java/lib/*.jar'))
classpaths.concat(Dir.glob(File.join(CURRENT_PATH, 'java/dist/*.jar')))
Rjb::load(classpath = classpaths.join(':'), jvmargs=[])
HashMap = Rjb::import("java.util.HashMap")
FileInputStream = Rjb::import('java.io.FileInputStream')
FileOutputStream = Rjb::import('java.io.FileOutputStream')
WritePdf = Rjb::import('gendosu.WritePdf')
class CreatePdf
def initialize(stream=$stdout)
@stream = stream
@database = YAML::load(ERB.new(IO.read(File.join(CURRENT_PATH, 'config/database.yml'))).result)
end
def run_test(pdfName, outputDate, print_record_id)
jasperName = File.join(CURRENT_PATH, 'java/reports/report1.jasper')
jasperName2 = File.join(CURRENT_PATH, 'java/reports/report1.jasper')
@write_pdf = WritePdf.new(@database[@stream]['host'], @database[@stream]['database'], @database[@stream]['username'], @database[@stream]['password'])
hash_map = HashMap.new
hash_map.put("OUTPUT_DATE", outputDate);
hash_map.put("PRINT_RECORD_ID", print_record_id);
@write_pdf.runTest(jasperName, jasperName2, pdfName, hash_map)
end
end
@port = YAML::load(ERB.new(IO.read(File.join(CURRENT_PATH, 'config/pdf_server.yml'))).result)
rails_env = ARGV.shift
uri = "druby://localhost:#{@port[rails_env]['port']}"
DRb.start_service(uri, CreatePdf.new(rails_env))
puts DRb.uri
sleep
これで、RubyからRJBを使ってJavaのインスタンスを起動し、JasperReportsでPDF出力することが出来ます。
ここまでの修正で、実行テストは
create_pdf_client.rb:
require 'drb'
pdfName = 'test.pdf'
there = DRbObject.new_with_uri("druby://localhost:8787")
there.run_test(pdfName, "TEST", 1)
とし、このcreate_pdf_client.rbファイルを実行すると、PDFファイルが作成されます。

