0

我正在使用 PDFConverter 将“收据页面”保存到计算机上。它的设置方式是我使用从 Page X 到 Response.Redirect() 到 Receipt Page 的链接,因此它传输会话数据。

然后我使用 Session["Cart"] Data 用收据中的数据填充表格。问题是,当我使用 Winnovative PDFConverter 将页面保存到文件时,它不会保存表格。那是因为没有发送会话数据(或者它创建一个新的会话,不确定),因此没有填充表格,因此我保存的文件不包含表格,这是收据页面的重点。我该如何解决这个问题?我在网上找到了一个“解决方法”,但它似乎不起作用。它甚至不会保存文件,而是返回错误。

protected void Save_BtnClick(object sender, EventArgs e) 
    {
        PdfConverter converter = new PdfConverter();
        string url = HttpContext.Current.Request.Url.AbsoluteUri;

        StringWriter sw = new StringWriter();
        Server.Execute("Receipt.aspx", sw); //this line triggers an HttpException
        string htmlCodeToConvert = sw.GetStringBuilder().ToString();

        converter.SavePdfFromUrlToFile(htmlCodeToConvert, @"C:\Users\myname\Downloads\output.pdf"); // <--not even sure what method i should be running here

        //converter.SavePdfFromUrlToFile(url,@"C:\Users\myname\Downloads\output.pdf"); <-- this saves it without the table
    }

编辑:我想到的一个解决方案是,是否可以使用 Winnovative 抓取页面的某些元素以传递已填充的表格,而不是尝试使用该方法自动生成页面?我不能 100% 确定如何仅根据文档来工作,而且我无权访问示例代码。

4

2 回答 2

1

我不知道为什么 Server.Execute 会引发异常,但这是使用该调用的替代方法。

您正在使用 Server.Execute 将网页转换为 HTML。Winnovative 没有采用这种方法。诀窍是允许该页面请求访问当前用户的会话。您指定要调用的 URL,然后在 PDFConverter 的 cookie 集合中提供用户凭据。

请参阅此页面并根据您的身份验证技术选择方法。

Winnovative 身份验证处理

编辑:

@LordHonydew,我们在评论中绕了一个大圈,并在一开始就结束了。让我再试一次。

首先,在 Server.Execute 异常中是否存在内部异常?可能有更多信息有助于解释问题所在。即使在解决了该问题之后,还有其他项目必须修复。

其次,当使用 Winnovative 从受保护的网页生成 PDF 时,您必须向 PDFConverter 提供凭据,以便它可以访问该页面及其资源。winnovative 可以通过多种方式获取 HTML:一种是通过为 PDFConverter 提供要调用的 URL,另一种是使用 Server.Execute 直接获取 HTML,然后为 PDFConverter 提供 HTML,这就是您的方式正在做。无论哪种方式,PDFConverter 仍然需要与服务器通信以获取额外的页面资源。像图像和 CSS 文件这样的东西不在 HTML 中,它们被 HTML 引用。转换器将调用服务器以获取这些项目。由于您的应用程序是安全的,您必须向转换器提供访问服务器的凭据。我们将通过使用用于每个页面请求的相同身份验证 cookie 来做到这一点。还有其他方法,例如提供用户名和密码。上面的链接解释了各种方式。

此代码从当前请求中获取 auth cookie 并将其提供给转换器:

pdfConverter.HttpRequestCookies.Add(FormsAuthentication.FormsCookieName,
     Request.Cookies[FormsAuthentication.FormsCookieName].Value);

最后,converter.SavePdfFromUrlToFile 不是正确的使用方法。那只会将收据保存到本地服务器的驱动器中。您需要将其流式传输回给用户。

试试下面的。在 catch 块中设置断点,以便查看是否存在内部异常。

protected void Save_BtnClick(object sender, EventArgs e)
    {

        // Get the web page HTML as a string
        string htmlCodeToConvert = null;
        using (StringWriter sw = new StringWriter())
        {
            try
            {
                System.Web.HttpContext.Current.Server.Execute("Receipt.aspx", sw);
                htmlCodeToConvert = sw.ToString();

            }
            catch (Exception ex)
            {
                // set breakpoint below and on an exception see if there is an inner exception.
                throw;                    
            }
        }

        PdfConverter converter = new PdfConverter();
        // Supply auth cookie to converter
        converter.HttpRequestCookies.Add(System.Web.Security.FormsAuthentication.FormsCookieName,
            Request.Cookies[System.Web.Security.FormsAuthentication.FormsCookieName].Value);

        // baseurl is used by converter when it gets CSS and image files
        string baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority +
            Request.ApplicationPath.TrimEnd('/') + "/";

        // create the PDF and get as bytes
        byte[] pdfBytes = converter.GetPdfBytesFromHtmlString(htmlCodeToConvert, baseUrl);

        // Stream bytes to user
        Response.Clear();
        Response.AppendHeader("Content-Disposition", "attachment;filename=Receipt.pdf");
        Response.ContentType = "application/pdf";
        Response.OutputStream.Write(pdfBytes, 0, pdfBytes.Length);
        HttpContext.Current.ApplicationInstance.CompleteRequest();

    }
于 2014-05-19T21:04:59.310 回答
1

请查看在同一会话演示中将 HTML 页面转换为 PDF。您可以在此处找到用于在转换期间保存会话数据的方法的描述以及 C# 示例代码。下面的代码是从那里复制的:

protected void convertToPdfButton_Click(object sender, EventArgs e)
{
    // Save variables in Session object
    Session["firstName"] = firstNameTextBox.Text;
    Session["lastName"] = lastNameTextBox.Text;
    Session["gender"] = maleRadioButton.Checked ? "Male" : "Female";
    Session["haveCar"] = haveCarCheckBox.Checked;
    Session["carType"] = carTypeDropDownList.SelectedValue;
    Session["comments"] = commentsTextBox.Text;

    // Execute the Display_Session_Variables.aspx page and get the HTML string 
    // rendered by this page
    TextWriter outTextWriter = new StringWriter();
    Server.Execute("Display_Session_Variables.aspx", outTextWriter);

    string htmlStringToConvert = outTextWriter.ToString();

    // Create a HTML to PDF converter object with default settings
    HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

    // Set license key received after purchase to use the converter in licensed mode
    // Leave it not set to use the converter in demo mode
    htmlToPdfConverter.LicenseKey = "fvDh8eDx4fHg4P/h8eLg/+Dj/+jo6Og=";

    // Use the current page URL as base URL
    string baseUrl = HttpContext.Current.Request.Url.AbsoluteUri;

    // Convert the page HTML string to a PDF document in a memory buffer
    byte[] outPdfBuffer = htmlToPdfConverter.ConvertHtml(htmlStringToConvert, baseUrl);

    // Send the PDF as response to browser

    // Set response content type
    Response.AddHeader("Content-Type", "application/pdf");

    // Instruct the browser to open the PDF file as an attachment or inline
    Response.AddHeader("Content-Disposition", String.Format("attachment; filename=Convert_Page_in_Same_Session.pdf; size={0}", outPdfBuffer.Length.ToString()));

    // Write the PDF document buffer to HTTP response
    Response.BinaryWrite(outPdfBuffer);

    // End the HTTP response and stop the current page processing
    Response.End();
}


Display Session Variables in Converted HTML Page

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        firstNameLabel.Text = Session["firstName"] != null ? (String)Session["firstName"] : String.Empty;
        lastNameLabel.Text = Session["lastName"] != null ? (String)Session["lastName"] : String.Empty;
        genderLabel.Text = Session["gender"] != null ? (String)Session["gender"] : String.Empty;

        bool iHaveCar = Session["haveCar"] != null ? (bool)Session["haveCar"] : false;
        haveCarLabel.Text = iHaveCar ? "Yes" : "No";
        carTypePanel.Visible = iHaveCar;
        carTypeLabel.Text = iHaveCar && Session["carType"] != null ? (String)Session["carType"] : String.Empty;

        commentsLabel.Text = Session["comments"] != null ? (String)Session["comments"] : String.Empty;
    }
}
于 2014-08-30T08:32:35.570 回答