首页 > 解决方案 > 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);
                     }
                 }*/
         }

标签: c#htmlitexthtml-to-pdf

解决方案


推荐阅读