Grape: Corrupted stream output for xlsx files

Created on 28 Sep 2013  ·  6Comments  ·  Source: ruby-grape/grape

Hi,

Im using the axlsx gem to create an xlsx file. The generation of the file works fine, but when I try to stream from the Grape API, the file is corrupted. Both from either method:

axlsx_package.serialize('simple.xlsx')

# send the file directly as stream
return File.open('simple.xlsx')

# or stream from the gem
return axlsx_package.to_stream.read

Any ideas what is causing this? The grape API is mounted within a Rails app.

bug?

Most helpful comment

You need a proper content-type and either a pass-through or some more specific formatter. Like this:

require 'axlsx'

module Acme
  class AxlsxBuild < Grape::API
    content_type :xlsx, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    format :xlsx
    formatter :xlsx, lambda { |object, env| object.to_stream.read }

    desc "Axlsx."
    get "axlsx" do
      header['Content-Disposition'] = "attachment; filename=report.xlsx"
      content_type 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      p = ::Axlsx::Package.new
      p.workbook.add_worksheet(:name => 'Test sheet') do |sheet|
        sheet.add_row ['Foobar test']
      end
      p.use_shared_strings = true
      p.serialize('simple.xlsx')
      p
    end
  end
end

All 6 comments

Define "corrupted". Are you returning the correct content-type? What data is being returned? Post a complete repro with a failing test.

Numbers.app says the following "Import Error" "An unknown error occurred."

Im setting a content-type of application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

The data being returned is something like this:

["PK\u0003\u0004\u0014\u0000\u0000\u0000\b\u0000\u0000€Ÿëc8kÔÙ\u0000\u0000\u0000A\u0002\u0000\u0000\u000B\u0000\u0000\u0000_rels/.rels­’ÁNÃ0\f†ï<EäûšnH\b¡e» ¤Ý\u0010*\u000F`\u0012·ÚÄ‘\u0013 ¼=\u0003bh\b\u000E;ZöÿýßÁÛý\u0012fõB’=G\u0003ë¦\u0005EѲóq0ðØÝ­®a¿Û>ÐŒ¥^äѧ¬j$f\u0003c)éFëlG\n","˜\u001BN\u0014ë¦g\tXê(ƒNh'\u001CHoÚöJËw\u0006\u001C3U‡2P1°Ìú•ezbžš\n",

I cannot send the complete file, but what gets me is that the file being serialized to disk is OK, but streaming that same file causes an issue.

Write something that reproduces the problem based on https://github.com/dblock/grape-on-rack

Any ideas on this issue? Something more I can do to help?
I made a failing test branch on rack here:
https://github.com/wprater/grape-on-rack/tree/corrupt-axslx

In your example format specified as :json (app/api.rb:4), try to use :txt instead.

You need a proper content-type and either a pass-through or some more specific formatter. Like this:

require 'axlsx'

module Acme
  class AxlsxBuild < Grape::API
    content_type :xlsx, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    format :xlsx
    formatter :xlsx, lambda { |object, env| object.to_stream.read }

    desc "Axlsx."
    get "axlsx" do
      header['Content-Disposition'] = "attachment; filename=report.xlsx"
      content_type 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      p = ::Axlsx::Package.new
      p.workbook.add_worksheet(:name => 'Test sheet') do |sheet|
        sheet.add_row ['Foobar test']
      end
      p.use_shared_strings = true
      p.serialize('simple.xlsx')
      p
    end
  end
end
Was this page helpful?
0 / 5 - 0 ratings