using System; using System.Collections.Generic; using System.Text; using VEPROMS.CSLA.Library; using iTextSharp.text.pdf; using iTextSharp.text; using System.IO; using VEPROMS.CSLA.Library; using System.Text.RegularExpressions; //using Volian.Generic; namespace Volian.Print.Library { public class PDFReport { private ICollection _ResultList; public ICollection ResultList { get { return _ResultList; } set { _ResultList = value; } } private string _FileName; public string FileName { get { return _FileName; } set { _FileName = value; } } private string _ReportTitle; public string ReportTitle { get { return _ReportTitle; } set { _ReportTitle = value; } } private string _TypesSelected; public string TypesSelected { get { return _TypesSelected; } set { _TypesSelected = value; } } private bool _ShowAnnotations = true; public bool ShowAnnotations { get { return _ShowAnnotations; } set { _ShowAnnotations = value; } } private string _SearchString; public string SearchString { get { return _SearchString; } set { _SearchString = VEPROMS.CSLA.Library.ItemInfo.ConvertToDisplayText(value); } } public PDFReport(string reportTitle, string typesSelected, ICollection resultList, string fileName) { _ResultList = resultList; _FileName = fileName; _ReportTitle = VEPROMS.CSLA.Library.ItemInfo.ConvertToDisplayText(reportTitle); _TypesSelected = VEPROMS.CSLA.Library.ItemInfo.ConvertToDisplayText(typesSelected); } //public void Build2() //{ // iTextSharp.text.Document document = new iTextSharp.text.Document(PageSize.LETTER, 36, 36, 36, 36); // try // { // PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(_FileName, FileMode.Create)); // // we add some meta information to the document // document.SetMargins(36, 36, 36, 36); // // step 3: we open the document // document.Open(); // AddTable(document, 20, 80); // //AddTable(document, 10, 90); // //AddTable(document, 10, 100); // //AddTable(document, 15, 75); // //AddTable(document, 20, 70); // //AddTable(document, 25, 65); // //AddTable(document, 30, 60); // document.Close(); // } // catch (Exception ex) // { // } //} //private void AddTable(iTextSharp.text.Document document, int width1, int width2) //{ // float[] headerwidths = { width1, width2 }; // PdfPTable datatable = new PdfPTable(headerwidths); // datatable.HeaderRows = 3; // datatable.FooterRows = 1; // //datatable.Padding = 4; // //datatable.DefaultCell.Padding = 4; // //datatable.Spacing = 0; // //datatable.setBorder(Rectangle.NO_BORDER); // //datatable.Widths = headerwidths; // //datatable.WidthPercentage = 100; // datatable.TotalWidth = (width1 + width2) * 5; // datatable.LockedWidth = true; // // the first cell spans 10 columns // //iTextSharp.text.Font f1 = FontFactory.GetFont("Arial Unicode MS", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 14, Font.BOLD); // iTextSharp.text.Font f1 = pdf.GetFont("Arial Unicode MS", 14, 1, Color.BLACK); // PdfPCell cell = new PdfPCell(new Phrase(ReportTitle, f1)); // //Font f2 = FontFactory.GetFont(FontFactory.HELVETICA, 10); // //FontFactory.RegisterDirectory(FontFind.FontDir); // //iTextSharp.text.Font f2 = FontFactory.GetFont("Arial Unicode MS", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 10); // iTextSharp.text.Font f2 = pdf.GetFont("Arial Unicode MS", 10, 0, Color.BLACK); // //iTextSharp.text.Font f3 = FontFactory.GetFont("Prestige Elite Tall", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 9); // iTextSharp.text.Font f3 = pdf.GetFont("Prestige Elite Tall", 9, 0, Color.BLACK); // cell.HorizontalAlignment = Element.ALIGN_CENTER; // //cell.Leading = 20; // cell.Colspan = 2; // //cell.Border = Rectangle.NO_BORDER; // cell.BackgroundColor = new Color(0xD0, 0xF0, 0xF0); // datatable.AddCell(cell); // Color subHeaderColor = new Color(0xD0, 0xF0, 0xD0); // // These cells span 2 rows // //datatable.DefaultCellBorderWidth = 2; // //datatable.DefaultHorizontalAlignment = 1; // //datatable.DefaultRowspan = 2; // datatable.DefaultCell.Padding = 4; // datatable.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER; // AddCell(datatable, "Step", f2, subHeaderColor); // AddCell(datatable, "Text", f2, subHeaderColor); // AddCell(datatable, "Step", f2, subHeaderColor); // AddCell(datatable, "Text", f2, subHeaderColor); // datatable.DefaultCell.HorizontalAlignment = Element.ALIGN_LEFT; // //datatable.DefaultCellBorderWidth = 1; // //datatable.DefaultRowspan = 1; // //datatable.DefaultHorizontalAlignment = Element.ALIGN_LEFT; // string lastDvPath = ""; // string lastPath = ""; // Color AnnoColor = new Color(0xFF, 0xFF, 0xC0); // Color TextColor = Color.WHITE; // Color SectColor = Color.LIGHT_GRAY; // foreach (ItemInfo item in _ResultList) // { // if (item.SearchDVPath != lastDvPath) // AddGroup(datatable, item.SearchDVPath, lastDvPath, f2, false, new Color(0xC0, 0xFF, 0xC0)); // lastDvPath = item.SearchDVPath; // //if (item.SearchPath != lastPath) // string stepPath = AddGroup(datatable, item.SearchPath, lastPath, f2, true, new Color(0xE0, 0xFF, 0xE0)); // lastPath = item.SearchPath; // AddCell(datatable, stepPath, f2, (item.IsSection ? SectColor : TextColor)); // if (item.DisplayText.Contains("|")) // Need a better way to determine if it is a table. // AddCell(datatable, item.DisplayText, f3, TextColor); // else // AddCell(datatable, item.DisplayText, f2, (item.IsSection ? SectColor : TextColor)); // if (item.ItemAnnotationCount > 0) // { // foreach (AnnotationInfo ai in item.ItemAnnotations) // { // AddCell(datatable, ai.MyAnnotationType.Name, f2, AnnoColor); // AddCell(datatable, ai.SearchText, f2, AnnoColor); // } // } // } // document.Add(datatable); //} //private static void AddCell(PdfPTable datatable, string str, iTextSharp.text.Font fnt, Color bgColor) //{ // PdfPCell cell = new PdfPCell(new Phrase(str, fnt)); // cell.BackgroundColor = bgColor; // datatable.AddCell(cell); //} private string AddGroup(PdfPTable datatable, string dvPath, string lastDvPath, Font f2, bool StripLast, Color bgColor) { int level = 0; string retval = ""; StringBuilder sb = new StringBuilder(); string ttt = dvPath.Replace("\x11", " "); string[] OldPath = lastDvPath.Split("\x7".ToCharArray()); string[] NewPath = dvPath.Split("\x7".ToCharArray()); string sep = ""; bool foundMisMatch = false; int n = NewPath.Length; if (StripLast) { retval = NewPath[--n]; if (retval.Contains("\x11")) retval = retval.Substring(0, retval.IndexOf("\x11")); } for (int j = 0; j < n; j++) { if (NewPath[j] != "" && (foundMisMatch || OldPath.Length < j + 1 || NewPath[j] != OldPath[j])) { sb.Append(sep + "".PadLeft(2 * level) + NewPath[j].Replace("\x11", " ")).Replace(@"\u8209?", "-"); sep = "\r\n"; foundMisMatch = true; } level++; } if (sb.ToString() != "") { PdfPCell cell = new PdfPCell(new Phrase(sb.ToString(), f2)); cell.Colspan = 2; cell.BackgroundColor = bgColor; cell.BorderWidthTop = 1; datatable.AddCell(cell); } return retval; } public void Build() { iTextSharp.text.Document document = new iTextSharp.text.Document(PageSize.LETTER, 36, 36, 36, 36); if (!CreateResultsPDF(document)) return; try { BuildTable1(document); } catch (Exception ex) { StringBuilder msg = new StringBuilder(); document.Add(new Paragraph("Error:")); while (ex != null) { document.Add(new Paragraph(ex.GetType().Name)); document.Add(new Paragraph(ex.Message)); ex = ex.InnerException; } } finally { if (document.IsOpen()) { document.Close(); System.Diagnostics.Process.Start(_FileName); } } } /// /// Attempt to open a file for the PDF output. /// If the file cannot be opened because it is in use, try adding a suffix /// If the file cannot be opened for some other reason, display an error message /// /// /// private bool CreateResultsPDF(iTextSharp.text.Document document) { bool result = false; string suffix = ""; int i = 0; // Try to open a file for creating the PDF. while (result == false) { string fileName = _FileName.ToLower().Replace(".pdf", suffix + ".pdf"); try { PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(fileName, FileMode.Create)); writer.PageEvent = new MyPageHelper(); // JSJ - 7/8/2011 document.SetMargins(36, 36, 36, 36); document.Open(); _FileName = fileName; result = true; } catch (System.IO.IOException exIO) { if (exIO.Message.Contains("because it is being used by another process")) suffix = string.Format("_{0}", ++i);// If this file is in use, increment the suffix and try again else // If some other error, display a message and don't print the results { ShowException(exIO); return false; } } catch (Exception ex) { ShowException(ex); return false; // Could not open the output file } } return true; } private static void ShowException(Exception ex) { Console.WriteLine("{0} - {1}", ex.GetType().Name, ex.Message); StringBuilder msg = new StringBuilder(); string sep = ""; string indent = ""; while (ex != null) { msg.Append(string.Format("{0}{1}{2}:\r\n{1}{3}", sep, indent, ex.GetType().Name, ex.Message)); ex = ex.InnerException; sep = "\r\n"; indent += " "; } System.Windows.Forms.MessageBox.Show(msg.ToString(), "Error during PDF creation for search:", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation); } /// /// Use Cells within Cells to see if I can limit the way Cells break from Page to Page /// /// private void BuildTable1(iTextSharp.text.Document document) { float[] headerwidths = { 20, 80 }; PdfPTable datatable = new PdfPTable(headerwidths); datatable.HeaderRows = 3; //datatable.FooterRows = 1; datatable.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin; datatable.LockedWidth = true; //FontFactory.RegisterDirectory(FontFind.FontDir); //iTextSharp.text.Font f1 = FontFactory.GetFont("Arial Unicode MS", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 14, Font.BOLD); //iTextSharp.text.Font f2 = FontFactory.GetFont("Arial Unicode MS", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 10); //iTextSharp.text.Font f3 = FontFactory.GetFont("Prestige Elite Tall", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 9); iTextSharp.text.Font f1 = pdf.GetFont("Arial Unicode MS", 14, 1, Color.BLACK); iTextSharp.text.Font f2 = pdf.GetFont("Arial Unicode MS", 10, 0, Color.BLACK); iTextSharp.text.Font f3 = pdf.GetFont("Arial Unicode MS", 12, 0, Color.BLACK); //iTextSharp.text.Font f3 = pdf.GetFont("Prestige Elite Tall", 9, 0, Color.BLACK); PdfPCell cell = new PdfPCell(new Phrase(ReportTitle, f1)); cell.HorizontalAlignment = Element.ALIGN_CENTER; cell.Colspan = 2; cell.BackgroundColor = new Color(0xD0, 0xF0, 0xF0); datatable.AddCell(cell); cell = new PdfPCell(new Phrase(TypesSelected,f3)); cell.HorizontalAlignment = Element.ALIGN_LEFT; cell.Colspan = 2; cell.BackgroundColor = new Color(0xD0, 0xF0, 0xF0); datatable.AddCell(cell); Color subHeaderColor = new Color(0xD0, 0xF0, 0xD0); datatable.DefaultCell.Padding = 4; datatable.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER; AddCell(datatable, "Step", f2, subHeaderColor); AddCell(datatable, "Text", f2, subHeaderColor); // This puts "Step" and "Text" column headers at the bottom of the page //AddCell(datatable, "Step", f2, subHeaderColor); //AddCell(datatable, "Text", f2, subHeaderColor); datatable.DefaultCell.HorizontalAlignment = Element.ALIGN_LEFT; string lastDvPath = ""; string lastPath = ""; Color AnnoColor = new Color(0xFF, 0xFF, 0xC0); Color TextColor = Color.WHITE; Color SectColor = Color.LIGHT_GRAY; foreach (ItemInfo item in _ResultList) { if (item.SearchDVPath != lastDvPath) AddGroup(datatable, item.SearchDVPath, lastDvPath, f2, false, new Color(0xC0, 0xFF, 0xC0)); lastDvPath = item.SearchDVPath; string stepPath = AddGroup(datatable, item.SearchPath, lastPath, f2, true, new Color(0xE0, 0xFF, 0xE0)); lastPath = item.SearchPath; AddCell(datatable, stepPath, f2, (item.IsSection ? SectColor : TextColor)); // This was for the old 16-bit style of table - jsj 7/7/2011 //if (item.DisplayText.Contains("|")) // Need a better way to determine if it is a table. // AddCell(datatable, item.DisplayText, f3, TextColor); //else AddCell(datatable, item.DisplayText, f2, (item.IsSection ? SectColor : TextColor)); if (item.ItemAnnotationCount > 0) { foreach (AnnotationInfo ai in item.ItemAnnotations) { AddCell(datatable, ai.MyAnnotationType.Name, f2, AnnoColor); AddCell(datatable, ai.SearchText, f2, AnnoColor); } } } document.Add(datatable); } private void AddCell(PdfPTable datatable, string str, iTextSharp.text.Font fnt, Color bgColor) { iTextSharp.text.Font fntBold = new Font(fnt.BaseFont, fnt.Size, Font.BOLD, Color.RED); Phrase p = BuildPhrase2(str, fnt, fntBold); PdfPCell cell = new PdfPCell(p); cell.PaddingBottom = 4; cell.BackgroundColor = bgColor; datatable.AddCell(cell); } private Phrase BuildPhrase(string str, Font fnt, Font fntBold) { Phrase p = new Phrase(); if (_SearchString != null) { while (str.ToLower().Contains(_SearchString.ToLower())) { int iStart = str.ToLower().IndexOf(_SearchString.ToLower()); if (iStart > 0) p.Add(new Phrase(str.Substring(0, iStart), fnt)); Phrase p2 = new Phrase(str.Substring(iStart, _SearchString.Length), fntBold); p.Add(p2); str = str.Substring(iStart + _SearchString.Length); } } if (str.Length > 0) p.Add(new Phrase(str, fnt)); return p; } private string _RegexSearchString = null; private string RegexSearchString { get { if (_RegexSearchString == null) { _RegexSearchString = _SearchString; if (_RegexSearchString[0] == '%') _RegexSearchString = _RegexSearchString.Substring(1); if (_RegexSearchString[_RegexSearchString.Length - 1] == '%') _RegexSearchString = _RegexSearchString.Substring(0, _RegexSearchString.Length - 1); _RegexSearchString = _RegexSearchString.Replace("%", ".*"); } return _RegexSearchString; } } private Phrase BuildPhrase2(string str, Font fnt, Font fntBold) { Phrase p = new Phrase(); int lastIndex = 0; if ((_SearchString ?? "") != "") { Regex reg = new Regex(RegexSearchString, RegexOptions.Multiline | RegexOptions.IgnoreCase); foreach (Match m in reg.Matches(str)) { if (m.Index > 0) p.Add(new Phrase(str.Substring(lastIndex, m.Index - lastIndex), fnt)); Chunk chk = new Chunk(m.Value, fnt); //Phrase p2 = new Phrase(); //foreach (Chunk chk in p2.Chunks) chk.SetBackground(Color.YELLOW); p.Add(chk); lastIndex = m.Index + m.Length; } } p.Add(new Phrase(str.Substring(lastIndex), fnt)); return p; } } public class MyPageHelper : PdfPageEventHelper { protected PdfTemplate total; protected BaseFont helv; private int ptSize = 10; // text point size of page number and page total public override void OnOpenDocument(PdfWriter writer, iTextSharp.text.Document document) { total = writer.DirectContent.CreateTemplate(100, 100); total.BoundingBox = new Rectangle(-20, -20, 100, 100); //try //{ helv = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED); //} //catch (Exception) //{ // //throw new ExceptionConverter(e); //} } public override void OnEndPage(PdfWriter writer, iTextSharp.text.Document document) { PdfContentByte cb = writer.DirectContent; cb.SaveState(); String text = "Page " + writer.PageNumber + " of "; float textBase = document.Bottom - 19;//20; float textSize = helv.GetWidthPoint(text, ptSize); cb.BeginText(); cb.SetFontAndSize(helv, ptSize); //if ((writer.PageNumber % 2) == 1) //{ // cb.SetTextMatrix(document.Left, textBase); // cb.ShowText(text); // cb.EndText(); // cb.AddTemplate(total, document.Left + textSize, textBase); //} //else //{ // float adjust = helv.GetWidthPoint("0", 12); // cb.SetTextMatrix( // document.Right - textSize - adjust, textBase); // cb.ShowText(text); // cb.EndText(); // cb.AddTemplate(total, document.Right - adjust, textBase); //} float posCenter = document.Left + ((document.Right - document.Left) / 2) - (helv.GetWidthPoint(text+"XX", ptSize) / 2); cb.SetTextMatrix(posCenter, textBase); cb.ShowText(text); cb.EndText(); cb.AddTemplate(total, posCenter + helv.GetWidthPoint(text, ptSize), textBase); cb.RestoreState(); AddVolianFooter(writer,document); AddDateFooter(writer, document); } private void AddVolianFooter(PdfWriter writer, iTextSharp.text.Document document) { PdfContentByte cb = writer.DirectContent; cb.SaveState(); String text = "PROMS Search Results"; float textBase = document.Bottom - 19;//20; float textSize = helv.GetWidthPoint(text, ptSize); cb.BeginText(); cb.SetFontAndSize(helv, ptSize); cb.SetTextMatrix(document.Left, textBase); cb.ShowText(text); cb.EndText(); cb.RestoreState(); } private void AddDateFooter(PdfWriter writer, iTextSharp.text.Document document) { PdfContentByte cb = writer.DirectContent; cb.SaveState(); String text = DateTime.Today.ToShortDateString(); float textBase = document.Bottom - 19;//20; float textSize = helv.GetWidthPoint(text, ptSize); float posRight = document.Right - helv.GetWidthPoint(text, ptSize); cb.BeginText(); cb.SetFontAndSize(helv, ptSize); cb.SetTextMatrix(posRight, textBase); cb.ShowText(text); cb.EndText(); cb.RestoreState(); } public override void OnCloseDocument(PdfWriter writer, iTextSharp.text.Document document) { total.BeginText(); total.SetFontAndSize(helv, ptSize); total.SetTextMatrix(0, 0); total.ShowText((writer.PageNumber - 1).ToString()); total.EndText(); base.OnCloseDocument(writer, document); } } }