2010-10-12 15:01:54 +00:00

410 lines
14 KiB
C#

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<ItemInfo> _ResultList;
public ICollection<ItemInfo> 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 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, ICollection<ItemInfo> resultList, string fileName)
{
_ResultList = resultList;
_FileName = fileName;
_ReportTitle = VEPROMS.CSLA.Library.ItemInfo.ConvertToDisplayText(reportTitle);
}
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);
}
}
}
/// <summary>
/// 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
/// </summary>
/// <param name="document"></param>
/// <returns></returns>
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));
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);
}
/// <summary>
/// Use Cells within Cells to see if I can limit the way Cells break from Page to Page
/// </summary>
/// <param name="document"></param>
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("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);
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);
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));
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;
}
}
}