public static bool CreatePdf(Stream output, Config config) { using (MemoryStream ms = new MemoryStream()) { using (Document document = new Document(PageSize.LETTER)) using (PdfWriter writer = PdfWriter.GetInstance(document, ms)) { document.AddTitle($"{config.website} - {config.title}"); document.AddAuthor($"{config.website}"); document.AddSubject(config.title); document.AddKeywords($"{config.keywords}"); document.AddCreator($"{config.creator}"); document.AddCreationDate(); document.AddLanguage("en"); document.Open(); document.SetPageSize(PageSize.LETTER); float w = document.PageSize.Width - document.LeftMargin - document.RightMargin; float h = document.PageSize.Height - document.TopMargin - document.BottomMargin; float headerInfoHeight = 68; float headerHeight = h / 16; float headerImageHeight = headerHeight + document.TopMargin + headerInfoHeight; float headerImageWidth = (headerImageHeight * 640.0f) / 480.0f; float headerWidth = w - headerImageWidth; float headerTitleHeight = headerImageHeight - headerInfoHeight; Rectangle[] bodyLayoutRects = new Rectangle[] { // // Page 1 // new Rectangle(0, 0, 0, 0), new Rectangle(0, 0, 0, 0), // // Page 2+ // new Rectangle(0, 0, 0, 0), new Rectangle(0, 0, 0, 0), // // Footer // new Rectangle(0, 0, 0, 0), }; Font fontTitle = new Font(Font.FontFamily.HELVETICA, 16, Font.BOLD, BaseColor.DARK_GRAY); Font fontPrimaryInfo = new Font(Font.FontFamily.HELVETICA, 8, Font.BOLD, BaseColor.DARK_GRAY); Font fontSecondaryInfo = new Font(Font.FontFamily.HELVETICA, 8, Font.NORMAL, BaseColor.DARK_GRAY); Font fontFooter = new Font(Font.FontFamily.HELVETICA, 6, Font.NORMAL, BaseColor.GRAY); Font fontBodyNormal = new Font(Font.FontFamily.HELVETICA, 8, Font.NORMAL, BaseColor.BLACK); Font fontBodyHeader = new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD, BaseColor.DARK_GRAY); Font fontBodyHeaderMinor = new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD, BaseColor.DARK_GRAY); bodyLayoutRects[2].Left = bodyLayoutRects[0].Left = document.LeftMargin; bodyLayoutRects[1].Top = bodyLayoutRects[0].Top = document.TopMargin; bodyLayoutRects[2].Right = bodyLayoutRects[0].Right = bodyLayoutRects[0].Left + ((w / 2) - (document.LeftMargin / 2)); bodyLayoutRects[1].Bottom = bodyLayoutRects[0].Bottom = bodyLayoutRects[0].Top + (h - (headerImageHeight - document.TopMargin / 2.0f)); bodyLayoutRects[3].Left = bodyLayoutRects[1].Left = document.LeftMargin + (w / 2) + (document.LeftMargin / 2); bodyLayoutRects[3].Right = bodyLayoutRects[1].Right = bodyLayoutRects[1].Left + ((w / 2) - (document.LeftMargin)); bodyLayoutRects[3].Top = bodyLayoutRects[2].Top = document.TopMargin; bodyLayoutRects[3].Bottom = bodyLayoutRects[2].Bottom = bodyLayoutRects[2].Top + (h - (document.TopMargin / 2.0f)); bodyLayoutRects[4].Left = document.LeftMargin; bodyLayoutRects[4].Right = w; bodyLayoutRects[4].Top = 0; bodyLayoutRects[4].Bottom = document.TopMargin / 2; Rectangle[] headerLayoutRects = new Rectangle[] { // // Title // new Rectangle(0, 0, 0, 0), // // Info // new Rectangle(0, 0, 0, 0), }; headerLayoutRects[0].Left = document.LeftMargin; headerLayoutRects[0].Top = document.PageSize.Height - (headerTitleHeight + document.TopMargin / 2); headerLayoutRects[0].Right = headerLayoutRects[0].Left + headerWidth; headerLayoutRects[0].Bottom = headerLayoutRects[0].Top + headerTitleHeight; headerLayoutRects[1].Left = document.LeftMargin; headerLayoutRects[1].Top = document.PageSize.Height - headerImageHeight + 4; headerLayoutRects[1].Right = headerLayoutRects[1].Left + headerWidth; headerLayoutRects[1].Bottom = headerLayoutRects[1].Top + headerInfoHeight; // // Cover Image // System.Drawing.Image sysCoverImage = CreateCoverImage(config.imageUrl, config.overlayUrl, headerImageWidth * 4, headerImageHeight * 4); if (sysCoverImage != null) { iTextSharp.text.Image coverImage = iTextSharp.text.Image.GetInstance(sysCoverImage, System.Drawing.Imaging.ImageFormat.Jpeg); if (coverImage != null) { coverImage.SetAbsolutePosition(document.PageSize.Width - headerImageWidth, document.PageSize.Height - headerImageHeight); coverImage.ScaleToFit(headerImageWidth, headerImageHeight); document.Add(coverImage); } } ColumnText ct = new ColumnText(writer.DirectContent); // // Title // { Paragraph p = new Paragraph(); p.Alignment = Element.ALIGN_CENTER; p.Font = fontTitle; p.Add(config.title); ct.AddElement(p); p = new Paragraph(); p.Alignment = Element.ALIGN_CENTER; p.Font = fontPrimaryInfo; p.Add(config.subHeader1); ct.AddElement(p); ct.SetSimpleColumn(headerLayoutRects[0]); ct.Go(); } // // Info // { Paragraph p = new Paragraph(); p.Alignment = Element.ALIGN_CENTER; p.Font = fontSecondaryInfo; Html2PdfContext ctxSubHeader = new Html2PdfContext() { defaultFontSize = fontSecondaryInfo.Size, defaultAlignment = Element.ALIGN_CENTER, bodyFont = fontSecondaryInfo, bodyFontHeader = fontSecondaryInfo, bodyFontHeaderMinor = fontSecondaryInfo, }; List <IElement> elementsNutrition = ParseHTML(config.subHeader2, ctxSubHeader); foreach (IElement el in elementsNutrition) { if (el is Paragraph) { ((Paragraph)el).Alignment = Element.ALIGN_CENTER; } ct.AddElement(el); } ct.SetSimpleColumn(headerLayoutRects[1]); ct.Alignment = Element.ALIGN_CENTER; ct.Go(); } Html2PdfContext ctx = new Html2PdfContext() { defaultFontSize = fontBodyNormal.Size, bodyFont = fontBodyNormal, bodyFontHeader = fontBodyHeader, bodyFontHeaderMinor = fontBodyHeaderMinor, }; List <IElement> elements = ParseHTML(config.body, ctx); foreach (IElement el in elements) { ct.AddElement(el); } int c = 0; int status = 0; while (ColumnText.HasMoreText(status)) { ct.SetSimpleColumn(bodyLayoutRects[c]); status = ct.Go(); ++c; if (c == 2) { ColumnText.ShowTextAligned(writer.DirectContentUnder, Element.ALIGN_CENTER, new Phrase(config.footer, fontFooter), (bodyLayoutRects[4].Left + bodyLayoutRects[4].Right) / 2, bodyLayoutRects[4].Bottom - (fontFooter.Size / 2), 0); document.NewPage(); } else if (c == 4) { ColumnText.ShowTextAligned(writer.DirectContentUnder, Element.ALIGN_CENTER, new Phrase(config.footer, fontFooter), (bodyLayoutRects[4].Left + bodyLayoutRects[4].Right) / 2, bodyLayoutRects[4].Bottom - (fontFooter.Size / 2), 0); document.NewPage(); c = 2; } } // // needed to ensure we dont access the stream // document.Close(); } MemoryStream msReadFrom = new MemoryStream(ms.GetBuffer()); EncryptPdf(msReadFrom, output); } return(true); }
private static List <IElement> ParseHTML(string rawHtml, Html2PdfContext ctx) { List <IElement> elements = new List <IElement>(); MatchCollection matches = _findHtmlToken.Matches(rawHtml); StringBuilder sb = new StringBuilder(); int lastIndex = 0; foreach (Match match in matches) { int textToEatLen = match.Index - lastIndex; if (textToEatLen > 0) { string textToEat = rawHtml.Substring(lastIndex, textToEatLen); sb.Append(textToEat); } string cleanPara = CleanupParagraph(sb.ToString()); bool isOpeningTag = true; if (match.Groups[1].Value == "</") { isOpeningTag = false; } string tag = match.Groups[2].Value.ToLower(); if (isOpeningTag) { ctx.EatText(cleanPara, elements); sb.Clear(); if (tag == "strong") { ctx.PushChunkFontStyle(Html2PdfContext.ChunkFontStyle.Strong); } else if (tag == "em") { ctx.PushChunkFontStyle(Html2PdfContext.ChunkFontStyle.Emphasis); } else if (tag == "a") { Match hrefMatch = _findHrefLink.Match(match.Value); if (hrefMatch.Success) { string url = hrefMatch.Groups[1].Value; ctx.currentAnchor = new Anchor(); ctx.currentAnchor.Font = new Font(ctx.bodyFont.BaseFont, ctx.CurrentChunkFontSize, Font.UNDERLINE, ctx.bodyFont.Color); ctx.currentAnchor.Reference = url; if (ctx.currentListItem != null) { ctx.currentListItem.Add(ctx.currentAnchor); } else if (ctx.currentParagraph != null) { ctx.currentParagraph.Add(ctx.currentAnchor); } } } else if (tag == "ul") { List list = new List(false, false, ctx.bodyFont.Size * 1.5f); list.ListSymbol = new Chunk(""); elements.Add(list); ctx.currentList = list; ctx.hasListItems = false; } else if (tag == "ol") { List list = new List(true, false, ctx.bodyFont.Size * 1.5f); elements.Add(list); ctx.currentList = list; ctx.hasListItems = false; } else if (tag == "li") { if (ctx.currentList == null) { List list = new List(false, false); elements.Add(list); ctx.currentList = list; } ListItem li = new ListItem(); li.SpacingBefore = 4; li.Font = ctx.bodyFont; ctx.currentList.Add(li); ctx.currentListItem = li; ctx.hasListItems = true; } else if (tag == "h1" || tag == "h2" || tag == "h3") { ctx.CreateParagraph(Html2PdfContext.ParaStyle.Header, elements); ctx.PushChunkFontSize(ctx.bodyFontHeader.Size); } else if (tag == "h4" || tag == "h5" || tag == "h6") { ctx.CreateParagraph(Html2PdfContext.ParaStyle.HeaderMinor, elements); ctx.PushChunkFontSize(ctx.bodyFontHeaderMinor.Size); } else if (IsBlockElementTag(tag)) { ctx.CreateParagraph(Html2PdfContext.ParaStyle.Body, elements); ctx.PushChunkFontSize(ctx.bodyFont.Size); } else if (IsLineBreakingTag(tag)) { sb.Append("\n"); } } else { ctx.EatText(cleanPara, elements); sb.Clear(); if (tag == "strong" || tag == "em") { ctx.PopChunkFontStyle(); } else if (tag == "h1" || tag == "h2" || tag == "h3" || tag == "h4" || tag == "h5" || tag == "h6" || IsBlockElementTag(tag)) { ctx.PopChunkFontSize(); } if (tag == "li") { ctx.currentListItem = null; } else if (tag == "ol" || tag == "ul") { ctx.currentListItem = null; ctx.currentList = null; if (ctx.hasListItems) { // // todo: Extra spacing after a list? // // elements.Add(new Paragraph("")); ctx.hasListItems = false; } } else if (tag == "a") { ctx.currentAnchor = null; } } lastIndex = match.Index + match.Length; } if (lastIndex < rawHtml.Length) { string textToEat = rawHtml.Substring(lastIndex); textToEat = CleanupParagraph(textToEat); ctx.EatText(textToEat, elements); } List <IElement> elementsToRemove = new List <IElement>(); foreach (IElement element in elements) { if (element is Paragraph) { Paragraph p = (Paragraph)element; if (p.Count >= 1 && p.Content.Trim().Length == 0) { elementsToRemove.Add(p); } } } foreach (IElement elementToRemove in elementsToRemove) { elements.Remove(elementToRemove); } return(elements); }