Skeeve has asked for the wisdom of the Perl Monks concerning the following question:

Solution and root cause found

This is what I just wrote in my pull request for Dancer on github:

I had a hard time trying to find why my Excel files of Content-type

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

(taken from http://blogs.msdn.com/b/vsofficedeveloper/archive/2008/05/08/office-2007-open-xml-mime-types.aspx )

were all corrupt.

Turns out Dancer thinks they are XML (they are zipped XML) because there is "xml" in the content-type.

A quick check on the net made me believe that real xml mime types have the string "xml" as seperate words (maybe with a "+" before it), so I think word boundaries would be good here.

At least they fixed my problem.

So the solution for me was, to change in Dancer/Handler.pm the "_is_text" sub:

sub _is_text { my ($content_type) = @_; - return $content_type =~ /(x(?:ht)?ml|text|json|javascript)/; + return $content_type =~ /(\bx(?:ht)?ml\b|text|json|javascript)/; }

Thanks to all who looked at my issue.


Next Update! No! It is NOT solved :( I made a mistake and was simply sending from a file in the filesystem because I forgot to reactivate my \$buffer.

I already asked aboout this in Dancer and Excel::Writer::XLSX incompatibility? and thought I found the solution, but obviously I did not.

Update: choroba gave the correct hint. I inserted the solution in the code below. So the following text just describes my previous problem and is no longer true.

Unfortunately I still can't give real test code, but here is the code I used to verify the problem that I see:

my $buffer; open my $fh, '>', \$buffer; #binmode($fh); <- does not seem to make a difference ############################## # Stop here... # I *THOUGHT* it did not make # a difference, but in fact # it will, if done correct. # So the next line of code # is the solution # binmode($fh, ':raw'); # <- Next update: No! It did NOT help. ############################## my $workbook = Excel::Writer::XLSX->new($fh); my $worksheet = $workbook->add_worksheet(); my $sth= database('mydb')->prepare($select); $sth->execute( @{$query_data->{'params'}} ); excel_results( $worksheet, $sth ); # <- Here I write some data $workbook->close(); close($fh); # Now I write out the buffer to the filesystem open my $x, '>', 'direct.xsl'; binmode $x; print $x $buffer; close $x; # And here I send the file to the browser return send_file( \$buffer, content_type => 'application/vnd.openxmlformats-officedocument.spr +eadsheetml.sheet', #content_type => 'application/vnd.ms-excel', filename => 'xxx.xls', );

When I open the downloaded file I get corrupt data. Except if I use the other content type shown above. Then I will get a warning and the file opens.

When I open the file written directly to the filesystem, there is no problem at all.

The files differ in size. The downloaded one is almost double the size.

I, again, have no idea what's going on :(

Additionally: If I send_file the directly written one, I get correct data in my download.


s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
+.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e

Replies are listed 'Best First'.
Re: Dancer and Excel::Writer::XLSX incompatibility!
by choroba (Cardinal) on Jan 28, 2014 at 16:24 UTC
    Double in size? Sounds like UTF-8. Try setting binmode to ':raw' also.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      I'm already trying to find out, where to set that :( It's not on my $fh, it must be somewhere for the standard file used by Dancer for sending stuff.

      You are my HERO!

      I couldn't believe it but tried it nonetheless and the download worked.

      I owe you a beer!

      As stated above: I made a mistake in my test and forgot to reactivate the "\$buffer" in the send_file and so I still sent a file from the filesystem.


      s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
      +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e

        It would be nice if you would reply and show exactly how you fixed the code. Perhaps save the next person from "trying to find out". Thanks!

        - tye