我正在使用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对话框消失。
那么我使用这个错误?我见过的大多数例子都是用这种方法导出的。我还有另一种更清洁和/或更安全的出口方式吗?我需要做一个简单的调整,这将让生命周期继续下去吗?谁创造了液体肥皂,为什么?
任何帮助你可以提供将大大,非常感谢。
我真诚地不能谢谢你,这已经让我头痛的时间最长,你的解决方案也简单而优雅。我也很欣赏对这个回应是什么的解释 - 出于某种原因,这只是让我的脑海里“点击”的东西,并且我明白了它为什么不起作用。再次感谢和快乐编码! –
不客气。乐于帮助! –