c# - ItextSharp PDF页眉页脚重复问题
问题描述
我使用了 Nuget Package 中的 Itextsharp 并将 HTML 解析为 PDF 并将字节传递到网站的前端并在 iframe 上显示 PDF。
首先,我有两个单独的 PDF 的 HTML,即一个用于标题,另一个用于正文。当我过去将 HTML 解析为 PDF 时,遇到的问题是标题的重复。页眉在第一页上工作正常,但在第二页上,页眉和正文相互重叠。我通过覆盖 OnStartPage 和 OnEndPage 函数进行了很多尝试,但没有任何效果。
其次,我通过 C# 代码尝试了标头,通过 HTML 尝试了正文,但这似乎也不起作用并且遇到了同样的问题。
我认为主要问题是分页符(如果我错了,请纠正我)。如果社区中的任何人可以帮助我,请继续前进。我正在分享代码,非常感谢所有帮助。
如果缺少任何代码,请告诉我。我需要每个页面上的标题都需要保持一致但具有动态内容。
using System;
using System.Collections.Generic;
using iTextSharp.text.html.simpleparser;
namespace WebApi.Controllers
{
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using iTextSharp.tool.xml.css;
using iTextSharp.tool.xml.html;
using iTextSharp.tool.xml.parser;
using iTextSharp.tool.xml.pipeline.css;
using iTextSharp.tool.xml.pipeline.end;
using iTextSharp.tool.xml.pipeline.html;
using System.IO;
using System.Text;
using System.Web.Mvc;
public class PDFGenerateController : Controller
{
[NonAction]
public byte[] Index(IModel iModel)
{
// get HTML for body
var html = GetHtml(iModel, false);
byte[] bytes;
Document pdfDocument = new Document(PageSize.A4);
using (MemoryStream memoryStream = new MemoryStream())
{
PdfWriter writer = PdfWriter.GetInstance(pdfDocument, memoryStream);
AddImageToHeader pageEventHandler = new AddImageToHeader(GetHtml(processedData, true)); // get html for header right side
IHeaderFooter iHeaderFooter = new IHeaderFooter(GetHtml(processedData, true)); // get html for header right side
writer.PageEvent = iHeaderFooter;
writer.PageEvent = pageEventHandler;
writer.PageEvent = new HeaderFooterAdd(iModel);
writer.CloseStream = false;
pdfDocument.Open();
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
cssResolver.AddCssFile("C:/pdf.css", true);
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext,
new PdfWriterPipeline(pdfDocument, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser xmlParser = new XMLParser(worker);
xmlParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(html)));
pdfDocument.Close();
bytes = memoryStream.GetBuffer();
memoryStream.Close();
}
return bytes;
}
public class iHeaderFooter : PdfPageEventHelper
{
private readonly string _html;
public iHeaderFooter(string html)
{
_html = html;
}
public override void OnStartPage(PdfWriter writer, Document document)
{
var cssResolver = new StyleAttrCSSResolver();
XMLWorkerFontProvider fontProvider =
new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html1 = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html1);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.Parse(new StringReader(_html));
//for page break but didn't worked out
/*using (TextReader htmlViewReader = new StringReader(_html))
{
using (var htmlWorker = new HeaderFooterAdd.HTMLWorkerExtended(document))
{
htmlWorker.Open();
htmlWorker.Parse(htmlViewReader);
}
}*/
base.OnStartPage(writer, document);
}
}
}
// Add logo image to header left side
public class AddImageToHeader : PdfPageEventHelper
{
private readonly string _html;
public AddImageToHeader(string html)
{
_html = html;
}
public override void OnStartPage(PdfWriter writer, Document document)
{
iTextSharp.text.Image imghead = iTextSharp.text.Image.GetInstance("C:/logo.png");
imghead.ScaleAbsolute(189f, 79f);
imghead.SetAbsolutePosition(30, 0);
PdfContentByte cbhead = writer.DirectContent;
PdfTemplate tp = cbhead.CreateTemplate(320, 100);
tp.AddImage(imghead);
cbhead.AddTemplate(tp, 0, 830 - 95);
base.OnStartPage(writer, document);
}
}
public class HeaderFooterAdd : PdfPageEventHelper
{
//C# Header
public override void OnEndPage(PdfWriter writer, Document document)
{
PdfPTable tbHeader = new PdfPTable(2);
tbHeader.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin;
tbHeader.DefaultCell.Border = Rectangle.NO_BORDER;
tbHeader.DefaultCell.BorderWidth = 0;
tbHeader.DefaultCell.Top = 100;
tbHeader.DefaultCell.Bottom = 100;
tbHeader.AddCell(new Paragraph());
Phrase datePhrase = new Phrase(new Chunk($"{"Label"}: {"Text"}\n", FontFactory.GetFont(FontFactory.TIMES, 10, Font.NORMAL, BaseColor.BLACK)));
PdfPCell _cell = new PdfPCell(datePhrase);
_cell.HorizontalAlignment = Element.ALIGN_RIGHT;
_cell.BorderWidthBottom = 0f;
_cell.BorderWidthLeft = 0f;
_cell.BorderWidthTop = 0f;
_cell.BorderWidthRight = 0f;
_cell.PaddingTop = 45f;
_cell.ExtraParagraphSpace = 2f;
tbHeader.AddCell(_cell);
tbHeader.AddCell(new Paragraph());
tbHeader.WriteSelectedRows(0, -1, document.Left,
writer.PageSize.GetTop(document.TopMargin) + 40,
writer.DirectContent);
}
//for page break but didn't worked out
/*public class HTMLWorkerExtended : HTMLWorker
{
public HTMLWorkerExtended(IDocListener document) :
base(document)
{
}
public override void StartElement(string tag,
IDictionary<string, string> str)
{
if (tag.Equals("newpage"))
document.Add(Chunk.NEXTPAGE);
else
base.StartElement(tag, str);
}
}*/
}
解决方案
推荐阅读
- java - JTextArea 和 JButton。将焦点设置在按钮上
- javascript - 用jquery拖放(一个工具箱和一个报表窗口)
- asp.net-core - Microsoft Distrubted Redis Cache - 根据模式获取密钥
- python-3.x - 为什么这个 Python 脚本不会用另一个变量替换一个变量?
- javascript - 下拉列表和 Javascript
- android - Android Studio 连接到 asp.net API 时出错
- android - 图片网址未在毕加索中加载
- bash - 从任意深度的子shell跳转到顶层父shell
- javascript - 从视频中提取特定时间的帧
- javascript - 在 Edge 浏览器中加载 GWT 页面/项目比 Chrome 和 Safari 浏览器花费更多时间