ASP.NET UpdatePanel 中的下载 PDF 功能无法刷新 UpdateProgress 控件
ASP.NET download PDF feature in UpdatePanel unable to refresh UpdateProgress control
我在一个页面中有两个 UpdatePanel。第二个有 UpdateMode="Conditional",这里有一个 link 按钮来生成 PDF 文件。
我的目标是允许 PDF 下载,同时让等待图像出现(如沙漏)。
经过几天的学习我达到了我的目标但是我无法在所有操作终止后隐藏图像。
在代码示例中,我简化了生成 pdf 的逻辑(在完整代码中,我使用 gridview 控件数据生成 pdf)。
如果我在 UpdatePanel 中使用异步 PostBackTrigger,即使 UpdateProgress(具有预期图像)工作正常,也不会下载 PDF。
如果我在 UpdatePanel 中使用同步 PostBackTrigger,PDF 会被正确下载,但 updateProgress 不起作用,因为等待的图像仍然在屏幕上。在这种情况下,我使用了客户端功能 (postbackButtonClick) 来显示图像。
我读过很多话题,但每一个总是有点不同。
我的实际目标是在 PDF 生成操作完成时在客户端知道是否可以隐藏图像。
也许一般的做法是错误的?
aspx 文件
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" EnableCdn="true"> </asp:ScriptManager>
<asp:UpdateProgress ID="UpdateProgress1" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="updateGrid" DisplayAfter="0" >
<ProgressTemplate> <div class="progress"> <img src="../images/ajax-loader.gif" /> Waiting...</div> </ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="updateGrid" runat="server">
<ContentTemplate>
<asp:TextBox class='form-control' ID="txtMat" runat="server" style='width:110px' Text="1672"></asp:TextBox>
<asp:Button class='btn btn-primary' ID="cmdGO" runat="server" Text="Execute"/>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="panelCMD" runat="server">
<asp:LinkButton ID="LinkButton3" OnClientClick="return postbackButtonClick();"
runat ="server" CssClass="btn btn-small btn-primary fullwidth" OnClick="mtdCreatePDF"><i class="icon icon-ok"></i> TEST PDF</asp:LinkButton>
</asp:Panel>
</ContentTemplate>
<Triggers >
<asp:PostBackTrigger ControlID="LinkButton3" />
</Triggers>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress2" ClientIDMode="Static" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="UpdatePanel2" DisplayAfter="0" >
<ProgressTemplate>
<div class="progress">
<asp:image id="imgOld" runat="server" imageurl="../images/ajax-loader.gif" />
<br />
<img id="imgLike" src="../images/ajax-loader.gif" /> Attendere...</div>
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
<script src="Test.js" type="text/javascript"></script>
Test.js
function postbackButtonClick() {
updateProgress = $find("UpdateProgress2");
window.setTimeout(function () { updateProgress.set_visible(true); }, 100);
return true;
}
cs文件
protected void mtdCreatePDF(object sender, EventArgs e)
{
byte[] content = null;
string TypeOutput = "RESPONSE";
string suffix = @"Pdf_PROD\Print.pdf";
string nameTGT = HttpContext.Current.Server.MapPath("~") + suffix;
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Hello world!"));
document.Close();
if (TypeOutput == "RESPONSE")
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=print.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
//writer.SetCloseStream(false);
Response.BinaryWrite(stream.ToArray());
Response.End();
}
else
{
content = stream.ToArray();
using (FileStream fs = File.Create(nameTGT))
{
fs.Write(content, 0, (int)content.Length);
}
}
}
首先,超时需要有一个timeoutID。我们稍后将使用它来禁用超时。 pdf 创建完成后,hideUpdateProgress()
函数将从代码隐藏调用以隐藏进度图像。
Test.js
var timeoutID;
function postbackButtonClick() {
updateProgress = $find("UpdateProgress2");
timeoutID = window.setTimeout(function () { updateProgress.set_visible(true); }, 100);
return true;
function hideUpdateProgress()
{
clearTimeout(timeoutID);
updateProgress = $find("UpdateProgress2");
updateProgress.set_visible(false);
}
要调用hideUpdateProgress();
,您可以在mtdCreatePDF
函数的末尾添加这一行。
ClientScript.RegisterStartupScript(Page.GetType(),
"hideUpdateProgress",
"hideUpdateProgress();",
true);
我是这样解决的:我把所有的东西都移到了客户端。
一个。我在单击 link 按钮时添加了一个客户端事件
<asp:LinkButton ID="LinkButton6" OnClientClick="return TestPDFDEF();" runat="server" CssClass="btn btn-small btn-primary fullwidth"><i class="icon icon-ok"></i> TEST PDF WebService Def</asp:LinkButton>
乙。我向页面添加了一个 WebMethod,它为 Ajax 调用
提供了一个 [byte] 类型的变量
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public byte[] GetPDF(List<Classes.GridCosts> MyGrid)
{
foreach (Classes.GridCosts rowsGrid in GrMyGridglia)
{
Console.Write(rowsGrid.Field1);
Console.Write(rowsGrid.Field2);
}
string suffix = @"Pdf_PRODOTTI\Print.pdf";
string nameTGT = HttpContext.Current.Server.MapPath("~") + suffix;
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Hello world!"));
document.Close();
return stream.ToArray();
}
C。我定义了一个 class 用于接收将传递给方法
的网格
public class GridCosts
{
public string Field1{ get; set; }
public string Field2{ get; set; }
}
D.添加了为沙漏显示的图像:
$(document).ready(function () {
$('body').append('<div class="progress" id="ajaxBusy"><p><img src="../images/ajax-loader.gif"> Waiting..</p></div>');
$('#ajaxBusy').hide();
//$('#ajaxBusy').css({
// display: "none",
// left: "50%",
// margin: "0px",
// paddingLeft: "0px",
// paddingRight: "0px",
// paddingTop: "0px",
// paddingBottom: "0px",
// position: "fixed",
// right: "3px",
// top: "35%",
// width: "auto"
//});
// Ajax activity indicator bound to ajax start/stop document events
$(document).ajaxStart(function () {
$('#ajaxBusy').show();
}).ajaxStop(function () {
$('#ajaxBusy').hide();
});
});
E.我用 Javascript
将 B 点中引用的变量发送给用户
function TestPDFDEF() {
$(function () {
var MyGrid= new Array();
var CostsRow = {};
$('[id*=MyGrid]').find('tr:has(td)').each(function () {
CostsRow.Field1= $.trim($(this).find("td:nth-child(3)").text());
CostsRow.Field2= $.trim($(this).find("td:nth-child(4)").text());
MyGrid.push(CostsRow );
CostsRow = {};
});
type: "POST",
url: "WebService1.asmx/GetPDF",
contentType: "application/json; charset=utf-8",
data: '{MyGrid: ' + JSON.stringify(MyGrid) + '}',
dataType: "json",
beforeSend: function () {
},
success: function (data) {
data = data.d;
var byteArray = new Uint8Array(data);
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob([byteArray], { type: 'application/pdf' }));
a.download = 'FileName';
document.body.appendChild(a)
a.click();
document.body.removeChild(a)
},
complete: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
});
}
我在一个页面中有两个 UpdatePanel。第二个有 UpdateMode="Conditional",这里有一个 link 按钮来生成 PDF 文件。 我的目标是允许 PDF 下载,同时让等待图像出现(如沙漏)。 经过几天的学习我达到了我的目标但是我无法在所有操作终止后隐藏图像。
在代码示例中,我简化了生成 pdf 的逻辑(在完整代码中,我使用 gridview 控件数据生成 pdf)。
如果我在 UpdatePanel 中使用异步 PostBackTrigger,即使 UpdateProgress(具有预期图像)工作正常,也不会下载 PDF。
如果我在 UpdatePanel 中使用同步 PostBackTrigger,PDF 会被正确下载,但 updateProgress 不起作用,因为等待的图像仍然在屏幕上。在这种情况下,我使用了客户端功能 (postbackButtonClick) 来显示图像。
我读过很多话题,但每一个总是有点不同。
我的实际目标是在 PDF 生成操作完成时在客户端知道是否可以隐藏图像。
也许一般的做法是错误的?
aspx 文件
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" EnableCdn="true"> </asp:ScriptManager>
<asp:UpdateProgress ID="UpdateProgress1" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="updateGrid" DisplayAfter="0" >
<ProgressTemplate> <div class="progress"> <img src="../images/ajax-loader.gif" /> Waiting...</div> </ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="updateGrid" runat="server">
<ContentTemplate>
<asp:TextBox class='form-control' ID="txtMat" runat="server" style='width:110px' Text="1672"></asp:TextBox>
<asp:Button class='btn btn-primary' ID="cmdGO" runat="server" Text="Execute"/>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="panelCMD" runat="server">
<asp:LinkButton ID="LinkButton3" OnClientClick="return postbackButtonClick();"
runat ="server" CssClass="btn btn-small btn-primary fullwidth" OnClick="mtdCreatePDF"><i class="icon icon-ok"></i> TEST PDF</asp:LinkButton>
</asp:Panel>
</ContentTemplate>
<Triggers >
<asp:PostBackTrigger ControlID="LinkButton3" />
</Triggers>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress2" ClientIDMode="Static" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="UpdatePanel2" DisplayAfter="0" >
<ProgressTemplate>
<div class="progress">
<asp:image id="imgOld" runat="server" imageurl="../images/ajax-loader.gif" />
<br />
<img id="imgLike" src="../images/ajax-loader.gif" /> Attendere...</div>
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
<script src="Test.js" type="text/javascript"></script>
Test.js
function postbackButtonClick() {
updateProgress = $find("UpdateProgress2");
window.setTimeout(function () { updateProgress.set_visible(true); }, 100);
return true;
}
cs文件
protected void mtdCreatePDF(object sender, EventArgs e)
{
byte[] content = null;
string TypeOutput = "RESPONSE";
string suffix = @"Pdf_PROD\Print.pdf";
string nameTGT = HttpContext.Current.Server.MapPath("~") + suffix;
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Hello world!"));
document.Close();
if (TypeOutput == "RESPONSE")
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=print.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
//writer.SetCloseStream(false);
Response.BinaryWrite(stream.ToArray());
Response.End();
}
else
{
content = stream.ToArray();
using (FileStream fs = File.Create(nameTGT))
{
fs.Write(content, 0, (int)content.Length);
}
}
}
首先,超时需要有一个timeoutID。我们稍后将使用它来禁用超时。 pdf 创建完成后,hideUpdateProgress()
函数将从代码隐藏调用以隐藏进度图像。
Test.js
var timeoutID;
function postbackButtonClick() {
updateProgress = $find("UpdateProgress2");
timeoutID = window.setTimeout(function () { updateProgress.set_visible(true); }, 100);
return true;
function hideUpdateProgress()
{
clearTimeout(timeoutID);
updateProgress = $find("UpdateProgress2");
updateProgress.set_visible(false);
}
要调用hideUpdateProgress();
,您可以在mtdCreatePDF
函数的末尾添加这一行。
ClientScript.RegisterStartupScript(Page.GetType(),
"hideUpdateProgress",
"hideUpdateProgress();",
true);
我是这样解决的:我把所有的东西都移到了客户端。
一个。我在单击 link 按钮时添加了一个客户端事件
<asp:LinkButton ID="LinkButton6" OnClientClick="return TestPDFDEF();" runat="server" CssClass="btn btn-small btn-primary fullwidth"><i class="icon icon-ok"></i> TEST PDF WebService Def</asp:LinkButton>
乙。我向页面添加了一个 WebMethod,它为 Ajax 调用
提供了一个 [byte] 类型的变量[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public byte[] GetPDF(List<Classes.GridCosts> MyGrid)
{
foreach (Classes.GridCosts rowsGrid in GrMyGridglia)
{
Console.Write(rowsGrid.Field1);
Console.Write(rowsGrid.Field2);
}
string suffix = @"Pdf_PRODOTTI\Print.pdf";
string nameTGT = HttpContext.Current.Server.MapPath("~") + suffix;
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Hello world!"));
document.Close();
return stream.ToArray();
}
C。我定义了一个 class 用于接收将传递给方法
的网格 public class GridCosts
{
public string Field1{ get; set; }
public string Field2{ get; set; }
}
D.添加了为沙漏显示的图像:
$(document).ready(function () {
$('body').append('<div class="progress" id="ajaxBusy"><p><img src="../images/ajax-loader.gif"> Waiting..</p></div>');
$('#ajaxBusy').hide();
//$('#ajaxBusy').css({
// display: "none",
// left: "50%",
// margin: "0px",
// paddingLeft: "0px",
// paddingRight: "0px",
// paddingTop: "0px",
// paddingBottom: "0px",
// position: "fixed",
// right: "3px",
// top: "35%",
// width: "auto"
//});
// Ajax activity indicator bound to ajax start/stop document events
$(document).ajaxStart(function () {
$('#ajaxBusy').show();
}).ajaxStop(function () {
$('#ajaxBusy').hide();
});
});
E.我用 Javascript
将 B 点中引用的变量发送给用户function TestPDFDEF() {
$(function () {
var MyGrid= new Array();
var CostsRow = {};
$('[id*=MyGrid]').find('tr:has(td)').each(function () {
CostsRow.Field1= $.trim($(this).find("td:nth-child(3)").text());
CostsRow.Field2= $.trim($(this).find("td:nth-child(4)").text());
MyGrid.push(CostsRow );
CostsRow = {};
});
type: "POST",
url: "WebService1.asmx/GetPDF",
contentType: "application/json; charset=utf-8",
data: '{MyGrid: ' + JSON.stringify(MyGrid) + '}',
dataType: "json",
beforeSend: function () {
},
success: function (data) {
data = data.d;
var byteArray = new Uint8Array(data);
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob([byteArray], { type: 'application/pdf' }));
a.download = 'FileName';
document.body.appendChild(a)
a.click();
document.body.removeChild(a)
},
complete: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
});
}