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.
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
Most helpful comment
You need a proper content-type and either a pass-through or some more specific formatter. Like this: