My workbook always named like my template "invoices_generate.xlsx".
How can i rename this File ?
Template "invoices_generate.xlsx.axlsx" :
wb = xlsx_package.workbook
wb.add_worksheet(:name => "Beleg") do |sheet|
.
.
.
sheet.column_widths 2 , 11, 11, 11, 11, 23, 3
end
Do you have the axlsx_rails gem added as well? If so:
wb = xlsx_package.workbook
wb.add_worksheet(name: "Beleg") do |sheet|
sheet.column_widths 2 , 11, 11, 11, 11, 23, 3
end
See https://github.com/straydogstudio/axlsx_rails#template for more details and if that doesn't work try setting the filename from the controller action rendering the xlsx template as described here: https://github.com/straydogstudio/axlsx_rails#file-name
For future references: In the controller, on the function where generate the workbook
def index
#users = User.all
render xlsx: 'export', filename: 'my_new_filename.xlsx' //Render with export and naming the file
respond_to do |format|
format.html
format.xlsx
end
end
Related
I'm using rails 4.2, and using gems axlsx and axlsx_rails
I'm going to move to rails 5 soon but for now I use this version.
What I want: Export xlsx file from a query using axls_rails gem
What I get instead: it export the whole html file as data instead, see picture:
I followed 3 different guides as the git documentation exactly and already debugged it several times and didn't find the problem. Hope someone here can help me understand what causing it.
Gemfile:
gem 'rails', '4.2.11'
# import/export xlsx gems
gem 'write_xlsx'
gem 'rubyzip', '>= 1.2.1'
gem 'axlsx', git: 'https://github.com/randym/axlsx.git', ref: 'c8ac844'
gem 'axlsx_rails'
html file:
= link_to "<i class='icon icon-file-down'></i> Export</a></li>".html_safe, server_report_system_reports_path(format: :xlsx)
controller file:
def server_report
organization_id = params[:organization_id]
#accounts = Admin::Account.where("organization_id = ?", organization_id) unless organization_id.blank?
#accounts_paginated = #accounts.paginate(per_page: 10, page: params[:page] || 1 )
respond_to do |format|
format.html
format.xlsx {
response.headers['Content-Disposition'] = 'attachment; filename="server_report.xlsx"'
}
end
end
xlsx.axlsx file:
wb = xlsx_package.workbook
wb.add_worksheet(name: "Accounts") do |sheet|
sheet.add_row ["Account id", "Member id", "Member name", "Member email"]
#accounts_paginated.each do |account|
account.members.each do |member|
sheet.add_row [account.id, member.id, member.name, member.email]
end
end
end
EDIT:
I tried to call a different def called export and try to see if there's a problem with respond_to and use another query but it also did the same
I also tried to write in format.xlsx this line but still nothing changed:
EDIT 2:
I tried to render in respond_to the file instead in axlsx.xlsx file in format.xlsx but I got the same result
response.headers['Content-Disposition'] = 'attachment; filename="server_report.xlsx"'
I found the problem. I added layout: false when I render the xlsx file in the controller and it worked
In rails 4, I am using wicked_pdf gem for .pdf file download. I have to add an image inside this pdf, right now image is rendering through wicked_pdf_image_tag in development but in test environment image(s3) is not rendering.
Used Gems are,
gem 'wicked_pdf', '1.0.3'
gem 'wkhtmltopdf-binary', '0.9.9.3'
In initializers,
class WickedPdf
wkhtmltopdf_path = Rails.env.production? ? "#{Rails.root}/bin/wkhtmltopdf-amd64" : "#{Rails.root}/bin/wkhtmltopdf-amd64"
WICKED_PDF = {
:exe_path => wkhtmltopdf_path,
:wkhtmltopdf => wkhtmltopdf_path
}
end
In controller,
respond_to do |format|
format.html {
render :pdf => "sample",
:margin => {:top => 10, :bottom => 10, :left => 10, :right => 10},
:orientation => 'Portrait', # default , Landscape,
:no_background => true
}
end
In views, I have tried to load through
<%= Rails.env.development? ? wicked_pdf_image_tag("img/logo.png") : wicked_pdf_image_tag("#{Rails.root}/public/assets/img/logo.png") %>
<%= Rails.env.development? ? wicked_pdf_image_tag("img/logo.png") : wicked_pdf_image_tag("#{Rails.root}/assets/img/logo.png") %>
<%= image_tag(ActionController::Base.helpers.asset_path('img/logo.png')) %>
How can I load s3 image in pdf file?
You can put the image in a s3 bucket and make it public. After that try it like below. If you use the below code no need to use separate syntax for different environments, it will works for all .Hope it works.
<%= wicked_pdf_image_tag('//s3.amazonaws.com/bucket_name/image.png') %>
I have worked on the similar functionality but using PDFKit gem. But I think rendering logic will be almost similar.
Below is the code where I rendered my partial in controller
def print_batch
batch = Batch.find(params[:id])
respond_to do |format|
format.pdf {
html = render_to_string("_batch",:formats => [:html], layout: false , locals: { batch: batch })
Rails.logger.debug(html.inspect)
kit = PDFKit.new(html)
send_data(kit.to_pdf, :filename => "file_name_#{batch.id}.pdf", :type => 'application/pdf') and return
}
format.html
format.json { render json: {id: batch.id, processed: batch.processed?} }
end
end
In _batch.html.haml. You can see I have used person.s3_logo for rendering the pdf image.
- logo_image_pdf = person.logo.present? ? person.s3_logo : default_credit_logo
- logo_image_html = person.logo.present? ? image_path(Person.logo.thumb('100x100').url) : image_path('default_credit_logo.png')
- logo_image = params[:format] == 'pdf' ? logo_image_pdf : logo_image_html
.bucks
%img.logo{src: logo_image }
In Person.rb model. Anyway we cannot directly render image in PDF file directly from s3. So any gem will first download it in /tmp folder and render it. This is how I have done it in my model file.
def s3_logo
file = open(self.logo.remote_url)
file.path if file
end
I have a Rails 3 app that uses these gems:
gem 'paperclip'
gem 'wicked_pdf'
gem 'combine_pdf'
I'm using wicked_pdf to open a pdf for a costproject. The costproject has an HTML page called viewproject.pdf.erb.
I'm trying to combine the wicked pdf with the costproject attachments into a single pdf.
This is my controller code:
def viewproject
#costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf = CombinePDF.new
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
pdf << CombinePDF.new(pdf2)
#costproject.attachments.each do |attachment|
pdf << CombinePDF.new(attachment.attach.path)
end
send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf"
end
end
end
The line pdf << CombinePDF.new(pdf2) is giving me:
string contains null byte
If I look at pdf2, it starts like this - so it looks like a pdf:
>> pdf2
=> "%PDF-1.4\n1 0 obj\n<<\n/Title (\xFE\xFF)\n/Producer (wkhtmltopdf)\n/CreationDate (D:20150405202628)\n>>\nendobj\n4 0 obj\n<<\n/Type /ExtGState\n/SA true\n/SM 0.02\n/ca 1.0\n/CA 1.0\n/AIS false\n/SMask /None>>\nendobj\n5 0 obj\n[/Pattern /DeviceRGB]\nendobj\n8 0 obj\n<<\n/Type /XObject\n/Subtype /Image\n/Width 71\n/Height 75\n/BitsPerComponent 8\n/ColorSpace /DeviceRGB\n/Length 9 0 R\n/Filter
I also tried pdf << CombinePDF.new(pdf2.to_pdf)
Thanks for the help!
UPDATE1
As a test, to see if pdf2 is working, I did this successfully:
def viewproject
#costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
send_data pdf2, :disposition => 'inline', :type => "application/pdf"
end
end
end
UPDATE2
Myst was correct about using parse. Thanks!
I am now using this line in the controller code:
pdf << CombinePDF.new(attachment.attach.url)
I get this error:
No such file or directory - http://s3.amazonaws.com/ ...
But, if I copy the http address and paste into the browser the pdf shows up.
I am editing this answer to reflect the issue of remotely stored PDF files.
I should point out that without a persistent connection to the S3 storage and without using the S3 API, the following solution WILL effect performance*.
As I pointed out, the CombinePDF.new method is the same as the CombinePDF.load method. It accepts a file name and attempts to open the file. The CombinePDF.parse method will accept raw PDF data and parses it into a PDF Object.
In the following code I use Net::HTTP.get(URI.parse(url)) to get the raw PDF data.
I recommend replacing this solution with a S3 native solution, so that the whole application can share one or more persistent connections. This is a performance issue that may or may not be important for you.
require 'net/http'
def viewproject
#costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf = CombinePDF.new
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
pdf << CombinePDF.parse(pdf2)
#costproject.attachments.each do |attachment|
pdf << CombinePDF.parse( Net::HTTP.get( URI.parse( attachment.attach.url ) ) )
end
send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf"
end
end
end
* The performance hit is dependent on the amount of PDF attachments you have, on the number of users your app has, on network traffic, on your framework (single/multi-thread) and other factors.
A persistent connection should reduce the performance hit in a dramatic way, mainly due to the fact that establishing connections is an expensive action.
I'm using this gem to use Prawn to create a PDF: https://github.com/Whoops/prawn-rails
However, I can't seem to figure out how to add an image. I've tried pdf.image "path/to/img.jpg but it would say the file is not a recognized format.
I've also looked into this on page 101: http://prawn.majesticseacreature.com/manual.pdf , but it doesn't work.
This is happening in the views:
prawn_document() do |pdf|
pdf.image "#{Rails.root}/public/logo.gif"
end
This throws:
Prawn::Errors::UnsupportedImageType at /admin/purchases/6188.pdf
image file is an unrecognised format
Same happens for a .jpg image
I would do something like this.
gem 'prawn'
bundle install
In your controller.
def controller_method
pdf = Prawn::Document.new
begin
pdf_file_path = "#{Rails.root}/public/output"
full_doc = "#{Rails.root}/public/something.png"
pdf.image full_doc
pdf.start_new_page
pdf.render_file pdf_file_path
rescue Prawn::Errors::UnsupportedImageType
flash[:notice] = "Image unsupported"
redirect_to '/handle'
end
end
Adding an image is easy enough.
def download
#document = Document.find(params[:id])
tmp_file = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
pdf = Prawn::Document.generate(tmp_file.path, :margin => 0, :page_size => "A4", :skip_page_creation => true) do |posting|
posting.start_new_page
posting.image #document.user.logo.path
send_data posting.render, :filename => "whatever.pdf", :type => "application/pdf"
end
end
Obviously #document.user.logo.path could be a literal path, that's just a Paperclip attachment in this case.
UPDATE
If it's a literal path you might need to do something like this:
require "open-uri"
def download
...
posting.image File.open("/path/to/image.jpg")
...
end
It seems the latest prawn (version 1.0.0) has changed. You'll get
undefined method `image=' for #<Prawn::Document
if you try and apply something to pdf.image.
This worked for me:
img = "#{Rails.root}/public/my_lovely_image.png"
Prawn::Document.new(background: img)
I am using Spreadsheet gem to allow users to export data with .xls format. The code I am showing is allowing users to open the file in Open Office and MS Excel for MAC, but not for Windows, which I get a "file is corrupted" error.
I have a method that do the XLS export like this:
book = Spreadsheet::Workbook.new
sheet1 = book.create_worksheet(:name => "Expired Activity")
# Title
title_format = Spreadsheet::Format.new(:size => 12, :pattern => 1, :pattern_fg_color => :blue, :align => :merge)
for i in 0..5
sheet1.row(0).set_format(i, title_format)
end
sheet1.row(0).push "Activity"
# Header row
header_format = Spreadsheet::Format.new(:size => 11, :pattern => 1, :pattern_fg_color => :yellow, :align => :merge)
index_row = sheet1.row(1)
index_row.push("Date")
index_row.push("First Name")
index_row.push("Last Name")
for i in 0..2
index_row.set_format(i, header_format)
end
# Row values
row_iterator = 2
#expired.each do |expired|
sheet1.row(row_iterator).push(expired.earnedOn, expired.firstName, expired.lastName)
row_iterator = row_iterator + 1
end
file_io = StringIO.new
book.write file_io
file_io.string
And this method is being called like this:
format.xls {#expired = current_user.recent_activity(unlimited_size,params[:start],nil);
send_data(build_excel_expired_activity, :filename => "#{Time.now.strftime('%Y-%m-%d')}_Expired_Activity.xls", :type => "application/xls", :disposition => 'attachment')
}
Any thoughts, or ideas?
You might want to have a look at the axlsx gem and its rails counterpart acts_as_xlsx. It supports full schema validation so you don't have to fight with this kind of thing.
https://www.ruby-toolbox.com/projects/axlsx