I'm looking to extract all records to a single pdf using Prawn PDF and rails 4.2.
Currently I have them generating by id for individual pdf's and works well.
Show
def show
#agreement = Agreement.find(params[:id])
respond_to do |format|
format.html
format.pdf do
pdf = AgreementPdf.new(#agreement)
send_data pdf.render, filename: "Agreement - #{#agreement.entity}", type: "application/pdf", disposition: "inline"
end
end
end
Index in table
<% #agreements.each do |agreement| %>
<tr>
<td><%= agreement.entity %></td>
<td><%= link_to 'Download', agreement_path(agreement.id, format: 'pdf'), :target => "_blank" %></td>
</tr>
<% end %>
First, you have to add a route with the path of the new method:
get '/agreements/all_records' => 'agreements#all_records', :as => :agreement_all_records
Then call the methods with in the view:
<td><%= link_to 'Download All Records', agreement_all_records_path(), :target => "_blank" %></td>
It will look something like this in the controllers:
def all_records
#agreements = Agreement.all
pdf = AgreementsPdf.new(#agreements)
send_data pdf.render,filename:'agreements.pdf',type:'application/pdf', disposition: 'inline'
end
And the Report may look like this ( assuming that agreement model has id,name fields ):
require 'prawn/table'
class AgreementsPdf < PdfReport
TABLE_WIDTHS = [100, 100]
PAGE_MARGIN = [40, 40, 40, 40]
def initialize(agreements=[])
super(:page_size => "LEGAL", margin: PAGE_MARGIN, :page_layout => :landscape)
#agreements = agreements
display_table
end
private
def display_table
if table_data.empty?
text "None data"
else
table(table_data,column_widths: TABLE_WIDTHS, :cell_style => { size: 10 } )
end
end
def table_data
#table_data ||= #agreements.map { |e| [e.id, e.name] }
end
end
Hope this will give you an idea
Related
Hello everybody who likes RAILS, i have a problem i'm trying to export by "ejecutive_id" to XLS but i'm not doing the correct code,
-I created a select box where i can select all my ejecutives.
-I created another select box where i can select by status_id.
-I selected 1 ejecutive for example "Mogan" (ejecutive_id = 1)
-I selected 1 status form example "active" (status_id = 0 )
-After selecting both select boxes i click on "SEARCH"
-After doing SEARCH i'm getting my results (#list_policies this value in my code is before respond format)
Here is my controller
****PROJECT/APP/CONTROLLER/policy_managment/policy.rb********
class PolicyManagement::PolicyController < ApplicationController
def generate_print_ejecutive_comercial
#search_ejecutive = params[:search_ejecutive]
#search_status = params[:status_id]
#list_ejecutives_comision = Ejecutive.find(:all)
#list_policies_search = Policy.deleted_is(0)
if params[:search_ejecutive].to_i!=0
#list_policies_search = #list_policies_search.ejecutive_id_is(#search_ejecutive)
end
if !params[:status_id].blank?
if params[:status_id].to_i != 3
#list_policies_search = #list_policies_search.state_is(params[:status_id])
end
else
#list_policies_search = #list_policies_search.state_is(0)
end
#status_id = params[:status_id]
if !#search_dependent_dni.blank?
if #list_dependents.blank?
#list_dependents = Dependent.id_gt(0)
end
#list_dependents = #list_dependents.num_document_is(#search_dependent_dni)
list_dependencies = []
#list_dependents.each do |dependent|
list_dependency_dependents = Dependency.find(:all, :conditions => { :dependent_id => dependent.id })
list_dependency_dependents.each do |dependency|
list_dependencies << dependency
end
end
policy_ids = []
list_dependencies.each do |dependency|
policy_ids << dependency.policy_id.to_i
end
end
#list_policies_search = #list_policies_search.deleted_is(0)
#list_policies = #list_policies_search.paginate(:page => params[:page], :per_page => 10)
#results = #list_policies_search.find(:all,:conditions=> { :ejecutive_id => #search_ejecutive })
respond_to do |format|
format.html
format.xls
format.js {
render :update do |page|
page.replace_html 'table', :partial => 'table2'
end
}
end
end
end
Here maybe could be the problem,also those are my links where i can export
*********HERE IS MY VIEW***********
<% form_remote_tag :url=>{:action=>"generate_print_ejecutive_comercial"},:before=>"load_close('loading_search')",:success=>"load_off('loading_search')" do -%>
<label>EJECUTIVES:</label>
<%= select_tag 'search_ejecutive',"<option value=\"\">Select</option>"+options_for_select(#list_ejecutives_comision.collect {|t| [t.name.to_s+" "+t.lastname1.to_s,t.id]})%>
</span>
<label>STATUS :</label>
<%= select_tag "status_id","<option value=\"3\">ALL</option>"+options_for_select([["active",0],["cancel",1],["no cancel ",2]],0) %>
</span>
<input name="Buscar" value="SEARCH" type="submit" /><span id="loading_search"></span>
<% end %>
#HERE WITH THOSE LINKS I'M EXPORTING ONLY MY FIRST 10 VALUES
<%= link_to("Export Excel","http://localhost:3000/policy_management/policy/generate_print_ejecutive/generate_print_ejecutive_comercial.xls")%>
<%= link_to "Export XLS",:controller=>"policy_management/policy",:action=>"generate_print_ejecutive_comercial",:format=>"xls" %>
<%= link_to 'PRINT PDF', :controller=>"policy_management/policy",:action=>"generate_print_ejecutive_comercial", :format=>"pdf" %>
I'm exporting my partial view and it depends of this
#list_policies = #list_policies_search.paginate(:page => params[:page], :per_page => 10)
Here is my partial view and i'm using #list_policies
********************PARTIAL VIEW THAT I WANT TO EXPORT*********
<table>
<% #list_policies.each do |policy| %>
<tr>
<td><div class="nobreak"><%= policy.num_policy%></div></td>
<td><div class="nobreak">
<% if !policy.ejecutive.blank? %>
<%= policy.ejecutive.name %><%= policy.ejecutive.lastname1 %><%= policy.ejecutive.lastname2 %>
<% end %></div>
</td>
<td><div class="nobreak"><%= policy.str_state%></div></td>
</tr>
</table>
Seems that i need to add some params to my links_to....format.... i don't know what to add
Somebody can check this code?
It seems like using an options hash to dynamically build your query might be easier / cleaner. I would do it like this:
class PolicyManagement::PolicyController < ApplicationController
def generate_print_ejecutive_comercial
#list_ejecutives_comision = Ejecutive.find(:all)
policy_options = {:deleted => false}
policy_options = policy_options.merge({:ejecutive_id => params[:search_ejecutive]}) unless params[:search_ejecutive].blank?
policy_options = policy_options.merge({:state => params[:status_id]}) unless params[:status_id].blank? and (params[:status_id] != 3)
#list_policies_search = Policy.all(policy_options)
if !#search_dependent_dni.blank?
if #list_dependents.blank?
#list_dependents = Dependent.id_gt(0)
end
#list_dependents = #list_dependents.num_document_is(#search_dependent_dni)
list_dependencies = []
#list_dependents.each do |dependent|
list_dependency_dependents = Dependency.find(:all, :conditions => { :dependent_id => dependent.id })
list_dependency_dependents.each do |dependency|
list_dependencies << dependency
end
end
policy_ids = []
list_dependencies.each do |dependency|
policy_ids << dependency.policy_id.to_i
end
end
#list_policies = #list_policies_search.paginate(:page => params[:page], :per_page => 10)
respond_to do |format|
format.html
format.xls
format.js {
render :update do |page|
page.replace_html 'table', :partial => 'table2'
end
}
end
end
end
How to redirect the two links to two urls by using single method in controller?
Example:
def index
#location_id = Location.find(#location_id)
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
if # PDF EPC link clicked
#epc.current_epc_path[-4..-1] == '.pdf'
content = open(#epc.current_epc_path, "rb") {|io| io.read }
send_data content, :filename => 'epc.pdf', :disposition => 'inline'
end
if # LIVE EPC link clicked
#epc = Enr::Rds::XmlData.find_by_location_id(#location_id)
redirect_to #epc.report_url
end
end
in my view,
<%= link_to 'PDF', enr_location_current_epc_index_path(#location) %>
<%= link_to 'LIVE', enr_location_current_epc_index_path(#location) %>
in my routes
resources :current_epc, only: [:index, :show] do
get :download, :on => :collection
end
I would consider create 2 differente actions. One for each case. It would make your actions and your code much easier to read.
Then u would result with 3 actions. Index which would only load the initial objects, one to treat the specific id by the first logic and another link to treat the second logic.
def index
#location_id = Location.find(#location_id)
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
end
pdf_epc
#location_id = Location.find(#location_id)
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
#epc.current_epc_path[-4..-1] == '.pdf'
content = open(#epc.current_epc_path, "rb") {|io| io.read }
send_data content, :filename => 'epc.pdf', :disposition => 'inline'
end
def live_epc
#epc = Enr::Rds::XmlData.find_by_location_id(#location_id)
redirect_to #epc.report_url
end
in your routes
resources :current_epc, only: [:index, :show] do
get :download, :on => :collection
end
get "/pdf_epc/:id" => "current_epc#pdf_epc", :as => enr_location_current_epc_pdf
get "/live_epc/:id" => "current_epc#live_epc", :as => enr_location_current_live_epc
in your view
<%= link_to 'PDF', enr_location_current_epc_pdf_path(#location) %>
<%= link_to 'LIVE', enr_location_current_live_epc_path(#location) %>
def pdf_url
if (params[:url] == 1)
do something
else
do something else
end
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
if #epc != nil
#epc.current_epc_path[-4..-1] == '.pdf'
content = open(#epc.current_epc_path, "rb") {|io| io.read }
send_data content, :filename => 'epc.pdf', :disposition => 'inline'
end
end
In your routes.rb:
match "/anything/pdf_url/:url" => "anything#pdf_url"
And your two links:
<%= link_to "first", "/anything/pdf_url/1" %>
<%= link_to "second", "/anything/pdf_url/2" %>
EDIT:
member is used when it requires an :id parameter, if not it is a collection. Anyway, I would use match in that case like (which is in parenthesis is optional):
match "/anything(/download/:url)" => "anything#index"
and get the parameter in your controller like this:
def index
if params[:url] == 1 # Or whatever you put in your link_to
# redirect_to url
else
# redirect_to url
end
end
EDIT 2:
Index controller:
def index
if params[:id]
#location_id = Location.find(params[:id])
#epc = Enr::Rds::CurrentEpc.find_by_location_id(#location_id)
if params[:url] == 'pdf'
#epc.current_epc_path[-4..-1] == '.pdf'
content = open(#epc.current_epc_path, "rb") {|io| io.read }
send_data content, :filename => 'epc.pdf', :disposition => 'inline'
elsif params[:url] == 'live'
#epc = Enr::Rds::XmlData.find_by_location_id(#location_id)
redirect_to #epc.report_url
end
else
#locations = Location.all
respond_to do |format|
format.html
format.json { render :json => #locations }
end
end
end
Your routes:
match "/anything(/:id(/:url))" => "anything#index"
Your view (change links to fit your tastes, it's just a simple example):
<%= link_to "first", "/anything/1/pdf" %>
<%= link_to "second", "/anything/1/live" %>
Hello!
I have this trouble: I'm searching reports by date and in html view everything is alright, BUT when I'm rendering xls view error appear, because it didn't receive params, so I need to pass them in URL for xls link_to generator.
My controller:
def show
#website = Website.find(params[:id])
if params[:report] && params[:report][:start_date] && params[:report][:end_date]
#search_by_created_at
#performance_reports = #website.performance_reports.where("created_at between ? and ?", params[:report][:start_date].to_date, params[:report][:end_date].to_date)
else
#performance_reports = #website.performance_reports
end
respond_to do |format|
format.html # index.html.erb
format.xls
format.xml { render :xml => #performance_reports }
end
end
and my generated url looks like:
http://127.0.0.1:3000/websites/25/performance_reports/show?utf8=%E2%9C%93&report[end_date]=07%2F09%2F2012&report[start_date]=04%2F09%2F2012&commit=Run+Report
mine xls url is generated like this:
<%= link_to url_for(:format => 'xls') do%>
<%= image_tag("excel.png", :id => "analytics",:size => '21x23')%> <b>Export</b>
<% end %>
result:
http://127.0.0.1:3000/websites/25/performance_reports/show
Any help will be appreciated.
xls in not available by default.
Add this:
gem "spreadsheet"
gem "to_xls", :git => "https://github.com/dblock/to_xls.git", :branch => "to-xls-on-models"
Register the Excel MIME type in config/initializers/mime_types.rb by adding this:
Mime::Type.register "application/vnd.ms-excel", :xls
Add an as_xls method to model that you want to export for the fields you want.
For example for a User model you might have:
def as_xls(options = {})
{
"Id" => id.to_s,
"Name" => name,
"E-Mail" => email,
"Joined" => created_at,
"Last Signed In" => last_sign_in_at,
"Sign In Count" => sign_in_count
}
end
Add code to the controller:
def index
#users = User.all
respond_to do |format|
format.html
format.xls { send_data #users.to_xls, content_type: 'application/vnd.ms-excel', filename: 'users.xls' }
end
end
Provide a link:
= link_to 'Export', users_path(request.parameters.merge({:format => :xls}))
All code should have a test. You could do something like this:
describe "GET index.xls" do
it "creates an Excel spreadsheet with all users" do
user = Fabricate :user
get :index, :format => :xls
response.headers['Content-Type'].should == "application/vnd.ms-excel"
s = Spreadsheet.open(StringIO.new(response.body))
s.worksheets.count.should == 1
w = s.worksheet(0)
w.should_not be_nil
w.row(0)[0].should == "Id"
w.row(1)[0].should == user.id.to_s
w.row(0)[1].should == "Name"
w.row(1)[1].should == user.name
end
end
When I want to select a file via file_field, it gives me the error that my file is 'nil'. Here's the error: "No such file or directory - Book1.csv"
May I know why? Below are the codes:
controller
def import_csv
#list = List.find(params[:list_id])
#lists = List.all
respond_to do |format|
#csv_text = File.read(params[:list][:file])
#csv = CSV.parse(#csv_text, :headers => true)
#n=0
#csv.each do | row |
#user_new = User.new
#user_new.first_name = row[0]
#user_new.last_name = row[1]
#user_new.email = row[2]
#user_new.company = row[3]
#user_new.address = row[4]
#user_new.city = row[5]
#user_new.state = row[6]
#user_new.zipcode = row[7]
#user_new.country = row[8]
#user_new.notes = row[9]
#user_new.birthday = row[10]
#user_new.home_number = row[11]
#user_new.mobile_number = row[12]
#user_new.list_id = #list.id
#user_new.save
#list.subscribers += 1
#list.save
#n=#n+1
GC.start if #n%50==0
flash[:notice] = "CSV Imported Successfully, with #{#n} records"
end
format.html { redirect_to lists_url }
format.json { head :no_content }
end
end
view
<%= form_for(:list, :url => list_import_csv_path(#list), :method => :get, :html => {:multipart => true}) do |f| %>
<table>
<tr>
<td><label for="dump_file">Select a CSV File :</label></td>
<td><%= f.file_field :file %></td>
</tr>
<tr>
<td colspan='2'><%= submit_tag 'Import from CSV file' %></td>
</tr>
</table>
<% end %>
This is because you try to pass the ActionDispatch::Http::UploadedFile Object as a path instead of the real path. You do:
#csv_text = File.read(params[:list][:file])
you should do:
#csv_text = File.read(params[:list][:file].tempfile.to_path.to_s)
Also it might be a problem that you use :method => :get when you upload not so tiny files. Genereally GET and File Upload arent such a great combination.^^
6/27/2017 - Hopefully someone will benefit from this if they are in the same situation I was.
It turns out, whereas I had:
= form_tag action: :bulk_upload_submit, multipart: true do
...
= file_field_tag :file, accept: 'text/csv'
and it was sending the file params as:
"file"=>"subscribers.csv"
I needed to change the form_tag to use a path instead of an action:
= form_tag upload_subscribers_path, multipart: true do
which changed the params to:
"file"=>
#<ActionDispatch::Http::UploadedFile:0x007ffda857b5e0
#content_type="text/csv",
#headers="Content-Disposition: form-data; name=\"file\"; filename=\"subscribers.csv\"\r\nContent-Type: text/csv\r\n",
#original_filename="subscribers.csv",
#tempfile=#<File:/var/folders/_4/50fjk9z57x544klj30k0g1780000gn/T/RackMultipart20170627-33947-12xwfow.csv>>
I have a view which contain multiple links:
<% a.each do |q| %>
<%= link_to "stock it",
{ :action => "stock",
:qid => q.question_id,
:qur => q.question_answers_url,
:qti => q.title } ,
:remote => true %>
<div id="<%= "stock" + q.question_id.to_s %>"></div>
<% end %>
Each link generate AJAX-request. Here is a controller:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
respond_to do |format|
format.js { render :layout=>false }
end
end
Now return to the view. Each link has a 'div' with unique id='stock'. When user press the link I need to add text to specific div with corresponding id.
I have a stock.js.erb file:
$("#stock<number>").html("some text");
How can I pass div-id to stock.js.erb and how can I use it ?
Common use is to add object.id to your DOM id. That what you exactly did:
<div id="<%= "stock_#{q.question_id}" %>"></div>
Then in your controller you shoud define your question_id or your exact question:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
#question_id = params[:qid]
end
Now it will be shared with your stock.js.erb file:
$("#stock_<%= #question_id %>").html("some text");