我有一個將Excel作爲自定義FileResult返回的操作。我的解決方案基於ClosedXml庫(內部使用OpenXml)。 我的XlsxResult類使用服務器上的只讀.xlsx文件作爲模板。然後它將模板傳遞到一個內存流中,然後使用ClosedXml進行操作並保存。最後,將內存流寫入響應。Azure上的自定義FileResult:瀏覽器永遠等待
這對卡西尼以及IIS Express都可以正常工作,但在部署在天藍色時無法正常工作,無任何錯誤。我遇到的唯一影響是發送到服務器的請求永遠不會得到任何迴應。我仍然在等待的東西到60分鐘左右後發生......
我的行動:
[OutputCache(Location= System.Web.UI.OutputCacheLocation.None, Duration=0)]
public FileResult Export(int year, int month, int day) {
var date = new DateTime(year, month, day);
var filename = string.Format("MyTemplate_{0:yyyyMMdd}.xlsx", date);
//return new FilePathResult("~/Content/templates/MyTemplate.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
var result = new XlsxExportTemplatedResult("MyTemplate.xlsx", filename, (workbook) => {
var ws = workbook.Worksheets.Worksheet("My Export Sheet");
ws.Cell("B3").Value = date;
// Using a OpenXML's predefined formats (15 stands for date)
ws.Cell("B3").Style.NumberFormat.NumberFormatId = 15;
ws.Columns().AdjustToContents(); // You can also specify the range of columns to adjust, e.g.
return workbook;
});
return result;
}
我FileResult
public class XlsxExportTemplatedResult : FileResult
{
// default buffer size as defined in BufferedStream type
private const int BufferSize = 0x1000;
public static readonly string TEMPLATE_FOLDER_LOCATION = @"~\Content\templates";
public XlsxExportTemplatedResult(string templateName, string fileDownloadName, Func<XLWorkbook, XLWorkbook> generate)
: base("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
this.TempalteName = templateName;
this.FileDownloadName = fileDownloadName;
this.Generate = generate;
}
public string TempalteName { get; protected set; }
public Func<XLWorkbook, XLWorkbook> Generate { get; protected set; }
protected string templatePath = string.Empty;
public override void ExecuteResult(ControllerContext context) {
templatePath = context.HttpContext.Server.MapPath(System.IO.Path.Combine(TEMPLATE_FOLDER_LOCATION, this.TempalteName));
base.ExecuteResult(context);
}
//http://msdn.microsoft.com/en-us/library/office/ee945362(v=office.11).aspx
protected override void WriteFile(System.Web.HttpResponseBase response) {
FileStream fileStream = new FileStream(templatePath, FileMode.Open, FileAccess.Read);
using (MemoryStream memoryStream = new MemoryStream()) {
CopyStream(fileStream, memoryStream);
using (var workbook = new XLWorkbook(memoryStream)) {
Generate(workbook);
workbook.Save();
}
// At this point, the memory stream contains the modified document.
// grab chunks of data and write to the output stream
Stream outputStream = response.OutputStream;
byte[] buffer = new byte[BufferSize];
while (true) {
int bytesRead = memoryStream.Read(buffer, 0, BufferSize);
if (bytesRead == 0) {
// no more data
break;
}
outputStream.Write(buffer, 0, bytesRead);
}
}
fileStream.Dispose();
}
static private void CopyStream(Stream source, Stream destination) {
byte[] buffer = new byte[BufferSize];
int bytesRead;
do {
bytesRead = source.Read(buffer, 0, buffer.Length);
destination.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
}
所以我失去的東西(顯然我是)。
請注意:
- 沒有dll文件,因爲我查了使用Windows Azure工具1.7
- 我的出口是不是一個沉重的長期運行的任務的遠程訪問功能可以從Azure中失蹤。
- 當我將操作更改爲僅返回帶有模板xlsx的FilePathResult時,它在azure上工作。但我需要在返回之前處理文件,因爲你可能會懷疑:-)
坦克。
UPDATE: 後,我在我的代碼登錄廣泛的執行與在ClosedXml「保存」方法調用沒有錯誤掛起。但仍然沒有錯誤。從路徑
- 打開模板文件: E:從WADLogsTable摘要\ sitesroot \ 0 \內容\模板\ MyTemplate.xlsx
從路徑- 打開模板: E:\ sitesroot \ 0 \內容\模板\ MyTemplate.xlsx只需
- 將模板複製到可編輯內存流。字節複製:15955, 位置:15955
- 修改了內存中的excel文件。
- 這裏它掛起時,它調用workbook.Save();這是一個ClosedXml方法調用。
如果您沒有收到任何錯誤,我們不會輕易爲您提供幫助。嘗試在每行代碼之間添加一些日誌記錄。通過這種方式,您可以確切知道「停止」處理請求的位置,我們將更好地瞭解發生了什麼。 –
@SandrinoDiMattia我會嘗試記錄跟蹤並返回更多信息。但奇怪的是,當我遠程訪問Azure實例之一時,沒有在EventLog中發生異常的條目。 – cleftheris
@SandrinoDiMattia我更新了更多信息的問題。這似乎是我正在使用的ClosedXml庫問題。我下載了源代碼。 +1給你的評論,因爲我覺得我在某處:-) – cleftheris