Skip to content

Instantly share code, notes, and snippets.

@sheastrickland
Created March 30, 2011 09:10
Show Gist options
  • Save sheastrickland/894101 to your computer and use it in GitHub Desktop.
Save sheastrickland/894101 to your computer and use it in GitHub Desktop.
AbcPdf in ASP.Net Mvc
public class AbcPdfDocumentGenerator : IDocumentGenerator
{
public string ContentType
{
get { return "application/pdf"; }
}
public string FileExtension
{
get { return "pdf"; }
}
public AbcPdfDocumentGenerator(string licenceKey)
{
if (!string.IsNullOrEmpty(licenceKey))
XSettings.InstallSystemLicense(licenceKey);
}
public Stream Generate(Uri httpAddress)
{
return GenerateDocumentStream(doc => doc.AddImageUrl(httpAddress.ToString(), true, 1024, true));
}
public Stream Generate(string html)
{
return GenerateDocumentStream(doc => doc.AddImageHtml(html, true, 1024, true));
}
public Stream Generate(Stream html, Encoding encoding)
{
using (var rdr = new StreamReader(html, encoding))
return Generate(rdr.ReadToEnd());
}
private Stream GenerateDocumentStream(Func<Doc, int> initialPage)
{
using (var doc = new Doc())
{
doc.Rect.Inset(0, 25);
doc.HtmlOptions.Engine = EngineType.Gecko;
doc.HtmlOptions.ImageQuality = 70; //101 = lossless
doc.HtmlOptions.AddLinks = true;
doc.HtmlOptions.AddTags = true;
doc.HtmlOptions.BrowserWidth = 1024;
doc.HtmlOptions.FontEmbed = true;
doc.HtmlOptions.InitialWidth = 1024;
doc.HtmlOptions.TargetLinks = true;
doc.Font = doc.AddFont("Arial");
var pdfsettingsid = doc.AddObject("<< >>");
doc.SetInfo(-1, "/Info:Ref", pdfsettingsid.ToString());
//doc.SetInfo(pdfsettingsid, "/Title:Text", title);
doc.SetInfo(pdfsettingsid, "/Author:Text", "Toll");
//doc.SetInfo(pdfsettingsid, "/Subject:Text", title);
//doc.SetInfo(pdfsettingsid, "/Keywords:Text", "Toll,Visa");
doc.SetInfo(pdfsettingsid, "/Creator:Text", "Toll");
doc.SetInfo(pdfsettingsid, "/Producer:Text", "Toll");
var date = string.Format("D:{0}", DateTime.Now.ToString("YYYYmmdd"));
doc.SetInfo(pdfsettingsid, "/CreationDate:Text", date);
doc.SetInfo(pdfsettingsid, "/ModDate:Text", date);
doc.SetInfo(pdfsettingsid, "/Trapped:Name", "False");
var htmlId = initialPage(doc); //Add the initial page of the pdf document
while (true) //Until the doc is no longer chainable, loop
{
if (!doc.Chainable(htmlId)) break;
doc.Page = doc.AddPage();
htmlId = doc.AddImageToChain(htmlId); //Add new page
}
for (var i = 1; i <= doc.PageCount; i++)
{
doc.PageNumber = i;
doc.Flatten();
}
//return stream of the pdf
var memoryStream = new MemoryStream();
doc.Save(memoryStream);
memoryStream.Position = 0;
return memoryStream;
}
}
}
public class DocumentGenerationActionFilter : IActionFilter
{
private readonly IDocumentGenerator _documentGenerator;
public DocumentGenerationActionFilter(IDocumentGenerator documentGenerator)
{
_documentGenerator = documentGenerator;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
if ((filterContext.RouteData.Values["pdf"] ?? string.Empty).ToString() == "pdf" && filterContext.Result.GetType().IsAssignableFrom(typeof (ViewResult)))
{
var view = (ViewResult) filterContext.Result;
var baseUrl = filterContext.HttpContext.Request.Url;
var content = filterContext.Controller.ViewResultToString(view).Replace("<head>", "<head><base href=\"" + baseUrl + "\" />");
var documentStream = _documentGenerator.Generate(content);
filterContext.Result = new FileStreamResult(documentStream, _documentGenerator.ContentType)
{
FileDownloadName = Path.ChangeExtension(filterContext.RouteData.GetRequiredString("action"), _documentGenerator.FileExtension)
};
}
}
}
public interface IDocumentGenerator
{
string ContentType { get; }
string FileExtension { get; }
Stream Generate(Uri httpAddress);
Stream Generate(string html);
Stream Generate(Stream html, Encoding encoding);
}
public static class MvcExtensions
{
public static string ViewResultToString(this ControllerBase controller, ViewResult viewResult)
{
if (string.IsNullOrEmpty(viewResult.ViewName))
viewResult.ViewName = controller.ControllerContext.RouteData.GetRequiredString("action");
viewResult.View = viewResult.ViewEngineCollection.FindView(controller.ControllerContext, viewResult.ViewName, viewResult.MasterName).View;
// init string writer
using (var sw = new StringWriter())
{
// get the view context
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
// render the view
viewResult.View.Render(viewContext, sw);
// return the string
return sw.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment