使用web服务创建PDF仅在直接调用该服务时有效
本文关键字:服务 调用 有效 web 创建 PDF 使用 | 更新日期: 2023-09-27 18:01:46
我是一个web服务的新手,所以这个问题难倒了我。我已经创建了一个web服务,它将(最终)接受html块并从中创建pdf文件。为了简单起见,目前我没有向服务传递任何参数;我只是创建了一个pdf文档,里面有"hello world"。在调试模式下,当我直接调用服务(即从那个asmx页面开始调试)时,我可以调用exportPDF()方法,结果非常完美——它创建了我所希望的pdf。
问题是当我从javascript调用web服务时,什么都没有发生。我在服务内部设置了一个断点,所以我知道它正在被调用,正如我提到的,没有参数被传递进来,所以我不明白为什么它在直接调用时工作,但当它从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: <<p> /strong> 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();
}
}
}
谢谢你的回复,Mason!我一直在研究这个问题,并找到了一个解决方案;虽然我承认它并不完美,但我不认为它太糟糕。从我读过的所有不同的材料中,我开始感觉到web服务更像是传递数据的"中间人",而不是真正用来处理发布PDF文档之类的功能。它可以让您在调试和直接调用它时避开它,但仅此而已。
所以我没有使用web服务,而是创建了一个类对象。我还在html中创建了一个隐藏字段。当有人点击"导出到PDF"按钮时,该字段通过JavaScript填充所需的div.innerHtml内容。在回发时,我的代码隐藏检查隐藏字段是否为空,如果不是,则调用exportPDF函数,该函数反过来实例化创建/下载PDF的类对象。这样做的最大的陷阱,有些人可能认为这是一个很大的陷阱,是在代码中读取有html标记的字段时,你必须关闭对网页的验证,这显然为恶意攻击打开了你的代码。
下面是我的代码的亮点:
网络。配置
添加requestValidationMode = "2.0"到web。配置文件
<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>";
}
}
}