Tìm hiểu cách tạo reports với JasperReports trong ruby on rails

JasperReport là một trong những công cụ mã nguồn mở của java được sử dụng phổ biến trong việc tạo báo cáo với các định dạng file khác như như (pdf, xml, csv).

Trong ruby on rails(RoR) có rât nhiều gem hỗ trợ việc tạo báo cáo, tuy nhiên hầu hết đều dựa theo nguyên lý tạo ra HTML và chuyển đổi sang PDF hoặc CSV... Trong bài viết này tôi sẽ giới thiệu cách sử dụng JasperReport trong RoR.

Đầu tiên, để sử dụng được một thư viện java trong RoR bạn cần sử dụng JRuby để chạy một chương trình RoR.

Khởi tạo một ứng dụng CRUD cơ bản trong RoR.

Tôi sẽ bắt đầu với một ứng dụng RoR với model "Contacts" và các hàm CRUD.

Đầu tiên: bạn cần cài đặt môi trường là JRuby để khởi tạo chương trình (hướng dẫn tại http://jruby.org/)

rails new jasperreport

Di chuyển đến thư mục chương trình.

cd jasperreport

rails g scaffold Contact name:string address:string city:string phone:string email:string

Tiếp theo bạn cần migrate database:

rake db:migrate

Khởi động server kiểm tra xem saffold đã làm việc chưa.

rails s

Để kiểm tra bạn vào http://localhost:3000/contacts và thử tạo 1 bản ghi Contacts cho việc sử dụng report trong phần tiếp theo.

Tạo một mẫu report với JasperReport.

Để tạo một mẫu báo cáo với JasperReport bạn cần download Jaspersoft Studio tại http://community.jaspersoft.com/project/jaspersoft-studio/releases . Sau đó cài đặt. JasperReport studio là một công cụ được phát triển dựa trên Eclipse để phục vụ việc tạo report bằng JasperReport.

Tạo một mẫu báo cáo với tên Contacts bằng jasperReport studio.

Build report và copy file contacts.jasper vào thư mục app/reports/ trong ứng dụng RoR.

Thêm thư viện JasperReport vào ứng dụng RoR.

Bây giờ đến phần quan trọng nhất, thêm thư viện JasperReport vào ứng dụng RoR của bạn. Bạn cần download thư viện JasperReport tại trang http://community.jaspersoft.com/project/jasperreports-library/releases và copy vào thư mục sau trong ứng dụng của bạn. jasperreport --app ...... --lib jasperreports jasperreports-6.3.0.jar

Tiếp theo bạn cần tạo một lớp để tích hợp jasperreport vào ứng dụng của bạn.

Tạo file jasper_report.rb trong thư mục lib có nội dung như sau:

Dir.entries("#{Rails.root}/lib/jasperreports").each do |lib|
  require "jasperreports/#{lib}" if lib =~ /\.jar$/
end

require "java"

java_import Java::net::sf::jasperreports::engine::JasperFillManager
java_import Java::net::sf::jasperreports::engine::JasperExportManager
java_import Java::net.sf.jasperreports.engine.JRResultSetDataSource

class JasperReport
  DIR = "#{Rails.root}/app/reports"

  def initialize(report, query, params = nil)
    @model = report
    @report_params = params
    @conn = ActiveRecord::Base.connection.jdbc_connection
    @query = query
  end

  def to_pdf
    stmt = @conn.create_statement
    @result = JRResultSetDataSource.new(stmt.execute_query(@query))
    report_source = "#{DIR}/#{@model}.jasper"
    raise ArgumentError, "#@model does not exist." unless File.exist?(report_source)
    params = {}
    params.merge!(@report_params) if @report_params.present?
    fill = JasperFillManager.fill_report(report_source, params, @result)
    pdf = JasperExportManager.export_report_to_pdf(fill)
    return String.from_java_bytes(pdf)
  end
end

Bây giờ cùng xem thử đoạn code trên bạn đã làm gì nào:

Dir.entries("#{Rails.root}/lib/jasperreports").each do |lib|
  require "jasperreports/#{lib}" if lib =~ /\.jar$/
end

Đầu tiên bạn đang yêu cầu tất cả file .jar trong thư mục jasperreports vào ứng dụng của mình.

require 'java'

java_import Java::net::sf::jasperreports::engine::JasperFillManager
java_import Java::net::sf::jasperreports::engine::JasperExportManager
java_import Java::net.sf.jasperreports.engine.JRResultSetDataSource

Tiếp theo là phần thêm thư viện jasperreports cho java.

`DIR = "#{Rails.root}/app/reports"`

Phần định nghĩa nơi sẽ lưu trữ file báo cáo của bạn.

def initialize(report, query, params = nil)
    @model = report
    @report_params = params
    @conn = ActiveRecord::Base.connection.jdbc_connection
    @query = query
end

Thêm một method khơi tạo cho class của bạn.

trong đó:

report: tên file báo cáo query: lệnh SQL truy vấn đến csdl params: một đối số bất kỳ cho việc báo cáo.

@conn là một cổng kết nối JDBC mà jasperreport yêu cầu để thực hiện một câu query.

Cuối cùng, bạn cần thêm một method để export dữ liệu sang PDF:

def to_pdf
  stmt = @conn.create_statement
  @result = JRResultSetDataSource.new(stmt.execute_query(@query))
  report_source = "#{DIR}/#{@model}.jasper"
  raise ArgumentError, "#@model does not exist." unless File.exist?(report_source)
  params = {}
  params.merge!(@report_params) if @report_params.present?
  fill = JasperFillManager.fill_report(report_source, params, @result)
  pdf = JasperExportManager.export_report_to_pdf(fill)
  return String.from_java_bytes(pdf)
end

Bạn đã có một method để export dữ liệu sang PDF, tuy nhiên bạn chưa thể gọi được chúng trong RoR, vì vậy bạn cần một method để trợ giúp việc này.

Bạn cần thêm một method mà khi cần sử dụng thì gọi đến chúng. Tại đây tôi viết method này trong file app/controllers/contacts_controller.rb:

  def respond_to_report(name, query, filename, download = false, report_params = nil)
    @report = JasperReport.new(name, query, report_params)
    disposition = (download.nil? || download == false) ? 'inline' : 'attachment'
    send_data @report.to_pdf, :filename => filename, :type => :pdf, :disposition => disposition
  end

Method này hỗ trợ bạn trong việc gửi phản hồi lại cho người dùng đồng thời giúp người dùng chọn tải report về máy.

Tiếp theo bạn cần add một action để gọi đến việc tạo report.

Bạn thêm method report trong file app/controllers/contacts_controller.rb:

def report
  respond_to_report('contacts', 'select * from contacts', 'contacts.pdf')
end

Thêm một action trong file routes.rb

`resources :contacts do`
`get :report`
`end`

Thêm link report trong file contacts/index.html.erb để download file báo cáo.

`<%= link_to 'Download as PDF', report_contacts_path %>`

Cuối cùng: bạn chạy lại server RoR và xem thành quả của mình: http://localhost:3000/contacts. Chọn ‘Download as PDF để xem file PDF.

Kết thúc.

Đây là một cách đơn giản để áp dụng Jasperreport vào một ứng dụng RoR. Tôi hy vọng nó giúp ích cho các bạn.

Để hiểu rõ hơn về ứng dụng, bạn có thể tìm hiểu trước về Jruby và cách chạy ứng dụng java trong một ứng dụng RoR.

Chúc các bạn có thể thực hiện thành công trong việc thực hiện ứng dụng này.

Source code: github

Nguồn: https://www.sitepoint.com/create-great-reports-jasperreports/