initial add

This commit is contained in:
Jonathan Ouellette
2022-09-27 14:10:30 -07:00
parent 91fd8a50a9
commit 580e90f6a2
3941 changed files with 954648 additions and 19 deletions

View File

@ -0,0 +1,44 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BinaryContentResult.cs" company="SemanticArchitecture">
// http://www.SemanticArchitecture.net pkalkie@gmail.com
// </copyright>
// <summary>
// An ActionResult used to send binary data to the browser.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Fab2ApprovalSystem.PdfGenerator
{
using System.IO;
using System.Web;
using System.Web.Mvc;
/// <summary>
/// An ActionResult used to send binary data to the browser.
/// </summary>
public class BinaryContentResult : ActionResult
{
private readonly string contentType;
private readonly byte[] contentBytes;
public BinaryContentResult(byte[] contentBytes, string contentType)
{
this.contentBytes = contentBytes;
this.contentType = contentType;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.Clear();
response.Cache.SetCacheability(HttpCacheability.Public);
response.ContentType = this.contentType;
using (var stream = new MemoryStream(this.contentBytes))
{
stream.WriteTo(response.OutputStream);
stream.Flush();
}
}
}
}

View File

@ -0,0 +1,27 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FakeView.cs" company="SemanticArchitecture">
// http://www.SemanticArchitecture.net pkalkie@gmail.com
// </copyright>
// <summary>
// Defines the FakeView type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Fab2ApprovalSystem.PdfGenerator
{
using System;
using System.IO;
using System.Web.Mvc;
public class FakeView : IView
{
#region IView Members
public void Render(ViewContext viewContext, TextWriter writer)
{
throw new NotImplementedException();
}
#endregion
}
}

View File

@ -0,0 +1,51 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="HtmlViewRenderer.cs" company="SemanticArchitecture">
// http://www.SemanticArchitecture.net pkalkie@gmail.com
// </copyright>
// <summary>
// This class is responsible for rendering a HTML view to a string.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Fab2ApprovalSystem.PdfGenerator
{
using System.IO;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
/// <summary>
/// This class is responsible for rendering a HTML view into a string.
/// </summary>
public class HtmlViewRenderer
{
public string RenderViewToString(Controller controller, string viewName, object viewData)
{
var renderedView = new StringBuilder();
using (var responseWriter = new StringWriter(renderedView))
{
var fakeResponse = new HttpResponse(responseWriter);
var fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse);
var fakeControllerContext = new ControllerContext(new HttpContextWrapper(fakeContext), controller.ControllerContext.RouteData, controller.ControllerContext.Controller);
var oldContext = HttpContext.Current;
HttpContext.Current = fakeContext;
using (var viewPage = new ViewPage())
{
var html = new HtmlHelper(CreateViewContext(responseWriter, fakeControllerContext), viewPage);
html.RenderPartial(viewName, viewData);
HttpContext.Current = oldContext;
}
}
return renderedView.ToString();
}
private static ViewContext CreateViewContext(TextWriter responseWriter, ControllerContext fakeControllerContext)
{
return new ViewContext(fakeControllerContext, new FakeView(), new ViewDataDictionary(), new TempDataDictionary(), responseWriter);
}
}
}

View File

@ -0,0 +1,69 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PdfViewController.cs" company="SemanticArchitecture">
// http://www.SemanticArchitecture.net pkalkie@gmail.com
// </copyright>
// <summary>
// Extends the controller with functionality for rendering PDF views
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Fab2ApprovalSystem.PdfGenerator
{
using System.Web.Mvc;
using System.IO;
/// <summary>
/// Extends the controller with functionality for rendering PDF views
/// </summary>
public class PdfViewController : Controller
{
private readonly HtmlViewRenderer htmlViewRenderer;
private readonly StandardPdfRenderer standardPdfRenderer;
public PdfViewController()
{
this.htmlViewRenderer = new HtmlViewRenderer();
this.standardPdfRenderer = new StandardPdfRenderer();
}
/// <summary>
///
/// </summary>
/// <param name="pageTitle"></param>
/// <param name="viewName"></param>
/// <param name="model"></param>
/// <returns></returns>
protected ActionResult ViewPdf(string pageTitle, string viewName, object model)
{
// Render the view html to a string.
string htmlText = this.htmlViewRenderer.RenderViewToString(this, viewName, model);
// Let the html be rendered into a PDF document through iTextSharp.
byte[] buffer = standardPdfRenderer.Render(htmlText, pageTitle);
// Return the PDF as a binary stream to the client.
return new BinaryContentResult(buffer, "application/pdf");
}
/// <summary>
///
/// </summary>
/// <param name="fileName"></param>
/// <param name="viewName"></param>
/// <param name="model"></param>
protected void SavePdf(string fileName, string viewName, object model)
{
// Render the view html to a string.
string htmlText = this.htmlViewRenderer.RenderViewToString(this, viewName, model);
// Let the html be rendered into a PDF document through iTextSharp.
byte[] buffer = standardPdfRenderer.Render(htmlText, "");
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
fs.Write(buffer, 0, buffer.Length);
}
}
}
}

View File

@ -0,0 +1,84 @@
namespace Fab2ApprovalSystem.PdfGenerator
{
using System;
using iTextSharp.text;
using iTextSharp.text.pdf;
/// <summary>
/// This class represents the standard header and footer for a PDF print.
/// application.
/// </summary>
public class PrintHeaderFooter : PdfPageEventHelper
{
private PdfContentByte pdfContent;
private PdfTemplate pageNumberTemplate;
private BaseFont baseFont;
private DateTime printTime;
public string Title { get; set; }
public override void OnOpenDocument(PdfWriter writer, Document document)
{
printTime = DateTime.Now;
baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
pdfContent = writer.DirectContent;
pageNumberTemplate = pdfContent.CreateTemplate(50, 50);
}
public override void OnStartPage(PdfWriter writer, Document document)
{
base.OnStartPage(writer, document);
Rectangle pageSize = document.PageSize;
if (Title != string.Empty)
{
pdfContent.BeginText();
pdfContent.SetFontAndSize(baseFont, 11);
pdfContent.SetRGBColorFill(0, 0, 0);
pdfContent.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetTop(40));
pdfContent.ShowText(Title);
pdfContent.EndText();
}
}
public override void OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer, document);
int pageN = writer.PageNumber;
string text = pageN + " - ";
float len = baseFont.GetWidthPoint(text, 8);
Rectangle pageSize = document.PageSize;
pdfContent = writer.DirectContent;
pdfContent.SetRGBColorFill(100, 100, 100);
pdfContent.BeginText();
pdfContent.SetFontAndSize(baseFont, 8);
pdfContent.SetTextMatrix(pageSize.Width / 2, pageSize.GetBottom(30));
pdfContent.ShowText(text);
pdfContent.EndText();
pdfContent.AddTemplate(pageNumberTemplate, (pageSize.Width / 2) + len, pageSize.GetBottom(30));
pdfContent.BeginText();
pdfContent.SetFontAndSize(baseFont, 8);
pdfContent.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, printTime.ToString(), pageSize.GetRight(40), pageSize.GetBottom(30), 0);
pdfContent.EndText();
}
public override void OnCloseDocument(PdfWriter writer, Document document)
{
base.OnCloseDocument(writer, document);
pageNumberTemplate.BeginText();
pageNumberTemplate.SetFontAndSize(baseFont, 8);
pageNumberTemplate.SetTextMatrix(0, 0);
pageNumberTemplate.ShowText(string.Empty + (writer.PageNumber - 1));
pageNumberTemplate.EndText();
}
}
}

View File

@ -0,0 +1,49 @@
using System.IO;
using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;
namespace Fab2ApprovalSystem.PdfGenerator
{
/// <summary>
/// This class is responsible for rendering a html text string to a PDF document using the html renderer of iTextSharp.
/// </summary>
public class StandardPdfRenderer
{
private const int HorizontalMargin = 40;
private const int VerticalMargin = 40;
public byte[] Render(string htmlText, string pageTitle)
{
byte[] renderedBuffer;
using (var outputMemoryStream = new MemoryStream())
{
using (var pdfDocument = new Document(PageSize.A4, HorizontalMargin, HorizontalMargin, VerticalMargin, VerticalMargin))
{
PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, outputMemoryStream);
pdfWriter.CloseStream = false;
pdfWriter.PageEvent = new PrintHeaderFooter { Title = pageTitle };
pdfDocument.Open();
using (var htmlViewReader = new StringReader(htmlText))
{
using (var htmlWorker = new HTMLWorker(pdfDocument))
{
htmlWorker.Parse(htmlViewReader);
}
}
}
renderedBuffer = new byte[outputMemoryStream.Position];
outputMemoryStream.Position = 0;
outputMemoryStream.Read(renderedBuffer, 0, renderedBuffer.Length);
}
return renderedBuffer;
}
}
}