使用Web服务创建PDF仅在直接调用服务时有效

时间:2015-07-08 20:14:02

标签: javascript c# web-services pdf

我是webservices的新手,所以这个让我难过。我创建了一个web服务,它将(最终)接受一个html块并从中创建一个pdf文件。为了简单起见,目前我没有将任何参数传递给服务;我只是创建一个带有“hello world”的pdf文档。在调试模式下,当我直接调用服务(即从该asmx页面开始调试)时,我可以调用exportPDF()方法,结果很完美 - 它就像我希望的那样创建pdf。

问题是当我从javascript调用webservice时,没有任何反应。我在服务中设置了一个断点,所以我知道它被调用了,正如我所提到的,没有传入任何参数,所以我不明白为什么它在直接调用时起作用,但不是从它调用时一个javascript电话。

我的javascript和webservice代码如下......任何帮助都会非常受欢迎!!

使用Javascript:

    function getPDF(elem) {
    var param = { html: elem.innerHTML };

    $.ajax({
        type: "POST",
        contentType: "application/json; charset=UTF-8",
        url: "../WebServices/exporting.asmx/exportPDF",
        data: "{ }",
        dataType: "json",
        success: function (response) {
        }
    })
}

WebService的:

using DMC.Classes;
using NReco.PdfGenerator;
using System;
using System.IO;
using System.Web;
using System.Web.Services;
using System.Web.UI;

namespace DMC.WebServices
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]

    public class exporting : System.Web.Services.WebService
    {
        [WebMethod]
        public void exportPDF()
        {
            WriteDocument("htmlToPDF.pdf", "application/pdf", ConvertHtmlToPDF());
        }

        public byte[] ConvertHtmlToPDF()
        {
            HtmlToPdfConverter nRecohtmltoPdfObj = new HtmlToPdfConverter();
            nRecohtmltoPdfObj.Orientation = PageOrientation.Portrait;
            nRecohtmltoPdfObj.PageFooterHtml = CreatePDFFooter();
            nRecohtmltoPdfObj.CustomWkHtmlArgs = "--margin-top 35 --header-spacing 0 --margin-left 0 --margin-right 0";
            return nRecohtmltoPdfObj.GeneratePdf(CreatePDFScript() + "Hello world" + "</body></html>");
        }

        public string CreatePDFScript()
        {
            return "<html><head><style>td,th{line-height:20px;} tr { page-break-inside: avoid }</style><script>function subst() {var vars={};var x=document.location.search.substring(1).split('&');for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}" +
            "var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];for(var i in x) {var y = document.getElementsByClassName(x[i]);" +
            "for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];}}</script></head><body onload=\"subst()\">";
        }

        public string CreatePDFFooter()
        {
            return "<div style='text-align:center;font-family:Tahoma; font-size:9px;'>Page <span class=\"page\"></span> of <span class=\"topage\"></span></div>";
        }

        public void WriteDocument(string fileName, string contentType, byte[] content)
        {
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ContentType = contentType;
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
            HttpContext.Current.Response.CacheControl = "No-cache";
            HttpContext.Current.Response.BinaryWrite(content);
            HttpContext.Current.Response.Flush();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

谢谢你的回复,梅森!我一直在努力,找到了解决方案;虽然我承认它并不完美,但我认为这不太糟糕。从我阅读的所有不同材料中,我开始感觉到Web服务更像是“传递”以传递数据而不是真正意味着处理发布PDF文档等功能。它可以让你在调试和直接调用它时逃脱它,但这就是它。

因此,我创建了一个类对象,而不是使用Web服务。我还在我的html中创建了一个隐藏字段。当有人点击“导出到PDF”按钮时,此字段将通过JavaScript填充所需的div.innerHtml内容。在回发时,我的代码隐藏检查隐藏字段是否为空,如果不是,则调用exportPDF函数,该函数又实例化创建/下载PDF的类对象。这样做的最大陷阱,有些人可能认为这是一个很大的陷阱,就是要在代码隐藏中读取具有html标记的字段,你必须关闭网页的验证,这显然会打开你的恶意攻击的代码。

以下是我的代码的重点:

<强>的Web.Config

将requestValidationMode =“2.0”添加到web.config文件

<system.web>
  <httpRuntime 
    requestValidationMode="2.0" 
    targetFramework="4.5" 
  />
</system.web>

.aspx页面

在页面参考

中设置ValidateRequest =“false”
<%@ Page Title="Referrals" Language="C#" MasterPageFile="~/Behavior/Behavior.master" AutoEventWireup="true" CodeBehind="Referrals.aspx.cs"
Inherits="DMC.Behavior.Referrals" ClientIDMode="Static" EnableEventValidation="false" ValidateRequest="false" %>
.
.
.
    <asp:LinkButton ID="LinkButton2" runat="server" OnClientClick="createPDF();">
        <img src='../Images/icons/pdf.png'>PDF</asp:LinkButton>
.
.
.
<div id="export_pdf" class="pdfWidth_Portrait pdfSection" style="margin-top: 10px;" runat="server">
    <div class="alert-info text-center" style="margin: 0; padding: 0;">
        <table class="table table-condensed" style="margin-top: 0; padding: 30px; width: 100%;">
    .
    .
    .   
        </table>
    </div>
</div>
.
.
.
<asp:HiddenField ID="pdfData" runat="server" />
.
.
.
<script type="text/javascript">
    function createPDF() {
        document.getElementById("pdfData").value = document.getElementById("export_pdf").innerHTML;
    }
</script>

代码背后:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //Set the hidden pdf field to null initially
            pdfData.Value = "";
        }

        //If this field is no longer null, it means somebody is wanting to export into PDF
        if (pdfData.Value != "")
        {
            exportPDF();
        }
    }

    public void exportPDF()
    {
        string fileName = null;
        export dmc = new export();

        fileName = lblLocation.Text + " Behavior Statistics YTD " + lblDate.Text;

        dmc.exportPDF(fileName, "Portrait", pdfData.Value);

        //PDF downloaded, reset value to ""
        pdfData.Value = "";
    }

导出类

using NReco.PdfGenerator;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace DMC.Classes
{
    public class export 
    {
        public void exportPDF(string fileName, string Orientation, string html)
        {
            HtmlToPdfConverter pdf = new HtmlToPdfConverter();

            //Remove these control characters, they interfere with the formatting of the pdf document
            html = html.Replace("\n", "");
            html = html.Replace("\t", "");
            html = html.Replace("\r", "");

            switch (Orientation)
            {
                case "Portrait":
                    pdf.Orientation = PageOrientation.Portrait;
                    break;
                case "Landscape":
                    pdf.Orientation = PageOrientation.Landscape;
                    break;
                default:
                    pdf.Orientation = PageOrientation.Default;
                    break;
            }

            //In case needed for future
            //pdf.CustomWkHtmlArgs = "--margin-top 35 --header-spacing 0 --margin-left 0 --margin-right 0";

            pdf.Margins.Top = 25;
            pdf.PageFooterHtml = createPDFFooter();

            var pdfBytes = pdf.GeneratePdf(createPDFScript() + html + "</body></html>");

            HttpContext.Current.Response.ContentType = "application/pdf";
            HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + fileName + ".pdf");
            HttpContext.Current.Response.BinaryWrite(pdfBytes);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }

        private string createPDFScript()
        {
            return "<html><head><style>td,th{line-height:20px;} tr { page-break-inside: avoid }</style><script>function subst() {var vars={};var x=document.location.search.substring(1).split('&');for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}" +
        "var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];for(var i in x) {var y = document.getElementsByClassName(x[i]);" +
        "for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];}}</script></head><body onload=\"subst()\">";
        }

        private string createPDFFooter()
        {
            return "<div><table style='font-family:Tahoma; font-size:9px; width:100%'><tr><td style='text-align:left'>Research Dept|RR:mm:jpg</td><td style='text-align:right'>Page <span class=\"page\"></span> of <span class=\"topage\"></span></td></div>";
        }
    }
}