Permalink
Browse files

adding simple pdf renderer implementation, ability to strip CSS from …

…processed HTML before rendering as PDF (closes issue #1)
  • Loading branch information...
1 parent 7c3162c commit e2aa037e1ce4f7bfda4ca6b33ad79d8db5e10658 @AlexCuse committed Dec 14, 2011

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
using System.Reflection;
using System.Windows.Forms;
+using RazorReport.Pdf;
namespace RazorReport.Example {
public partial class Form1 : Form {
@@ -15,7 +18,8 @@ public partial class Form1 : Form {
builder = ReportBuilder<Example>.Create ("modelReport")
.WithCssFromResource ("RazorReport.Example.Style.css", assembly)
- .WithTemplateFromResource ("RazorReport.Example.ExampleTemplate.htm", assembly);
+ .WithTemplateFromResource ("RazorReport.Example.ExampleTemplate.htm", assembly)
+ .WithPdfRenderer (new PdfRenderer ());
precompilingBuilder = ReportBuilder<Example>.Create ("modelReport")
.WithCssFromResource ("RazorReport.Example.Style.css", assembly)
@@ -28,7 +32,7 @@ public partial class Form1 : Form {
string RunCompiled () {
var model = new Example { Name = "Alex", Email = "test@example.com", Values = new Dictionary<object, object> { { "Compiled", "Yes" }, { "Worked", "Yes" } } };
- return builder.BuildReport (model);
+ return precompilingBuilder.BuildReport (model);
}
string Run () {
@@ -37,12 +41,33 @@ public partial class Form1 : Form {
return builder.BuildReport (model);
}
+ byte[] RunPdf () {
+ var model = new Example { Name = "Alex", Email = "test@example.com", Values = new Dictionary<object, object> { { "Compiled", "No" }, { "Worked", "Yes" } } };
+
+ return builder.BuildPdf (model);
+ }
+
private void runCompiled_Click (object sender, EventArgs e) {
webBrowser1.DocumentText = RunCompiled ();
}
private void run_Click (object sender, EventArgs e) {
webBrowser1.DocumentText = Run ();
}
+
+ private void runPdf_Click (object sender, EventArgs e) {
+ using (var sfd = new SaveFileDialog ()) {
+ var dialogResult = sfd.ShowDialog ();
+ if (dialogResult == DialogResult.OK) {
+ var file = sfd.FileName;
+
+ using (var fileStream = File.OpenWrite (file)) {
+ var content = RunPdf ();
+ fileStream.Write (content, 0, content.Length);
+ }
+ MessageBox.Show (string.Format ("PDF Saved to: {0}", file));
+ }
+ }
+ }
}
}
@@ -86,6 +86,10 @@
</Compile>
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\RazorReport.Pdf\RazorReport.Pdf.csproj">
+ <Project>{0473BC90-3850-45E2-912E-9265C792219A}</Project>
+ <Name>RazorReport.Pdf</Name>
+ </ProjectReference>
<ProjectReference Include="..\RazorReport\RazorReport.csproj">
<Project>{5F85C306-C30D-44CC-9B97-230E8D9A2FF7}</Project>
<Name>RazorReport</Name>
@@ -0,0 +1,27 @@
+using System.IO;
+using iTextSharp.text;
+using iTextSharp.text.html.simpleparser;
+using iTextSharp.text.pdf;
+
+namespace RazorReport.Pdf {
+ public class PdfRenderer : IPdfRenderer {
+ public byte[] RenderFromHtml (string html) {
+ var output = new MemoryStream ();
+ using (var reader = new StringReader (html)) {
+ var document = new Document ();
+ var writer = PdfWriter.GetInstance (document, output);
+ var worker = new HTMLWorker (document);
+
+ document.Open ();
+ worker.StartDocument ();
+ worker.Parse (reader);
+
+ worker.EndDocument ();
+ worker.Close ();
+ document.Close ();
+
+ return output.ToArray ();
+ }
+ }
+ }
+}
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle ("RazorReport.Pdf")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("Microsoft")]
+[assembly: AssemblyProduct ("RazorReport.Pdf")]
+[assembly: AssemblyCopyright ("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible (false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid ("a5fb4e32-a754-4235-a6d3-16a3d8175d74")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion ("1.0.0.0")]
+[assembly: AssemblyFileVersion ("1.0.0.0")]
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{0473BC90-3850-45E2-912E-9265C792219A}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>RazorReport.Pdf</RootNamespace>
+ <AssemblyName>RazorReport.Pdf</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="itextsharp">
+ <HintPath>..\lib\itextsharp.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="PdfRenderer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\RazorReport\RazorReport.csproj">
+ <Project>{5F85C306-C30D-44CC-9B97-230E8D9A2FF7}</Project>
+ <Name>RazorReport</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
@@ -173,20 +173,23 @@ public class ReportBuilderTest {
var templateName = "templateName";
var template = "template";
+ var css = "css";
var model = new Example ();
- var rendered = "rendered";
- var pdf = new MemoryStream ();
+ var rendered = "cssrendered";
+ var strippedRendered = "rendered";
+ var pdf = new byte[0];
using (mockery.Record ()) {
engine.Compile (template, templateName);
SetupResult.For (engine.Run (model, templateName)).Return (rendered);
- Expect.Call (renderer.RenderFromHtml (rendered)).Return (pdf);
+ Expect.Call (renderer.RenderFromHtml (strippedRendered)).Return (pdf);
}
using (mockery.Playback ()) {
var builder = ReportBuilder<Example>.CreateWithEngineInstance (templateName, engine)
.WithTemplate (template)
+ .WithCss (css)
.WithPdfRenderer (renderer)
.WithPrecompilation ();
@@ -195,6 +198,38 @@ public class ReportBuilderTest {
}
}
+ [Test]
+ public void WithPdfRenderer_KeepStyles () {
+ var mockery = new MockRepository ();
+ var renderer = mockery.StrictMock<IPdfRenderer> ();
+ var engine = mockery.StrictMock<IEngine<Example>> ();
+
+ var templateName = "templateName";
+ var template = "template";
+ var css = "css";
+ var model = new Example ();
+ var rendered = "cssrendered";
+ var pdf = new byte[0];
+
+ using (mockery.Record ()) {
+ engine.Compile (template, templateName);
+ SetupResult.For (engine.Run (model, templateName)).Return (rendered);
+
+ Expect.Call (renderer.RenderFromHtml (rendered)).Return (pdf);
+ }
+
+ using (mockery.Playback ()) {
+ var builder = ReportBuilder<Example>.CreateWithEngineInstance (templateName, engine)
+ .WithTemplate (template)
+ .WithCss (css)
+ .WithPdfRenderer (renderer, false)
+ .WithPrecompilation ();
+
+ var output = builder.BuildPdf (model);
+ Assert.AreEqual (output, pdf);
+ }
+ }
+
[Test]
public void Exception_If_No_PdfRenderer () {
var builder = ReportBuilder<Example>.Create ("asdf");
Oops, something went wrong.

0 comments on commit e2aa037

Please sign in to comment.