我正在尝试使用 iTextSharper 制作带有页脚的 PDF。在大多数情况下,这工作正常。我想为每一页添加一个页脚。
我的代码确实正确添加了页脚,但是,正如您在图像中看到的那样,文本与 PDF 的内容重叠:
控制器动作:
public ActionResult GeneratePDF(int id)
{
Order order = db.Orders.Where(x => x.ID == id).SingleOrDefault();
return new HFPdfResult(order, "OrderPDF");
}
HFPDFResult ( ViewResult
) 类:
using System.Web.Mvc;
using RentproDC.Models.RazorPDF;
namespace RentproDC.Models.RazorPDF
{
public class HFPdfResult : ViewResult
{
//Constructors
public HFPdfResult(object model, string name)
{
ViewData = new ViewDataDictionary(model);
ViewName = name;
}
public HFPdfResult() : this(new ViewDataDictionary(), "Pdf")
{
}
public HFPdfResult(object model) : this(model, "Pdf")
{
}
//Override FindView to load PdfView
protected override ViewEngineResult FindView(ControllerContext context)
{
var result = base.FindView(context);
if (result.View == null)
return result;
var pdfView = new HFPdfView(result);
return new ViewEngineResult(pdfView, pdfView);
}
}
}
HFPDFView 类:
using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Web.Mvc;
using System.Xml;
using iTextSharp.text;
using iTextSharp.text.html;
using iTextSharp.text.pdf;
using iTextSharp.text.xml;
using iTextSharp.text.html.simpleparser;
using System.Collections.Generic;
namespace RentproDC.Models.RazorPDF
{
public class HFPdfView : IView, IViewEngine
{
private readonly ViewEngineResult _result;
public HFPdfView(ViewEngineResult result)
{
_result = result;
}
public void Render(ViewContext viewContext, TextWriter writer)
{
// generate view into string
var sb = new System.Text.StringBuilder();
TextWriter tw = new System.IO.StringWriter(sb);
_result.View.Render(viewContext, tw);
var resultCache = sb.ToString();
// detect itext (or html) format of response
XmlParser parser;
using (var reader = GetXmlReader(resultCache))
{
while (reader.Read() && reader.NodeType != XmlNodeType.Element)
{
// no-op
}
if (reader.NodeType == XmlNodeType.Element && reader.Name == "itext")
parser = new XmlParser();
else
parser = new HtmlParser();
}
// Create a document processing context
var document = new Document(PageSize.A4, 36, 36, 36, 120);
document.Header = new HeaderFooter(new Phrase("Test header"), false);
document.Open();
// associate output with response stream
var pdfWriter = PdfWriter.GetInstance(document, viewContext.HttpContext.Response.OutputStream);
pdfWriter.PageEvent = new PdfFileEvents();
pdfWriter.CloseStream = false;
// this is as close as we can get to being "success" before writing output
// so set the content type now
viewContext.HttpContext.Response.ContentType = "application/pdf";
// parse memory through document into output
using (var reader = GetXmlReader(resultCache))
{
parser.Go(document, reader);
}
pdfWriter.Close();
}
private static XmlTextReader GetXmlReader(string source)
{
byte[] byteArray = Encoding.UTF8.GetBytes(source);
MemoryStream stream = new MemoryStream(byteArray);
var xtr = new XmlTextReader(stream);
xtr.WhitespaceHandling = WhitespaceHandling.None; // Helps iTextSharp parse
return xtr;
}
public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName,
bool useCache)
{
throw new System.NotImplementedException();
}
public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName,
bool useCache)
{
throw new System.NotImplementedException();
}
public void ReleaseView(ControllerContext controllerContext, IView view)
{
_result.ViewEngine.ReleaseView(controllerContext, _result.View);
}
}
public class PdfFileEvents : PdfPageEventHelper
{
public override void OnEndPage(PdfWriter pi, Document doc)
{
PdfContentByte cb = pi.DirectContent;
ColumnText ct = new ColumnText(cb);
List list = new List(List.ORDERED);
string text = "<ol><li><span style='color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.12px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px; display: inline !important; float: none; background-color: rgb(255, 255, 255); font-size: 9px;'>"+RentProModels.Models.Settings.Get("CompanyName") + "<br />" + RentProModels.Models.Settings.Get("CompanyTelephone") + "<br />" +
RentProModels.Models.Settings.Get("CompanyEmail") + "<br />" +
"KVK " + "1234568789" + "<br />" +
"Bank ABN01Blahh12341</span></li></ol>";
ArrayList htmlarraylist = HTMLWorker.ParseToList(new StringReader(text), null);
for (int k = 0; k < htmlarraylist.Count; k++)
{
list.Add((IElement)htmlarraylist[k]);
}
ct.AddElement(list);
ct.SetSimpleColumn(500, 79, 900, 5); //curPos = verder naar boven
ct.Go();
}
public override void OnStartPage(PdfWriter pi, Document doc)
{
PdfContentByte cb = pi.DirectContent;
ColumnText ct = new ColumnText(cb);
cb.BeginText();
cb.SetFontAndSize(BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 12.0f);
cb.SetTextMatrix(doc.LeftMargin, doc.PageSize.Height - doc.TopMargin);
cb.ShowText(String.Format("{0} {1}", "Dit is een", "Header"));
cb.EndText();
}
}
}
订单视图(它将对象加载Order
到此视图中,并基于该视图生成 PDF):
@model RentPro.Models.Tables.Order
@using RentProModels.Models
@using RentPro.Models.Tables
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body style="font-size: 12px;">
<table width="100%" widths="60;40">
<row>
<td>
<newline />
<newline />
<h2 style="text-decoration:underline;">Pakbon</h2>
</td>
<td>
@* <img url="@System.Web.Hosting.HostingEnvironment.MapPath("/")@Settings.Get("PicturesPath") /../Images/@Settings.Get("LogoFile")" width="239" height="83" />*@
<newline />
<newline />
</td>
</row>
</table>
<table width="100%" cellpadding="0.0" widths="50;17;30">
@if (@Model.Delivery.Company != "nvt")
{
<row>
<cell>
<p style="font-weight:bold;">@Model.Delivery.Company</p>
</cell>
<cell></cell>
<cell></cell>
</row>
}
<row>
<cell><p style="font-weight:bold;">@Model.Delivery.FirstName @Model.Delivery.LastName</p></cell>
<cell>Order Nr:</cell>
<cell>@Model.ID</cell>
</row>
<row>
<cell><p style="font-weight:bold;">@Model.Delivery.StreetName @Model.Delivery.HouseNumber</p></cell>
<cell>Order Datum:</cell>
<cell>@Model.PlaceDate.ToShortDateString()</cell>
</row>
<row>
<cell><p style="font-weight:bold;">@Model.Delivery.ZipCode, @Model.Delivery.City</p></cell>
<cell>Transport:</cell>
<cell>@Model.TransportCarrier.Name</cell>
</row>
<row>
<cell><p style="font-weight:bold;">@Model.Phonenumber</p></cell>
<cell>Start Datum:</cell>
<cell>@Model.StartDate.ToShortDateString()</cell>
</row>
<row>
@{ string KVKofBTW;
if (Model.KVKnummer != null && Model.KVKnummer != "")
{
if (Model.Billing.Country.Name == "Nederland")
{
KVKofBTW = "KVK:";
}
else
{
KVKofBTW = "BTW:";
}
}
else
{
KVKofBTW = "";
}
}
<cell><p style="font-weight:bold;">@KVKofBTW @Model.KVKnummer</p></cell>
<cell>Eind Datum:</cell>
<cell>@Model.EndDate.ToShortDateString()</cell>
</row>
<row>
<cell></cell>
<cell>Aantal Dagen:</cell>
<cell>@((Model.EndDate.Date - Model.StartDate.Date).Days + 1)</cell>
</row>
<row>
<cell>Opmerkingen:</cell>
<cell></cell>
<cell></cell>
</row>
<row>
<cell colspan="3">@Model.Note</cell>
</row>
</table>
<table width="100%" widths="10;60" cellpadding="2">
<row>
<cell>
<newline />
</cell>
<cell></cell>
</row>
<row>
<cell><p style="font-style:italic;">Aantal</p></cell>
<cell><p style="font-style:italic;">Artikel</p></cell>
</row>
@foreach (var item in Model.Items)
{
<row>
<cell>@item.ProductCode</cell>
<cell>@item.Amount</cell>
<cell>@item.ProductTitle</cell>
<cell> [ ]</cell>
<cell> [ ]</cell>
<cell> [ ]</cell>
</row>
if (RentProModels.Models.Settings.GetBool("PakBonAccessory"))
{
foreach (RentPro.Models.Tables.Accessory accesory in item.Product.Accessories)
{
<row>
<cell></cell>
<cell></cell>
<cell>@accesory.Name</cell>
<cell> [ ]</cell>
<cell> [ ]</cell>
<cell> [ ]</cell>
</row>
}
}
}
</table>
<table width="100%" widths="60;50">
<row>
<cell>
<newline />
<newline />
<newline />
<newline />
<newline />
<newline />
</cell>
<cell></cell>
</row>
<row>
<cell>Handtekening voor ontvangst:</cell>
<cell>Retour ontvangen door:</cell>
</row>
<row>
<cell>Naam Klant:</cell>
<cell>Naam:</cell>
</row>
<row>
<cell>Handtekening:</cell>
<cell>Handtekening:</cell>
</row>
</table>
</body>
</html>
我看到一个关于设置文档大小的 SO 帖子,我这样做了,但它似乎不起作用:
var document = new Document(PageSize.A4, 36, 36, 36, 120);
我在底部给了它 120 个用户单位的边距,而我只使用了 110,为什么它仍然重叠?
任何帮助将不胜感激。