I'm trying to integrate a rails 3 app with jasper following this wiki:
http://wiki.rubyonrails.org/rails/pages/HowtoIntegrateJasperReports
But it seems that a lot of information isn't updated so it's been very hard to make it work by myself. I've also read a topic at ruby-forum: http://www.ruby-forum.com/topic/139453
with some details explained but still couldn't make it work.
My first problem is related with the render_to_string method:
When the controller method runs I receive a "Template is missing" error:
this is the method:
def report
#customers = Customer.all
send_doc(render_to_string(:template => report_customers_path, :layout => false), '/pdfs', 'report.jasper', "customers", 'pdf')
end
Although this seems simple I'm not understanding why is this happening. Doesn't render_to_string with layout => false suposed to get me the string result of that action?
I also tried :action instead of :template, but it does the same.
If anybody with some expertise with this integration could help...
Thanks in advance,
André
We actually use jasperreports to create reports, and recently upgraded to Rails 3.0. To create the xml, we use xml.erb templates. Jasper reports runs in a separate glassfish server Here's the general idea:
url = URI.parse(my_url_string)
dataxml = render_to_string(:template => my_template_name).gsub(/\n/, '')
params = {'type' => 'pdf', 'compiledTemplateURI' => my_jasper_file, 'data' => dataxml }
request = Net::HTTP::POST.new(url.request_uri)
request.set_form_data(params)
obj = Net::HTTP.new(url.host, url.port)
obj.read_timeout = my_timeout_setting
response = obj.start { |http| http.request(request) }
case response
when Net::HTTPOK
send_data(response.body, :filename => my_chosen_filename, :type => "application/pdf", :disposition => "inline")
else
raise "failed to generate report"
end
I don't know anything about jasper, but it sounds like you want to do two things: render a PDF template and then send the raw output back w/ a PDF mime type:
pdf_contents = render_to_string(:template => 'users/report')
send_data(pdf_contents, :file_name => 'report.pdf', :type => 'application/pdf')
You're passing in the external URL as the template path, but that's probably wrong if you're getting errors about the template path. Fix the template path first.
Use savon to interact with jaserserver in rails3.
Here is an example:
require 'logger'
require 'savon'
logger = Logger.new(STDOUT)
logger.info "Test jasper via Savon-SOAP"
#client = Savon::Client.new {
wsdl.document = "http://localhost:8080/jasperserver/services/repository?wsdl"
http.auth.basic "jasperadmin", "jasperadmin"
}
logger.info "runReport method"
begin
result = #client.request :run_report do
soap.body = "<requestXmlString>
<![CDATA[
<request operationName='runReport' >
<argument name='RUN_OUTPUT_FORMAT'>PDF</argument>
<resourceDescriptor name='' wsType='' uriString='/reports/samples/AllAccounts' isNew='false'>
<label></label>
</resourceDescriptor>
</request>
]]>
</requestXmlString>"
end
send_data result.http.raw_body, :type => 'application/pdf', :filename => 'report.pdf', :disposition => 'attachment'
rescue Exception => e
logger.error "SOAP Error: #{e}"
end
Try to change the render_to_string() code to this:
#customers.to_xml
Related
I am trying to call a SOAP api using Savon gem. I am getting the following error: "(pre:svcFault) Service Fault"
I created both the header and message for the request.
Here is the request sent from SoapUI: SoapUI request.
i am getting a true response from SoapUI.
My code is shown below:
class SoapApi
require 'savon'
def self.initialize
header = {
"ebmCID" => "9366498d-bc79-4fad-be2b-fa1a0e84241a",
"ebmMID" => "9366498d-bc79-4fad-be2b-fa1a0e84241a",
"ebmRTID" => "9366498d-bc79-4fad-be2b-fa1a0e84241a",
"ebmSID" => "FMobile-FCUBS",
"ebmTimestamp" => "2019-06-10T12:27:46.1623586Z",
}
message = {
customerId: '00653473'
}
client = Savon.client(
:wsdl => "https://192.168.176.103:8012/tevs/pp.pm.evs.Customer_1.2?wsdl",
:ssl_verify_mode => :none
)
response = client.call(
:get_account_list,
:soap_header => header,
:message => message
)
return response
end
end
And here i am calling the above method:
#index.html.erb
<%=
SoapApi.initialize
puts #response
%>
Where you able to create a valid call using SoapUI (https://www.soapui.org.)? Try this first and make it work.
Next create a call from a plain ruby script - without Rails - which sends the same functional XML as you did in SoapUI before.
Third embed this code into your RoR application.
You can put the following in your client definition for better logging:
client = Savon.client(
:wsdl => "https://192.168.176.103:8012/tevs/pp.pm.evs.Customer_1.2?wsdl",
:ssl_verify_mode => :none,
log: true,
log_level: :debug,
pretty_print_xml: true
)
Compare the output with your working SoapUI example.
My Rails 3.1 app makes a web service call to get a pdf file that I then need to send to the browser for download.
The XML response is something like this:
<RenderResponse>
<Result>blahblah this is the file info<Result>
<Extension>PDF</Extension>
<MimeType>application/pdf</MimeType>
</RenderResponse>
I am then trying to convert the "Result" tag to a file as so:
#report = #results[:render_response][:result]
#report_name = MyReport.pdf
File.open(#report_name, "w+") do |f|
f.puts #report
end
finally I try to send to the browser:
send_file File.read(#report_name), :filename => #report_name, :type => "application/pdf; charset=utf-8", :disposition => "attachment"
This yields an error the says "Cannot Read File" and it spits out all the text from the results tag.
If I use send_data as so:
send_data File.read(#report_name).force_encoding('BINARY'), :filename => #report_name, :type => "application/pdf; charset=utf-8", :disposition => "attachment"
The download works but I get a file with 0KB and an Adobe Error that says the file "MyReport.pdf" can't be opened because "its either not a supported file type or it has been damaged".
How can I take the XML response file info, create the file, and stream to the browser?
I found the solution. send_file is the correct stream mechanism to use but I needed to decode the string while writing to the file. I also need to add the 'b' parameter to the File.open call.
This works:
File.open(#report_name, "wb+") do |f|
f.puts Base64.decode64(#report)
end
#file = File.open(#report_name, 'r')
send_file #file, :filename => #report_name, :type => "application/pdf; charset=utf-8", :disposition => "attachment"
I wrote the following code.
def help_doc
pdf_filename = File.join(Rails.root, "/public/doc.pdf")
send_file(pdf_filename, :filename => "doc.pdf" :type => "application/pdf", :diposition => "inline")
end
It's working, but not as I want. I'd like to view in the browser the pdf, but it's doing download of the document.
I thought that just writing :disposition => "inline" and I could see on the browser the pdf.
Try removing the content disposition. You have a typo in your code, deposition vs disposition, and you're missing a comma after filename.
I have a servlet (java) returning a csv file. So in my controller I send a post request,
def handleCsvRequest
response = RestClient.post theUrlPathTotheServlet queryParams
end
Now how do I handle the response so that it prompts the user to download this csv file. I know you can do this via a form and hidden Iframe but i'd like to do it through rails. I am looking through fastercsv but i am not finding great examples. Many thanks.
I have tried the following:
i have tried the following
csv_string = RestClient.post url, json, :content_type => :json
csv_file = CSV.generate do |csv|
csv << [csv_string]
end
send_data csv_file, :type => 'text/csv; charset=iso-8859-1; header=present', :disposition => "attachment; filename=report.csv"
but i don't get prompt for a file download? any ideas?
Do have a look at
1> http://fastercsv.rubyforge.org/ - For Documenation
2> http://supriya-surve.blogspot.com/2010/02/using-fastercsv-to-import-data.html - As an e.g.
Use send_file or send_data to send the csv data back to the browser.
A typical example of send_data is something along the lines:
csv_data = CSV.generate do
# block to generate CSV text
end
send_data csv_data, :filename => 'your_data.csv'
A typical example of send_file is
#csv_filename ="#{RAILS_ROOT}/tmp/your_data.csv"
send_file #csv_filename, :filename => "your_data.csv"
This should work in development. If this does not work in production, and you are using an Apache server,
you have to comment out the following line in config/environments/production.rb
config.action_dispatch.x_sendfile_header = "X-Sendfile"
Hope this helps.
I have a function in a controller that takes in some specifications and generates a report on them. This function user_report is called in a view:
< %= submit_to_remote 'submit-button', "Export Report to Excel", :url => { :controller => :reports, :action => :user_report, :print_state => 'print'} % >
In reports_controller I use the Spreadsheet plugin to generate an Excel file within the user_report function. I want to use send_data to stream the file to the user without creating it on the server first. The research I've done shows that using StringIO is the way to go, as shown below. Frustratingly, nothing happens when I call send_data. The plugin seems to work well creating a file and saving it on the server, but does nothing when I use send_file, suggesting that the problem doesn't lie in the plugin. But then what am I doing wrong with send_file/send_data?
The function itself looks like this:
def user_report
if request.post?
unless params[:reports][:userid].blank?
#userid=params[:reports][:userid]
end
if params[:print_state]=='print'
report = Spreadsheet::Workbook.new
info = report.create_worksheet :name => 'User Information'
info.row(1).push 'User ID', #userid
#outfile = "Report_for_#{#userid}.xls"
require 'stringio'
data = StringIO.new ''
report.write data
send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => #outfile
end
respond_to do |format|
format.js { }
end
end
end
The log file reads
2010-10-18 14:13:59 INFO -- Sending data Report_for_jjohnson.xls
but no download begins in-browser. I've succeed in using send_data on this app before, which is confusing.
I'm using Rails v2.3, Ruby v1.8.7, and Spreadsheet v6.4.1 at spreadsheet.rubyforge.org.
Just change the line:
send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => #outfile
to:
send_data data.string.bytes.to_a.pack("C*"), :type=>"application/excel", :disposition=>'attachment', :filename => #outfile
Even though I dont like to write and delete , but with spreadsheet seems like the only solution.
# write the file
book.write "Employee_History_#{ params[:id]}.xls"
# send the file
send_file "Employee_History_#{ params[:id]}.xls", :type => "application/vnd.ms-excel", :filename => "data.xls", :stream => false
# and then delete the file
File.delete("Employee_History_#{ params[:id]}.xls")
For someone looking at this in (or after) 2022, a possible solution to this would be to use Axlsx Gem. The interface provides a method for converting it to a StringIO object. (From Axlsx Documentation)
#serialize to a file
p = Axlsx::Package.new
# ......add cool stuff to your workbook......
# Serialize to a stream
s = p.to_stream()
send_data(
s.read,
:type => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
:disposition => 'attachment',
:filename => #filename
)