Rails ActionController unknown format
Asked Answered
M

4

9

I am trying to render a xlsx file. But I keep getting a 406/UnknowFormat. I have done the right setup, maybe im missing something?

Rails 4.2 app

gem 'axlsx'
gem "axlsx_rails"
gem 'zip-zip'

config/initializers/mime

Mime::Type.register "application/xlsx", :xlsx

controller

respond_to do |format|
      format.xlsx { render xlsx: "create", template: "api/reports/create" }
end

views/api/reports/create.xlsx.axlsx

wb = xlsx_package.workbook
wb.add_worksheet(name: "Reports") do |sheet|
  sheet.add_row [@report_name]
end
Marsupial answered 29/10, 2015 at 12:49 Comment(8)
try this format.xlsx { render xlsx: "create", filename: "api/reports/create.xlsx" }Faro
Nope still got Completed 406 Not Acceptable in 10038ms ActionController::UnknownFormat (ActionController::UnknownFormat): app/controllers/api/reports_controller.rb:12:in 'create'Marsupial
Try restarting your server.Faro
that was the first thing I had done lolMarsupial
Have you tried setting the name via header? github.com/straydogstudio/axlsx_rails#file-nameGuidry
Im not sure thats relevant to the issue. For some reason ActionController is not able to find the xlsx format, that would be for sneding the file or downloading it, its not even getting to that point :(Marsupial
For what it is worth, axlsx_rails defines the xlsx mime type. You shouldn't have to.Broeder
Couple of quick questions: - 1. Could you please post the view code that hits that route please. 2. why do you have axlsx and axlsx_rails in your gemfile? axlsx is a dependency of axlsx_rails, so just axlsx_rails should be sufficient if I understand what you are trying to do here.Lantha
G
8

The error you are getting doesn't mean that rails didn't find the the xlsx format: it means that it compared the list of formats you're providing (i.e. just xlsx) and compared it to the set of formats it thinks the browser is willing to accept and didn't find any overlap.

If as it appears there is only one format you want to render then you don't need to use respond_to at all - just replace the whole thing with

render xlsx: "create", template: "api/reports/create"

Rails derives what it thinks are acceptable formats from the extension on the url and the Accept header. Format negotiation is generally simply done via the extension than the Accept header - linking (or posting) to /some/path.xlsx should set the format to xlsx. You can do this by including format: 'xlsx' in the options you pass to path helpers or as part of a hash of routing options.

Giza answered 29/10, 2015 at 14:35 Comment(1)
axlsx_rails used to add xlsx to the available formats array if it was missing. This would allow you to serve xlsx even if the url didn't have the right extension. This became very troublesome with Rails 4 and it was removed. So the problem with respond_to probably comes from not having the xlsx extension in the requesting url.Broeder
H
11

For me, in Rails 4.2 I had to specify the full template filename including extension. According to the axlsx_rails docs the syntax is different in Rails 4.2. Here's what worked for me:

some_controller.rb

def create_report
  render "template_path/report.xlsx.axlsx"
end

template_path/report.xlsx.axlsx

wb = xlsx_package.workbook
wb.add_worksheet(:name => "Basic Worksheet") do |sheet|
  sheet.add_row ["First Column", "Second", "Third"]
end
Healy answered 13/11, 2015 at 15:49 Comment(1)
For Rails 4.2, I got away with just typing in the file extension ... render xlsx: 'report_evals_by_supvr.xlsx.axlsx' or render 'report_evals_by_supvr.xlsx.axlsx' worked for me.Renfro
G
8

The error you are getting doesn't mean that rails didn't find the the xlsx format: it means that it compared the list of formats you're providing (i.e. just xlsx) and compared it to the set of formats it thinks the browser is willing to accept and didn't find any overlap.

If as it appears there is only one format you want to render then you don't need to use respond_to at all - just replace the whole thing with

render xlsx: "create", template: "api/reports/create"

Rails derives what it thinks are acceptable formats from the extension on the url and the Accept header. Format negotiation is generally simply done via the extension than the Accept header - linking (or posting) to /some/path.xlsx should set the format to xlsx. You can do this by including format: 'xlsx' in the options you pass to path helpers or as part of a hash of routing options.

Giza answered 29/10, 2015 at 14:35 Comment(1)
axlsx_rails used to add xlsx to the available formats array if it was missing. This would allow you to serve xlsx even if the url didn't have the right extension. This became very troublesome with Rails 4 and it was removed. So the problem with respond_to probably comes from not having the xlsx extension in the requesting url.Broeder
R
2

Well I am really late here, and the OP has probably moved on, but for others who've happened onto this problem, a possible explanation might be forgetting to set the format in the link itself. For example, you'd need to do something like this in your view: download_file_path(format: "xlsx")

Remex answered 10/7, 2016 at 1:34 Comment(1)
This was the issue for me. Thanks.Immaterialize
C
0

If you only have format.xlsx present in your controller, then adding format.html might be the solution if you are rendering a page and your xlsx file is a link.

respond_to do |format|
  format.html
  format.xlsx { ... }
end
Celiotomy answered 22/11, 2023 at 10:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.