• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Spreadsheet::WriteExcelについて教えてください。)

Spreadsheet::WriteExcelについて教えてください。

このQ&Aのポイント
  • Windows2000 IE6.0 Perl5.005_03 Spreadsheet-WriteExcel-0.33 Parse-RecDescent-1.80
  • CGIとして実行すると「サーバーが見つかりません」となってしまいます。エクセルファイルは正常に作成はできているようです。
  • use Spreadsheet::WriteExcel;をコメントにして実行すると移動したいURLに飛ぶことができるのですが、当然ながらEXCELファイルは作成されません。どのようにしたらよいのでしょうか・・・

質問者が選んだベストアンサー

  • ベストアンサー
  • nipotan
  • ベストアンサー率59% (134/227)
回答No.1

んー。手元で確認した限りは、問題なく動作しますね。 問題点を考えると、Spreadsheet::WriteExcel から、何らかの原因でエラーが Location ヘッダが出力される前にダンプ (標準エラー出力で) されていているのかも知れません。 ちなみに、use は上に書こうが下に書こうが、コードの実行前に対象モジュールを先に実行してオブジェクトを作ります。なのでどんなに先に Location ヘッダを出していても、エラーのダンプはトラップできません。 まずは原因の解明の為に、プログラムの先頭部分に use CGI::Carp 'fatalsToBrowser'; を書いてエラー時のプラグマを宣言し、エラーをトラップしてみてください。そうすれば、エラーメッセージが出ていたらトラップできます。 CGI::Carp を使うのが野暮ったければ、Location ヘッダを出した後に use するように、 use Spreadsheet::WriteExcel; の部分を、 eval q/use Spreadsheet::WriteExcel;/; とし、use させたいステップに意図的に遅延させた上で SpreadSheet::WriteExcel を実行させるってのも手です。 その場合は、全ての出力のバッファを避けるために $| = 1; を明示的に書いてください (エラー出力する前に Location を出力させるため) ちなみに、Location でフォーカスが移った後、httpd から STDOUT が開放されないので、ずっと (処理が全部終わるまで) 読み込みになってしまうかもしれません。特に出力させる Excel ファイルが膨大なほどこの問題は発生します。fork() システムコールを実装している処理系であったら、fork() させた小プロセスで Excel ファイルを生成させ、親プロセスでは close STDOUT; すれば、ブラウザは開放されます。一般的に重い処理が続く場合にそういう方法を使います。その際に wait するのを忘れると小プロセスは zombie になってしまうので注意が必要ですが。 あと指摘すべきは、Spreadsheet::WriteExcel のバージョンが古いですね。最新は 0.39 なので、今起きている問題はもしかしたら「既知のバグ」として fix されているかもしれません。 Microsoft の nmake ユーティリティで最新版をソースからインストールされたほうがいいと思います。 (と書きながら今自分の手元の version が 0.37 だという事に気付き慌てて入れなおしました。。。)

参考URL:
http://search.cpan.org/author/JMCNAMARA/Spreadsheet-WriteExcel-0.39/
taganyan
質問者

補足

早速の回答有難うございます。 eval q/use Spreadsheet::WriteExcel;/; に変えて実行したらできました。 ところで、 print "Location: 移動したいURL\n\n"; print '<html><body>'; print '<br><br>'; print '<table align = "center">'; print '<tr>'; print '<td><font size = 5 ; color = blue>'; print "EXCEL書き出し"; print '</font></td>'; print '</tr>'; print '</table>'; print '</body></html>'; これの"Location: 移動したいURL\n\n"; 部分を '<meta http-equiv="Refresh" content="0;移動したいURL>'; に変えて上記のHTMLを表示させたいのですが、何かよい方法ございませんでしょうか?

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • nipotan
  • ベストアンサー率59% (134/227)
回答No.2

解決したなら出来れば別質問にして欲しかったのですが (ボソボソ... > ところで、 > print "Location: 移動したいURL\n\n"; > print '<html><body>'; > print '<br><br>'; > print '<table align = "center">'; > print '<tr>'; > print '<td><font size = 5 ; color = blue>'; > print "EXCEL書き出し"; > print '</font></td>'; > print '</tr>'; > print '</table>'; > print '</body></html>'; > これの"Location: 移動したいURL\n\n"; 部分を > '<meta http-equiv="Refresh" content="0;移動したいURL>'; > に変えて上記のHTMLを表示させたいのですが、何かよい方法ございませんでしょうか? 要するに、現状であれば処理が完結する前に、Location で指定したページに行ってしまっていて、要求としては、Location で飛ばさないで、処理中は「EXCEL 書き出し」と画面に表示し、書き出しが終了し次第、別の URL を表示させたい…って事ですよね? (違ってたり、完全に的外れならごめんなさい) 一般的には… a. "EXCEL 書き出し" を表示し、Refresh ヘッダ (あるいは <meta http-equiv="Refresh" ... ) を出力するだけのページを出力する CGI ("リダイレクト CGI" とする) b. Spreadsheet::WriteExcel を用いて Excel ドキュメントを生成し、生成が終わったらしかるべき HTML を表示する CGI ("Excel CGI" とする) の二つを作ります。そして… 1. まずリダイレクト CGI で必要なデータを受け取ったり受け取らなかったりして、Refresh ヘッダで Excel CGI を呼び出します。この時、データを受け渡したいなら、QUERY_STRING や PATH_INFO あるいは、セッション ID を格納した Cookie 等を利用してデータをブラウザに渡します。 例えば print 'Refresh: 0; url="excel.cgi?session_id=1234567890"'."\n\n"; print '<html><body>'; みたいにするとか。。。(ここで 1234567890 って名前のテンポラリファイルを出力して、Excel CGI で読み取るって方法が考えられます。リダイレクト後の URL 枠に QUERY_STRING が入るので、それを含めたくなければ Set-Cookie ヘッダを出して Cookie を Excel CGI が受け取るとか) 2. リダイレクト CGI から呼び出された Excel CGI では、データを受け取るなりの処理を行うことで、リダイレクト CGI を呼び出したデータを特定できるので、上記のいずれかの方法でデータを受け取り、処理を行います。 これで、1. からリダイレクトされた Excel CGI は、処理に時間がかかるために、「しかるべき HTML」を出力するまでの時間がかかります。これによって、ブラウザは「必要な応答が無いので、応答があるまで待つ」状態に入ります。その間は「EXCEL書き出し」とだけ、画面に表示されます。2. で Excel ファイルの生成が完了し次第、HTML が出力されるので、ブラウザは応答反応を受け取り、すぐさま「しかるべき HTML」を表示し始めます。 この方法で、「処理待ち」→「処理完了」のページ遷移が出来上がります。

taganyan
質問者

お礼

有難うございました。 完璧に私のほしい回答でした! 本当に助かりました。 一度締め切らずに質問して大変申し訳ありませんでした。

すると、全ての回答が全文表示されます。

関連するQ&A