【发布时间】:2015-01-15 22:07:24
【问题描述】:
我正在尝试将 cshtml 文件发布到 PDF,但是当 PDF 呈现时,所有 html 格式都丢失了。我认为问题可能是我需要将视图呈现为一个字符串,就像这个例子中的 Render View As String 一样,但我没有使用 MVC,而且我对这个过程的理解不够好,无法确定如何从这个例子中推断出来。如何让视图呈现,以免丢失 HTML 格式?
以下是代码的设置方式:
public class PrintTemplate<T> : RazorEngine.Templating.TemplateBase<T>
{
public new T Model { get; set; }
public PrintTemplate()
{
//TODO: Add Constructor Logic
}
}
public class ViewPage
{
public string Body { get; set; }
}
public static class PrintPDFBO
{
public static ViewPage PrintPDF(id)
{
var newPrint = new ViewPage();
var pdf = GetDataForPDF(id);
newPrint.Body += RazorEngine.Razor.Parse(PrintPDFUtil.GetPrintTemplate(id), pdf, id.ToString());
newPrint.Body += "</body></html>";
return newPrint;
}
}
protected void btnPrintPDF_OnClick(object sender, EventArgs e)
{
var content = new ViewPage();
content = PrintPDFBO.PrintPDF(id);
title = DateTime.Now + "My Title";
}
UPDATE: I've tried depositing the text from my view into a panel then outputting the panel but
the result is the same, no formatting
protected void PrintablePdf(ViewPage view, string title)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;fileName=" + title);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
//StringBuilder sb = new StringBuilder(view.Body);
divPrint.InnerHtml = view.Body.ToString();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(sw);
pnlPrint.RenderControl(hw);
StringReader sr = new StringReader(sw.ToString());
Document pdf = new Document(PageSize.A4, 50f, 50f, 50f, 50f);
HTMLWorker htmlparser = new HTMLWorker(pdf);
PdfWriter.GetInstance(pdf, Response.OutputStream);
pdf.Open();
htmlparser.Parse(sr);
pdf.Close();
}
更新预期输出:
cshtml的内容:
@using Print.DataType
@using Print.Data
@inherits PrintTemplate<PDFPrint>
@*Start*@
<div style="border: 1px solid black; width: 7in; height: 2in;">
<div style="width: 3.5in; height: 2in; padding: 1em; float: left;">
<div>
<div style="float:left; width: 2.5in;">
<div style="border-bottom: 1px solid black; border-right: 1px solid black; height: .3in; padding-top: .25em;">
<span style="font-weight: bold;">OPERATOR</span>
</div>
<div style="border-right: 1px solid black; height: .27in;">
<div style="vertical-align: top;">NAME OF OPERATOR</div>
<div>@Model.Name</div>
</div>
</div>
<div style="float: left; width: 1in;">
<div style="border-bottom: 1px solid black;">
<div style="vertical-align: top;">CARD NO.</div>
<div>@Model.CardNo</div>
</div>
<div style="border-bottom: 1px solid black;">
<div style="vertical-align: top;">DATE ISSUED</div>
<div>@Model.IssueDate.ToShortDateString()</div>
</div>
<div>
<div style="vertical-align: top;">DATE EXPIRES</div>
<div>@Model.Expiration.ToShortDateString()</div>
</div>
</div>
</div>
我希望在 pdf 中看到的是一个带有实线边框的分区、多行每行都有一个边框、在某些情况下是粗体文本以及具有特定宽度的多个内部分区。
我得到的只是这个,没有格式:
名称 日期 时间
但是,html 的字符串在到达字符串生成器时是完整的,因此 Razor 可以正确输出它。
更新 - 新页面的实现:
所以我发现一篇关于将 asp.net 面板输出到 PDF 的帖子,有人建议它可以工作的两种方法是创建一个新页面,将内容放在面板中,然后尝试打印到 PDF 或执行它作为服务器上的流。所以我决定将我的代码移动到一个新页面,这样至少我可以在一个页面上看到从 cshtml 页面生成的输出 Razor 并确定它是否实际上是完整的,所有的边框样式和字体都发生了变化和宽度/高度似乎完好无损。然后从那里我尝试对面板进行正常的 PDF 打印,但在打印为 PDF 后仍然丢失了所有格式。我添加的一段代码只是调用 PrintablePdf() 函数的按钮的函数调用,在页面加载时,我添加了一行,以便在填充内容时将其添加到面板中,如下所示: divPrint.InnerHtml = content.Body;
更新:(无分辨率) 根据下面的第一个建议,我将 Printable PDF 更改为: (更正这里我在应该读取 StringReader 时键入了 StringBuilder)
protected void PrintablePdf(string title, string body)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;fileName=" + title);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Document pdf = new Document(PageSize.A4, 50f, 50f, 50f, 50f);
HTMLWorker htmlparser = new HTMLWorker(pdf);
PdfWriter.GetInstance(pdf, Response.OutputStream);
pdf.Open();
htmlparser.Parse(new StringReader(body));
pdf.Close();
}
最终更新解决方案:
最后,我没有尝试使用 CSHTML 以按照我需要的方式保留 PDf 中的布局。我最终不得不求助于使用 ITextSharp 的 PdfPTable、PdfPCell 和其他功能在代码隐藏中动态创建 PDF 来手动构建 pdf。我对完成所需布局所需的大量嵌套表并不感到兴奋,而且代码看起来非常复杂,但是我能够将一些部分减少为可重用的方法调用。
【问题讨论】:
-
“html 格式”是什么意思? Razor.Parse 将根据您传递给它的模板的内容返回一个 HTML 格式的字符串。什么是它不会错误地提供输入和实际输出与预期输出。
-
我已更新信息以包含 cshtml 和预期输出,谢谢。
-
您使用哪个库来生成 PDF?
-
我在页面上使用 iTextSharp.text、iTextSharp.html 和 iTextSharp.pdf。