0
0

IIS の CGI でバイナリデータを返すときにハマった

Posted at

ウェブアプリケーションのサーバーサイドで Excel ブックを作成する必要があり、もともと IIS (Internet Information Services) と Ruby が動作する環境があったこともあり、rubyXL を試してみることにしました。

ひとまず、次のようなプログラムを作成してみました。

require "rubyXL"

workbook = RubyXL::Workbook.new

puts "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
puts "Content-Disposition: attachment; filename=\"filename.xlsx\""
puts

print workbook.stream.string

しかし、ブラウザーで開くとファイルはダウンロードされるものの、そのファイルは Excel で開くことができません。

いろいろ調べてみると、次のように標準出力をバイナリモードに変更する必要があるようです。

require "rubyXL"

workbook = RubyXL::Workbook.new

puts "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
puts "Content-Disposition: attachment; filename=\"filename.xlsx\""
puts

+ STDOUT.binmode
+
print workbook.stream.string

無事、空白の Excel ブックがダウンロードされるようになりました。

これは、rubyXL や Ruby であることは直接関係なく、CGI のプログラムは標準出力にデータを出力しますが、Windows の IO にはテキストモードとバイナリモードがあり、IO のひとつである標準出力にもそれらのモードがある。そして、標準はテキストモードになっているので、そのままでバイナリデータである Excel ブック(というべきか、ZIP ファイルというべきか)を出力すると壊れてしまう、と理解しています。1

いまどき CGI はあまり使われない上に、Windows 特有ということもあってか、なかなか情報がなく、たかだか 1 行ですが解決に時間が掛かりました。

環境

  • Windows Server 2022 Datacenter
  • IIS 10.0
  • RubyInstaller Ruby+Devkit 3.3.4-1 (x64)

参考

  1. テキストモードとは改行コード (\n, \r\n) を自動的に変換するモードのこと。IIS というよりは Windows の機能なので、確認はしていませんが IIS 以外のウェブサーバーでも、Windows 環境の場合は同じなのではないかと思います

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0