我正在使用asp.net/C#/HTML5/bootstrap開發一個網站。其中一項要求是將文檔導出爲Excel和/或PDF。我能出口(成功),使用下面的片段(這是Excel的片段):使用HttpContext.Current.Response導出導致問題
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + filename);
HttpContext.Current.Response.BinaryWrite(xlsBytes);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
我遇到的問題是,這個運行後,它似乎停止頁面生命週期死在它的軌道。舉個例子,用戶點擊導出按鈕,它調用JavaScript代碼拋出了一個「請等待」模態對話框並提交表單:
<script src="../Scripts/waitingFor.js"></script>
<script type="text/javascript">
function pleaseWait() {
waitingDialog.show("Building File<br/>...this could take a minute", { dialogSize: "sm", progressType: "warning" });
form = document.getElementById("frm_contentMaster");
form.submit();
}
</script>
的JavaScript包括文件:
/**
* Module for displaying "Waiting for..." dialog using Bootstrap
*
* @author Eugene Maslovich <[email protected]>
*/
(function (root, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['jquery'], function ($) {
return (root.waitingDialog = factory($));
});
}
else {
root.waitingDialog = root.waitingDialog || factory(root.jQuery);
}
}(this, function ($) {
'use strict';
/**
* Dialog DOM constructor
*/
function constructDialog($dialog) {
// Deleting previous incarnation of the dialog
if ($dialog) {
$dialog.remove();
}
return $(
'<div id="waitingFor" class="modal fade" data-backdrop="static" data-keyboard="false" tabindex="-1" role="dialog" aria-hidden="true" style="padding-top:15%; overflow-y:visible;">' +
'<div class="modal-dialog modal-m">' +
'<div class="modal-content">' +
'<div class="modal-header" style="display: none;"></div>' +
'<div class="modal-body">' +
'<div class="progress progress-striped active" style="margin-bottom:0;">' +
'<div class="progress-bar" style="width: 100%"></div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>'
);
}
// Dialog object
var $dialog;
return {
/**
* Opens our dialog
* @param message Custom message
* @param options Custom options:
* options.headerText - if the option is set to boolean false,
* it will hide the header and "message" will be set in a paragraph above the progress bar.
* When headerText is a not-empty string, "message" becomes a content
* above the progress bar and headerText string will be set as a text inside the H3;
* options.headerSize - this will generate a heading corresponding to the size number. Like <h1>, <h2>, <h3> etc;
* options.headerClass - extra class(es) for the header tag;
* options.dialogSize - bootstrap postfix for dialog size, e.g. "sm", "m";
* options.progressType - bootstrap postfix for progress bar type, e.g. "success", "warning";
* options.contentElement - determines the tag of the content element.
* Defaults to "p", which will generate a <p> tag;
* options.contentClass - extra class(es) for the content tag.
*/
show: function (message, options) {
// Assigning defaults
if (typeof options === 'undefined') {
options = {};
}
if (typeof message === 'undefined') {
message = 'Loading';
}
var settings = $.extend({
headerText: '',
headerSize: 3,
headerClass: '',
dialogSize: 'm',
progressType: '',
contentElement: 'p',
contentClass: 'content',
onHide: null // This callback runs after the dialog was hidden
}, options),
$headerTag, $contentTag;
$dialog = constructDialog($dialog);
// Configuring dialog
$dialog.find('.modal-dialog').attr('class', 'modal-dialog').addClass('modal-' + settings.dialogSize);
$dialog.find('.progress-bar').attr('class', 'progress-bar');
if (settings.progressType) {
$dialog.find('.progress-bar').addClass('progress-bar-' + settings.progressType);
}
// Generate header tag
$headerTag = $('<h' + settings.headerSize + ' />');
$headerTag.css({ 'margin': 0 });
if (settings.headerClass) {
$headerTag.addClass(settings.headerClass);
}
// Generate content tag
$contentTag = $('<' + settings.contentElement + ' />');
if (settings.contentClass) {
$contentTag.addClass(settings.contentClass);
}
if (settings.headerText === false) {
$contentTag.html(message);
$dialog.find('.modal-body').prepend($contentTag);
}
else if (settings.headerText) {
$headerTag.html(settings.headerText);
$dialog.find('.modal-header').html($headerTag).show();
$contentTag.html(message);
$dialog.find('.modal-body').prepend($contentTag);
}
else {
$headerTag.html(message);
$dialog.find('.modal-header').html($headerTag).show();
}
// Adding callbacks
if (typeof settings.onHide === 'function') {
$dialog.off('hidden.bs.modal').on('hidden.bs.modal', function() {
settings.onHide.call($dialog);
});
}
// Opening dialog
$dialog.modal();
},
/**
* Closes dialog
*/
hide: function() {
if (typeof $dialog !== 'undefined') {
$dialog.modal('hide');
}
}
};
}));
我使用NPOI以在後面的代碼Excel文件米(簡化功能):
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
protected void exportExcel()
{
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sh = (XSSFSheet)wb.CreateSheet("Legend");
//*****************************************
//* Workbook Download & Cleanup
//*****************************************
MemoryStream stream = new MemoryStream();
wb.Write(stream);
stream.Dispose();
var xlsBytes = stream.ToArray();
string filename = "Behavior Stats YTD.xlsx";
MemoryStream newStream = new MemoryStream(xlsBytes);
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + filename);
HttpContext.Current.Response.BinaryWrite(xlsBytes);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
此創建Excel文件並將其推給用戶,但是代碼的生命週期的後面不續inue - 在結束命令後立即停止。如果我註釋掉HttpContext行,顯然Excel表格不會被創建,但頁面的生命週期仍在繼續 - 其餘的代碼運行,頁面刷新,並且模式Please Wait對話框消失。
那麼我使用這個錯誤?我見過的大多數例子都是用這種方法導出的。我還有另一種更清潔和/或更安全的出口方式嗎?我需要做一個簡單的調整,這將讓生命週期繼續下去嗎?誰創造了液體肥皂,爲什麼?
任何幫助你可以提供將大大,非常感謝。
我真誠地不能謝謝你,這已經讓我頭痛的時間最長,你的解決方案也簡單而優雅。我也很欣賞對這個迴應是什麼的解釋 - 出於某種原因,這只是讓我的腦海裏「點擊」的東西,並且我明白了它爲什麼不起作用。再次感謝和快樂編碼! –
不客氣。樂於幫助! –