トップ回答者
DataTableの内容をエクセルに保存する際にエラー発生

質問
-
こんにちは。いつもお世話になっています。
現在、C#(VS2005)でWebページを作成しています。
DBにデータが格納されており、ページ上のボタンを押下すると、
1.DBのデータをDataTableに格納
2.DataTableの内容をエクセル形式で保存
3.ファイルのダウンロードウィンドウを表示し、ページを表示しているPCに保存する
というプログラムを作成しています。
開発を行っている、PCのVS2005上では問題無く動作するのですが、
「ビルド」→「Webサイトの発行」
でサーバ上に配置し、クライアントPCでWebページを表示し、上記のボタンを押下すると
-------------------------------------------------------------------------------------------------
アプリケーションでサーバー エラーが発生しました。
オブジェクト参照がオブジェクト インスタンスに設定されていません。
説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。
例外の詳細: System.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません。
-------------------------------------------------------------------------------------------------のエラーが表示されます。
ここ、数日いろいろと調べているのですが、お手上げ状態となってしまいました。
サーバには、Office2003をインストールしてあり、「.NET プログラミング サポート」も
インストールしてあります。
エクセル保存のコードは下記サイトのコードを使用しています。
http://architect360.apricot-jp.com/500tips/excel.html
アドバイスをお願い致します。
コードを記しておきます。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;using System.Collections.Generic;
using System.Runtime.InteropServices;/// <summary>
/// ExcelIF の概要の説明です
/// </summary>
public class ExcelIF
{
public ExcelIF()
{
//
// TODO: コンストラクタ ロジックをここに追加します
//
}//エクセルシートにデータを書き出す行番号
private const int ROW_OFFSET = 2;
//(注意)Excelシートの行、列のインデックスは1から始まる
//エクセルシートにデータを書き出す列番号
private const int COLUMN_OFFSET = 1;///<summary>
/// データテーブルをエクセルファイルに出力します
/// </summary>
public bool CreateExcelFromDataTable(DataTable dt, string filePath, string sheetName)
{
//ヘッダー名称のリスト
List<string> headers = new List<string>();foreach (System.Data.DataColumn col in dt.Columns)
{
headers.Add(col.ColumnName);
}Microsoft.Office.Interop.Excel.Application xlsApplication = null;
Microsoft.Office.Interop.Excel.Workbooks xlsBooks = null;
Microsoft.Office.Interop.Excel.Workbook xlsBook = null;
Microsoft.Office.Interop.Excel.Sheets xlsSheets = null;
Microsoft.Office.Interop.Excel.Worksheet xlsSheet = null;
Microsoft.Office.Interop.Excel.Range xlsRange = null;try
{
xlsApplication = new Microsoft.Office.Interop.Excel.Application();
xlsApplication.DisplayAlerts = false;
//保存時の確認ダイアログを表示しないxlsBooks = xlsApplication.Workbooks;
xlsBook = xlsBooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
xlsSheets = xlsBook.Worksheets;//(注意)シートのインデックスは1から始まる
xlsSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlsSheets[1];
xlsSheet.Name = sheetName;for (int i = 0; i <= headers.Count - 1; i++)
{
xlsRange = (Microsoft.Office.Interop.Excel.Range)xlsSheet.Cells[1, i + 1];
xlsRange.Value2 = headers[i];
}// セルに値を設定する。
int sheetRowIndex = ROW_OFFSET;foreach (DataRow row in dt.Rows)
{
int sheetColumnIndex = COLUMN_OFFSET;foreach (DataColumn column in dt.Columns)
{
if (!row.IsNull(column))
{
xlsRange = (Microsoft.Office.Interop.Excel.Range)xlsSheet.Cells[sheetRowIndex, sheetColumnIndex];if (column.DataType.Name == "Integer" |
column.DataType.Name == "Int32" |
column.DataType.Name == "Decimal" |
column.DataType.Name == "Long" |
column.DataType.Name == "Double" |
column.DataType.Name == "Short")
{
//セルの書式を数値型に設定
xlsRange.NumberFormatLocal = "G/標準";
}
else if (column.DataType.Name == "DateTime")
{
xlsRange.NumberFormatLocal = "yyyy/m/d h:mm";
}
else
{
//セルの書式を文字列型に設定
xlsRange.NumberFormatLocal = "@";
}xlsRange.Value2 = row[column];
xlsRange.Columns.AutoFit();
ReleaseComObject((object)xlsRange);
sheetColumnIndex += 1;
}
}
sheetRowIndex += 1;
}// 保存
xlsBook.SaveAs(filePath, Microsoft.Office.Interop.Excel.XlFileFormat.xlXMLSpreadsheet, null, null, null, null, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, null, null, null, null, null);return true;
}catch (Exception ex)
{
return false;
}
finally
{
// エクセル関係のオブジェクトは必ず解放すること
ReleaseComObject((object)xlsRange);
ReleaseComObject((object)xlsSheet);
ReleaseComObject((object)xlsSheets);
xlsBook.Close(true, filePath, false);
ReleaseComObject((object)xlsBook);
ReleaseComObject((object)xlsBooks);
xlsApplication.Quit();
ReleaseComObject((object)xlsApplication);
}
}/// <summary>
/// COMオブジェクトを開放します。
/// </summary>
private static void ReleaseComObject(object target)
{
try
{
if ((target != null))
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(target);
}
}
finally
{
target = null;
}
}
}
回答
すべての返信
-
念のためにお聞きしますが、実行権限はどうなっていますか?
下記のサイトを一度ご覧ください。
ASP.NETからのExcel起動について
http://social.msdn.microsoft.com/Forums/ja-JP/vbgeneralja/thread/658f824d-7511-44ee-8fcb-84449025bc2a -
返信ありがとうございます。
お教え頂いたページの確認・設定を行いました。
--------------------------------------------------------------------------------------------------------
aspnet_wp.exeの実行ユーザ:ASPNET
web.configの<system.web>以下に<identity impersonate="true"/>を追加:状況変わらず
DCOMCNFGの[コンソールルート]→[コンポーネントサービス]→[コンピュータ]→[マイコンピュータ]→
右クリック→プロパティ→[COMセキュリティ]タブ
「アクセス許可」の「既定値の編集」でASPNETユーザを追加
「起動とアクティブ化のアクセス許可」の「既定値の編集」でASPNETユーザを追加
--------------------------------------------------------------------------------------------------------
上記の事を行いましたが、状況は変わりませんでした。
何か間違っている箇所があれば、ご指摘をお願い致します。