【发布时间】:2015-04-19 22:21:38
【问题描述】:
我创建了一个简单的 C# asmx 服务来将 HTML 转换为工作 PDF(我正在使用免费的 NReco C# 库)。
它在 Firefox 和 Chrome 中运行得非常好,但 IE 不会下载该文件。有人可以看看我的 JavaScript 吗?
这是一个非常 hacky 的 JSFiddle,它显示了我的 JavaScript 代码: jsfiddle_link
这是我的 C# asmx 代码:
[WebMethod(Description = "<div style=\"font-weight:bold;\">Passing Parameters to Format your PDF file</div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>orientation</b> - \"sets the page orientation\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">\\\"orientation\\\":\\\"portrait\\\"<br/>OR<br/>\\\"orientation\\\":\\\"landscape\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>height</b> - \"sets the page height (you can use in, cm, mm or px)\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">\\\"height\\\":\\\"4in\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>width</b> - \"sets the page width (you can use in, cm, mm or px)\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">\\\"width\\\":\\\"6in\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>smartshrink</b> - \"tries to shrink your html code so that it can all fit in one page\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">\\\"smartshrink\\\":\\\"true\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>title</b> - \"embeds details in the file-details-title section of the pdf file\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">\\\"title\\\":\\\"This PDF was created in Prince Manufacturing\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>removemargins</b> - \"by default, pdf docs are created with a marin of 1in on all sides. This sets all margins to 0\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">\\\"removemargins\\\":\\\"true\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>marginright | marginleft | margintop | marginbottom</b> - \"Sets given margin size (in pixels)\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">\\\"marginleft\\\":\\\"30\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>includepagenumbers</b> - \"adds a footer to each pdf page displaying 'Page x of y'\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">\\\"includepagenumbers\\\":\\\"true\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>rotate</b> - \"rotates all PDF pages to the specified degrees\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">(Acceptable degrees: -90 90 180)<br/><br/>\\\"rotate\\\":\\\"90\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;border:1px solid black;background-color:#FFFFD9;display:inline-block;\"><b>customeargs</b> - \"allows you to manually add any of the available wkhtml parameters\"</div>" +
"<div style=\"padding:8px;margin-left:40px;\"><table style=\"border-collapse:collapse;\"><tr><td style=\"background-color:gray;color:white;\">usage:</td><td style=\"padding-left:10px;\">(for all available parameters please refer to http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html)<br/><br/>\\\"customeargs\\\":\\\"--footer-right `My PDF is Cool!`\\\"</td></tr></table></div>" +
"<div style=\"padding:8px;margin-left:20px;background-color:yellow;display:inline-block;border:1px solid orange;\">In your C# code pass the parameters in a JSON string this way:<br/><br/>\"{\\\"orientation\\\":\\\"landscape\\\",\\\"height\\\":\\\"2in\\\",\\\"width\\\":\\\"3in\\\",\\\"smartshrink\\\":\\\"false\\\",\\\"removemargins\\\":\\\"true\\\"}\"</div>" +
"")]
public void ConvertHTMLtoPDFJS(int entryType, string sessionID, string inHTML, string properties, string FileNamex)
{
/* Lets do a little house cleaning first; we will delete any junk HTML parts older than one day */
using (MySqlConnection myConnectionX = new MySqlConnection(ConfigurationManager.ConnectionStrings["valleEvicore"].ConnectionString.ToString()))
{
myConnectionX.Open();
MySqlCommand myCmd = new MySqlCommand("spMobileServices_deleteOldHTMLparts", myConnectionX);
myCmd.CommandType = CommandType.StoredProcedure;
myCmd.ExecuteNonQuery();
}
/******************************/
if (entryType == 0)
{
using (MySqlConnection myConnectionX = new MySqlConnection(ConfigurationManager.ConnectionStrings["valleEvicore"].ConnectionString.ToString()))
{
myConnectionX.Open();
MySqlCommand myCmd = new MySqlCommand("spMobileServices_insertHTMLpart", myConnectionX);
myCmd.CommandType = CommandType.StoredProcedure;
myCmd.Parameters.AddWithValue("@_sessionid", sessionID);
myCmd.Parameters.AddWithValue("@_htmlpart", inHTML);
myCmd.ExecuteNonQuery();
}
//HttpContext.Current.Response.ContentType = "text/json";
//HttpContext.Current.Response.Write("{\"error\":\"0\",\"pdfRes\":\"0\"}");
//HttpContext.Current.Response.End();
HttpContext.Current.Response.Write("<script type=\"text/javascript\">window.parent.postMessage(\"next\", \"*\");</script>");
//HttpContext.Current.Response.End();
//HttpContext.Current.Response.SuppressContent = true;
//HttpContext.Current.ApplicationInstance.CompleteRequest();
}
else
{
DataTable tblResults = new DataTable();
StringBuilder htmlSB = new StringBuilder();
using (MySqlConnection myConnectionX = new MySqlConnection(ConfigurationManager.ConnectionStrings["valleEvicore"].ConnectionString.ToString()))
{
myConnectionX.Open();
MySqlCommand myCmd = new MySqlCommand("spMobileServices_getHTMLpartsBySessionID", myConnectionX);
myCmd.CommandType = CommandType.StoredProcedure;
myCmd.Parameters.AddWithValue("@_sessionid", sessionID);
MySqlDataAdapter adapter = new MySqlDataAdapter(myCmd);
adapter.Fill(tblResults);
}
for (int i = 0; i < tblResults.Rows.Count; i++)
{
htmlSB.Append(System.Uri.UnescapeDataString(tblResults.Rows[i][2].ToString()));
}
inHTML = htmlSB.ToString();
using (MySqlConnection myConnectionX = new MySqlConnection(ConfigurationManager.ConnectionStrings["valleEvicore"].ConnectionString.ToString()))
{
myConnectionX.Open();
MySqlCommand myCmd = new MySqlCommand("spMobileServices_deleteHTMLparts", myConnectionX);
myCmd.CommandType = CommandType.StoredProcedure;
myCmd.Parameters.AddWithValue("@_sessionid", sessionID);
myCmd.ExecuteNonQuery();
}
JavaScriptSerializer jss = new JavaScriptSerializer();
NReco.PdfGenerator.HtmlToPdfConverter pdfConv = new NReco.PdfGenerator.HtmlToPdfConverter();
pdfConv.PdfToolPath = @"C:\PDFTools\";
properties = System.Uri.UnescapeDataString(properties).Trim();
string[] finRotate = { "false", "" };
try
{
if (properties.Trim() == "none" || properties.Trim() == "")
{
//pdfConv.CustomWkHtmlArgs = "-O portrait";
}
else
{
StringBuilder sb = new StringBuilder();
try
{
Dictionary<string, string> finJSON = jsonParse(properties.ToLower());
if (finJSON.ContainsKey("orientation"))
{
if (finJSON["orientation"] == "portrait")
{
sb.Append(" -O portrait");
}
else if (finJSON["orientation"] == "landscape")
{
sb.Append(" -O landscape");
}
}
if (finJSON.ContainsKey("smartshrink"))
{
if (finJSON["smartshrink"] == "false")
{
sb.Append(" --disable-smart-shrinking");
}
}
if (finJSON.ContainsKey("title"))
{
sb.Append(" --title \"" + finJSON["title"] + "\"");
}
if (finJSON.ContainsKey("removemargins"))
{
if (finJSON["removemargins"] == "true")
{
//if (smartShrink == false)
//{
// sb.Append(" --margin-right 0 --margin-top 1 --margin-bottom 0 --margin-left 1");
//}
//else
//{
// sb.Append(" --margin-right 0 --margin-top 0 --margin-bottom 0 --margin-left 0");
//}
sb.Append(" --margin-right 0 --margin-top 0 --margin-bottom 0 --margin-left 0");
}
}
if (finJSON.ContainsKey("marginright"))
{
sb.Append(" --margin-right " + finJSON["marginright"]);
}
if (finJSON.ContainsKey("marginleft"))
{
sb.Append(" --margin-left " + finJSON["marginleft"]);
}
if (finJSON.ContainsKey("margintop"))
{
sb.Append(" --margin-top " + finJSON["margintop"]);
}
if (finJSON.ContainsKey("marginbottom"))
{
sb.Append(" --margin-bottom " + finJSON["marginbottom"]);
}
if (finJSON.ContainsKey("width"))
{
sb.Append(" --page-width " + finJSON["width"]);
}
if (finJSON.ContainsKey("height"))
{
sb.Append(" --page-height " + finJSON["height"]);
}
if (finJSON.ContainsKey("includepagenumbers"))
{
if (finJSON["includepagenumbers"] == "true")
{
sb.Append(" --footer-right \"Page [page] of [toPage]\"");
}
//pdfConv.CustomWkHtmlArgs = "--footer-right \"Page [page] of [toPage]\"";
}
if (finJSON.ContainsKey("customeargs"))
{
sb.Append(" " + finJSON["customeargs"].ToString().Replace("`", "\""));
}
if (finJSON.ContainsKey("rotate"))
{
finRotate[0] = "true";
finRotate[1] = finJSON["rotate"];
}
if (sb.ToString().Trim() == "")
{
//pdfConv.CustomWkHtmlArgs = "-O portrait";
}
else
{
pdfConv.CustomWkHtmlArgs = sb.ToString().Trim();
}
}
catch (Exception)
{
//pdfConv.CustomWkHtmlArgs = "-O portrait";
}
}
if (finRotate[0] == "true")
{
var pdfBytes = pdfConv.GeneratePdf(inHTML.ToString().Replace("⌐", "<").Replace("¬", ">"));
string tmpRfile = @"C:\PDFTools\rotate_" + Get8Digits() + ".pdf";
File.WriteAllBytes(tmpRfile, pdfBytes.ToArray());
rotatePDF(finRotate[1], tmpRfile);
FileStream fs = new FileStream(tmpRfile, FileMode.Open, FileAccess.Read);
byte[] filebytes = new byte[fs.Length];
fs.Read(filebytes, 0, Convert.ToInt32(fs.Length));
string encodedData = Convert.ToBase64String(filebytes, Base64FormattingOptions.InsertLineBreaks);
fs.Close();
bool fileDead = false;
while (fileDead == false)
{
fileDead = deletePDFFile(tmpRfile);
}
var buffer = Convert.FromBase64String(encodedData);
string whatI = "pdf";
bool showInline = false;
if (buffer != null)
{
if (whatI == "pdf")
{
HttpContext.Current.Response.ContentType = "Application/pdf";
}
else if (whatI == "doc")
{
HttpContext.Current.Response.ContentType = "Application/msword";
}
else if (whatI == "xls")
{
HttpContext.Current.Response.ContentType = "Application/x-msexcel";
}
else if (whatI == "dwf")
{
HttpContext.Current.Response.ContentType = "drawing/x-dwf";
}
string dispositionType = "";
if (showInline == true)
{
dispositionType = "inline;";
}
else
{
dispositionType = "attachment;";
}
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Clear();
//Response.ContentType = "drawing/x-dwf";
HttpContext.Current.Response.AddHeader("Content-Disposition", dispositionType + " filename=" + FileNamex);
HttpContext.Current.Response.AddHeader("content-length", buffer.Length.ToString());
HttpContext.Current.Response.BinaryWrite(buffer);
HttpContext.Current.Response.Flush();
//HttpContext.Current.Response.Clear();
//HttpContext.Current.Response.Headers.Clear();
//HttpContext.Current.Response.ContentType = "application/json";
//HttpContext.Current.Response.AddHeader("200", "Content-Type=application/json");
//HttpContext.Current.Response.Write("{\"status\":\"OK\"}");
//HttpContext.Current.Response.Status = "200 OK";
//HttpContext.Current.Response.StatusCode = 200;
HttpContext.Current.Response.End();
//HttpContext.Current.Response.SuppressContent = true;
//HttpContext.Current.ApplicationInstance.CompleteRequest();
}
//HttpContext.Current.Response.ContentType = "text/xml";
//HttpContext.Current.Response.ContentType = "text/json";
//HttpContext.Current.Response.Write("<script type=\"text/javascript\">var myBase64PDF=\"" + encodedData + "\";window.parent.postMessage(myBase64PDF, \"*\");</script>");
//HttpContext.Current.Response.End();
}
else
{
//var pdfBytes = pdfConv.GeneratePdf(System.Uri.UnescapeDataString(inHTML.ToString()));
var buffer = pdfConv.GeneratePdf(inHTML.ToString().Replace("⌐", "<").Replace("¬", ">"));
string whatI = "pdf";
bool showInline = false;
if (buffer != null)
{
if (whatI == "pdf")
{
HttpContext.Current.Response.ContentType = "Application/pdf";
}
else if (whatI == "doc")
{
HttpContext.Current.Response.ContentType = "Application/msword";
}
else if (whatI == "xls")
{
HttpContext.Current.Response.ContentType = "Application/x-msexcel";
}
else if (whatI == "dwf")
{
HttpContext.Current.Response.ContentType = "drawing/x-dwf";
}
string dispositionType = "";
if (showInline == true)
{
dispositionType = "inline;";
}
else
{
dispositionType = "attachment;";
}
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Clear();
//Response.ContentType = "drawing/x-dwf";
HttpContext.Current.Response.AddHeader("Content-Disposition", dispositionType + " filename=" + FileNamex);
HttpContext.Current.Response.AddHeader("content-length", buffer.Length.ToString());
HttpContext.Current.Response.BinaryWrite(buffer);
HttpContext.Current.Response.Flush();
//HttpContext.Current.Response.Clear();
//HttpContext.Current.Response.Headers.Clear();
//HttpContext.Current.Response.ContentType = "application/json";
//HttpContext.Current.Response.AddHeader("200", "Content-Type=application/json");
//HttpContext.Current.Response.Write("{\"status\":\"OK\"}");
//HttpContext.Current.Response.Status = "200 OK";
//HttpContext.Current.Response.StatusCode = 200;
//HttpContext.Current.Response.End();
//HttpContext.Current.Response.SuppressContent = true;
//HttpContext.Current.ApplicationInstance.CompleteRequest();
}
//HttpContext.Current.Response.ContentType = "text/xml";
//HttpContext.Current.Response.ContentType = "text/json";
//HttpContext.Current.Response.Write("<script type=\"text/javascript\">var myBase64PDF=\"" + System.Convert.ToBase64String(buffer) + "\";window.parent.postMessage(myBase64PDF, \"*\");</script>");
//HttpContext.Current.Response.End();
}
}
//catch (System.Threading.ThreadAbortException err)
//{
// System.Threading.Thread.ResetAbort();
//}
catch (Exception ex)
{
if (!ex.Message.ToString().Contains("Thread was being aborted"))
{
//HttpContext.Current.Response.ContentType = "text/xml";
//HttpContext.Current.Response.ContentType = "text/json";
HttpContext.Current.Response.Write("{\"error\":\"1\", \"errorCode\":" + jss.Serialize(ex.Message.ToString()) + "}");
//HttpContext.Current.Response.End();
//HttpContext.Current.Response.SuppressContent = true;
//HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
}
}
private void rotatePDF(string degrees, string xFileName)
{
try
{
FileInfo rFile = new FileInfo(xFileName);
string tempPDFfile = @"C:\PDFTools\rotate_" + Get8Digits() + "_" + rFile.Name;
System.IO.File.Move(xFileName, tempPDFfile);
if (degrees == "-90")
{
degrees = "1-endL";
}
else if (degrees == "90")
{
degrees = "1-endR";
}
else if (degrees == "180")
{
degrees = "1-endS";
}
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
process.StartInfo = startInfo;
process.Start();
StreamWriter sw = process.StandardInput;
if (sw.BaseStream.CanWrite)
{
try
{
sw.WriteLine("\"" + @"C:\PDFTools\pdftk.exe" + "\" \"" + tempPDFfile + "\" cat " + degrees + " output \"" + xFileName + "\" dont_ask");
//Writing the Command to Exit the CMD
sw.WriteLine("exit");
}
catch (Exception exxxz)
{
throw exxxz;
}
}
process.WaitForExit();
bool fileDead = false;
while (fileDead == false)
{
fileDead = deletePDFFile(tempPDFfile);
//Application.DoEvents();
}
}
catch (Exception ex)
{
throw ex;
}
}
private bool deletePDFFile(string xFile)
{
if (System.IO.File.Exists(xFile))
{
try
{
System.IO.File.Delete(xFile);
return true;
}
catch (Exception)
{
return false;
}
}
else
{
return true;
}
}
【问题讨论】:
-
验证 mime 类型的 http 标头。如果文件正在生成并且是从一个浏览器而不是另一个浏览器下载的,那么它可能不在生成问题所在的 pdf 的实际代码中。您还可以查看 IE 发出的请求与 Firefox 之间的区别。检查您的服务器日志以验证请求是否正在实际处理中。
标签: javascript c# jquery html pdf