請教各位先進,我寫一個Excel匯出功能,在VS下執行的環境下是可以正常匯出Excel的
但將程式碼更新至線上的IIS運作,執行同樣的匯出功能卻直接報500(Internal Server Error),想用try catch截取錯誤訊息也截取不到,不知道先進們是否知道該如何處理此狀況呢?
try catch抓錯誤訊息都抓不到,我真不知道該怎麼找問題了,在VS下的localhost運作都是正常的,程式也沒什麼複雜的東西,但遇到這樣的錯誤還真不知道怎麼解決~
是IIS上少安裝了什麼Excel的組件嗎?還是說IIS要設定什麼才可執行?
目前這台Web Server同時也有跑其它網站是Web From,而這網站也有寫Excel匯出功能,是可正常匯出的,當然寫法跟MVC不同,不知是否是MVC的寫法問題出錯~
public ActionResult ExportPapersExcel(int ConferenceId)
{
var exportSpource = GetExportDataWithAllColumns(ConferenceId);
var dt = JsonConvert.DeserializeObject<DataTable>(exportSpource.ToString());
string ConferenceTitle = conferenceSrv.GetConferenceTitle(ConferenceId);
try
{
return new ExportExcelResult
{
SheetName = "List",
FileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx",
ExportData = dt
};
}
catch (Exception e)
{
publicSrv.AddLog(Session["MemberId"].ToString(), "ExportPapersExcel", "匯出Excel錯誤:" + e.ToString(), 0, 0);
throw;
}
}
public JArray GetExportDataWithAllColumns(int ConferenceId)
{
var query = paperSrv.GetExcelPaperList(ConferenceId);
JArray jObjects = new JArray();
foreach (var item in query)
{
var jo = new JObject
{
{"稿件編號", item.CleanTitle},
{"論文標題", item.Title},
{"投稿類別", item.TrackTitle},
{"投稿者", item.MemberName},
{"新增作者", item.AuthorsName},
{"關鍵字", item.Keyword},
{"論文發表方式", item.Award},
{"是否參選優秀論文評選", item.PresentationName},
{"稿件狀態", item.StatusName},
{"提交日期", item.SubmittedDate}
};
jObjects.Add(jo);
}
return jObjects;
}
從程式碼比較難看出問題。
正常最好是從錯誤訊息來查看。
不過你說沒辦法知道錯誤訊息。就比較難了解發生什麼事。
基本上我會先猜測看看是不是路徑或是權限的問題。
可以先試著把你的站改成debug模式。搞不好就能輸出錯誤了。
你好,依照這個問題,我會先一步步 Debug.
以下是我的做法
通常就會找出原因來了。
public ActionResult ExportPapersExcel(int ConferenceId)
{
var exportSpource = GetExportDataWithAllColumns(ConferenceId);
var dt = JsonConvert.DeserializeObject<DataTable>(exportSpource.ToString());
Response.Write("A1"); /* 這裡*/
string ConferenceTitle = conferenceSrv.GetConferenceTitle(ConferenceId);
try
{
Response.Write("A2"); /* 這裡*/
return new ExportExcelResult
{
Response.Write("A3"); /* 這裡*/
SheetName = "List",
FileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx",
ExportData = dt
Response.Write("A4"); /* 這裡*/
};
}
catch (Exception e)
{
Response.Write("E1"); /* 這裡*/
publicSrv.AddLog(Session["MemberId"].ToString(), "ExportPapersExcel", "匯出Excel錯誤:" + e.ToString(), 0, 0);
throw;
}
}
public JArray GetExportDataWithAllColumns(int ConferenceId)
{
Response.Write("C1"); /* 這裡*/
var query = paperSrv.GetExcelPaperList(ConferenceId);
Response.Write("C2"); /* 這裡*/
JArray jObjects = new JArray();
foreach (var item in query)
{
Response.Write("D1"); /* 這裡*/
var jo = new JObject
{
Response.Write("D2"); /* 這裡*/
{"稿件編號", item.CleanTitle},
{"論文標題", item.Title},
{"投稿類別", item.TrackTitle},
{"投稿者", item.MemberName},
{"新增作者", item.AuthorsName},
{"關鍵字", item.Keyword},
{"論文發表方式", item.Award},
{"是否參選優秀論文評選", item.PresentationName},
{"稿件狀態", item.StatusName},
{"提交日期", item.SubmittedDate}
};
jObjects.Add(jo);
Response.Write("D3"); /* 這裡*/
}
return jObjects;
}
依大大的方法,把每個地方都加入log:
因為是匯出功能,所以Response.Write("");好像無法有效果
我有自己寫記錄在DB的log,如下程式碼是有記錄到A2的階段都沒問題,所以發生錯誤的地方應該是在最後的
return new ExportExcelResult這個地方,但還是不知道為何在VS 的localhost可以正常執行,在IIS上就直接死掉,500錯誤!!!
ExportPapersExcel?ConferenceId=1012 500 (Internal Server Error)
public ActionResult ExportPapersExcel(int ConferenceId)
{
var exportSpource = GetExportDataWithAllColumns(ConferenceId);
var dt = JsonConvert.DeserializeObject<DataTable>(exportSpource.ToString());
publicSrv.AddLog(Session["MemberId"].ToString(), "ExportPapersExcel", "匯出Excel錯誤:A1", 0, 0);
Response.Write("A1");
try
{
Response.Write("A2");
publicSrv.AddLog(Session["MemberId"].ToString(), "ExportPapersExcel", "匯出Excel錯誤:A2", 0, 0);
return new ExportExcelResult
{
SheetName = "稿件清單",
FileName = "exportList.xlsx",
ExportData = dt
};
}
catch (Exception e)
{
Response.Write("A3");
publicSrv.AddLog(Session["MemberId"].ToString(), "ExportPapersExcel", "匯出Excel錯誤:" + e.ToString(), 0, 0);
throw;
}
}
我改用別的套件EEPLus,測試匯出的情況還是一樣,在IIS上運作就直接報錯,但在VS的環境下卻可以正常運作,實在是搞不懂問題出在那裡~
//EEPLus
public ActionResult Export(int ConferenceId)
{
//取出要匯出Excel的資料
var query = paperSrv.GetExcelPaperList(ConferenceId);
//建立Excel
ExcelPackage ep = new ExcelPackage();
//建立第一個Sheet,後方為定義Sheet的名稱
ExcelWorksheet sheet = ep.Workbook.Worksheets.Add("FirstSheet");
int col = 1; //欄:直的,因為要從第1欄開始,所以初始為1
//第1列是標題列
//標題列部分,是取得DataAnnotations中的DisplayName,這樣比較一致,
//這也可避免後期有修改欄位名稱需求,但匯出excel標題忘了改的問題發生。
//取得做法可參考最後的參考連結。
sheet.Cells[1, col++].Value = "PaperId";
//資料從第2列開始
int row = 2; //列:橫的
foreach (PaperViewModel item in query)
{
col = 1;//每換一列,欄位要從1開始
//指定Sheet的欄與列(欄名列號ex.A1,B20,在這邊都是用數字),將資料寫入
sheet.Cells[row, col++].Value = item.PaperId;
row++;
}
//因為ep.Stream是加密過的串流,故要透過SaveAs將資料寫到MemoryStream,在將MemoryStream使用FileStreamResult回傳到前端
MemoryStream fileStream = new MemoryStream();
ep.SaveAs(fileStream);
ep.Dispose();//如果這邊不下Dispose,建議此ep要用using包起來,但是要記得先將資料寫進MemoryStream在Dispose。
fileStream.Position = 0;//不重新將位置設為0,excel開啟後會出現錯誤
return File(fileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "ExportRanger.xlsx");
}
你好,也有可能是 IIS 的設定問題,
請試看看:
iis 檔案權限 寫入
如果站台有”特別指定應用程式集區”,
則網站資料夾的安全性要指定 “IIS AppPool\站台的應用程式集區” 可以寫入
如果站台沒有指定,是用預設的DefaultAppPool
則網站資料夾的安全性要指定 “IIS_IUSRS” 可以寫入
(因為IIS_IUSRS群組已經包括DefaultAppPool帳戶)
感謝各方先進提供建議,問題己找到~如上所述~謝謝~
麻煩你給出最佳答案吧。