1

我在一个页面中有两个 UpdatePanel。第二个有 UpdateMode="Conditional" ,这里有一个链接按钮来生成 PDF 文件。我的目标是允许 PDF 下载,同时显示等待图像(如沙漏)。经过几天的学习,我达到了目标,但在所有操作终止后我无法隐藏图像。

在代码示例中,我简化了生成 pdf 的逻辑(在完整的代码中,我使用 gridview 控制数据来生成 pdf)。

  1. 如果我在 UpdatePanel 中使用异步 PostBackTrigger,即使 UpdateProgress(带有预期图像)正常工作,也不会下载 PDF。

  2. 如果我在 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" />&nbsp;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>&nbsp;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" />&nbsp;Attendere...</div>
     </ProgressTemplate>
     </asp:UpdateProgress>


</div>
</form>
<script src="Test.js" type="text/javascript"></script>

测试.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);
            }
        }


    }
4

2 回答 2

1

首先,需要有一个 timeoutID 用于超时。我们稍后将使用它来禁用超时。pdf 创建完成后,hideUpdateProgress()将从代码隐藏中调用函数以隐藏进度图像。

测试.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);
于 2021-09-20T11:21:22.347 回答
1

我通过以下方式解决了它:我将所有内容都移到了客户端。

A. 我在点击链接按钮时添加了一个客户端事件

<asp:LinkButton ID="LinkButton6" OnClientClick="return TestPDFDEF();" runat="server" CssClass="btn btn-small btn-primary fullwidth"><i class="icon icon-ok"></i>&nbsp;TEST PDF WebService Def</asp:LinkButton>

B. 我在页面中添加了一个 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. 我已经定义了一个类用于接收将传递给方法的网格

 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">&nbsp;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);
        }
    });



});

}

于 2021-09-23T17:42:51.277 回答