caxlsx / caxlsx_rails

A Rails plugin to provide templates for the axlsx gem
MIT License
742 stars 84 forks source link

Export Invalid .xlsx file in Api only mode #107

Closed NickBeukema closed 4 years ago

NickBeukema commented 6 years ago

I have created a base repo: https://github.com/NickBeukema/axlsx_rails_testing

For both regular and api only mode, for both have done the following

I visit the url and the api only version exports the file as 1 byte and cannot be opened, while the non api only version exports the excel file normally.

To reproduce the two repos, do the following:

  1. Clone and bundle
  2. rails db:migrate db:seed
  3. rails s
  4. Visit localhost:3000/leads.xlsx

I've also added a json responder to assure that the data is there and the respond_to function is working, so you can visit localhost:3000/leads.json to see the json data.

Do you know what dependencies I'm missing in the api only version? I've already included ActionController::MimeResponds to allow for respond_to usage. Any help would be great!

straydogstudio commented 6 years ago

Thanks! I'll take a look. I don't remember the differences off the top of my head.

straydogstudio commented 6 years ago

@NickBeukema I've spent some time looking at this and found the axlsx_rails template handler is not being called by the api even though the renderer is. I'll have to spend more time when I can digging into Rails itself to find the error. Have you tried this with rails 5.1 or earlier?

straydogstudio commented 6 years ago

Also I notice the api is rails 5.1.4 and the regular is 5.2.1. Did you just create a generic api?

fresh2nd commented 6 years ago

Same issue here. Do you know what we need to add? I am using rails 5.1.6 and created it in API Mode

NickBeukema commented 6 years ago

For now I just made my application_controller.rb class inherit from ActionController::Base instead of ActionController::API.

From

class ApplicationController < ActionController::API
...

to

class ApplicationController < ActionController::Base
...
straydogstudio commented 6 years ago

I’ve spent a few hours in this. Hopefully I will get some more time this week. It is deep in the inheritance tree.

straydogstudio commented 6 years ago

@NickBeukema @fresh2nd As I expected, Rails in API mode does not include the template loading mechanism. This is by design of course, since api does not include ActionView. See the difference in render_to_body between action_view/rendering.rb and action_controller/api/api_rendering.rb.

I would do one of two things:

If either of you do so, consider adding a pull request for the README. Or drop it here. I will do it at some point.

DonaldChiang commented 5 years ago

Based on this issue: https://github.com/rails/rails/issues/27211 Override render_to_body method in your API mode controller

class TestController < ActionController::API
  include ActionView::Rendering

  def show
    respond_to do |format|
      format.xlsx
    end
  end

  private

  def render_to_body(options)
    _render_to_body_with_renderer(options) || super
  end
end

And now you can export correct xlsx file, but still need better solution here.

straydogstudio commented 4 years ago

@DonaldChiang Did you ever find a better solution? What kind of solution were you imagining?

straydogstudio commented 4 years ago

Closing after adding this to the readme.

straydogstudio commented 4 years ago

There is another possibility. If you only have a Rails API, you really don't need to organize the code in templates. Instead consider using service classes to organize your code. Or something similar.