public abstract Stream Render( ReportLayout report, string documentId, string designId, string title, int version, DateTimeOffset timestamp, string photoUri, string resourceUri, bool drawRules, bool drawPageBoxes, Generator generator, ITrace tracer);
public override Stream Render( ReportLayout report, string documentId, string designId, string title, int version, DateTimeOffset timestamp, string photoUri, string resourceUri, bool drawRules, bool drawPageBoxes, Generator generator, ITrace tracer) { AssemblyName assName = Assembly.GetExecutingAssembly().GetName(); string creator = $"Demon report generator {assName.Name} version {assName.Version.Major}.{assName.Version.Minor}.{assName.Version.Revision}"; _generator = generator; Dictionary <string, string> docInfo = new Dictionary <string, string>(); docInfo.Add("Title", title); docInfo.Add("Creator", creator); docInfo.Add("Producer", creator); docInfo.Add("CreationDate", $"D:{timestamp:yyyyMMddHHmmssZ}"); docInfo.Add("Version", $"{version}"); docInfo.Add("DocumentId", documentId); docInfo.Add("ReportDesignId", designId); _package = new Demon.Word.Package(docInfo); _document = _package.Document; // Lay out the content. Even though we're going to let Word do // the actual laying out, we may want to insert explicit page // breaks, and we'll only get that information by doing our // own layout. List <PageLayout> pageLayouts = report.LayOut(); // Write the document-level data RenderFonts(); RenderStyles(); RenderSettings(); RenderProperties(); RenderRelationships(); // Write the content to the Word document tracer.TraceLayoutActivity("Generate document"); SectionProperties sectionProperties = null; PageLayout page = null; for (int pageIndex = 0; pageIndex < pageLayouts.Count; ++pageIndex) { page = pageLayouts[pageIndex]; RenderPage(page, _document); // If this is the last page in the chapter then create a section // break by applying the chapter's section properties to the last // paragraph in the section/chapter. (But in fact it's a lot easier // to insert an empty paragraph just for this purpose.) Also, it's // easier to identify the first page in chapter than the last, so // we peep at the next page and check whether it's the first in the // next chapter. int nextPageIndex = pageIndex + 1; if (nextPageIndex < pageLayouts.Count) { PageLayout next = pageLayouts[nextPageIndex]; if (next.IsChapterFirstPage) { sectionProperties = new SectionProperties(page.TrackingInfo); //TODO: fill the properties in. This includes the header and //footer, page size and so on _document.AddSectionProperties(sectionProperties); } } } // Apply the last section properties. These are applied to the // body element, not to the last paragraph in the section. sectionProperties = new SectionProperties(page.TrackingInfo); //TODO: fill the properties in _document.AddLastSectionProperties(sectionProperties); Stream file = _package.Write(); return(file); }
public Stream Generate( Stream designFile, int[] chapters, bool drawRules, bool drawPageBoxes, string mimeType, string photoUri, string resourceUri) //TODO: return byte[]? { _reportMimeType = mimeType; _fonts.Load(); // Set up a reference resolver DocumentStructure structure = new DocumentStructure(_documentId, _unitOfWork); DocTaggedObjects taggedObjects = new DocTaggedObjects(_documentId, _unitOfWork); _resolver = new Resolver(structure, taggedObjects, _tracePathDelegate); // Load the report structure as it's designed _design = new ReportDesign(designFile, _logger); _report = _design.Load(this); _report.Validate(); _report.Subset(chapters); // Load properties from the database and prepare them for matching // against expansion strings in text LoadProperties(); // Resolve all source references from ref-to-template-object // to ref-to-concrete-object, duplicating layouts as necessary TraceLayoutActivity("Resolve references"); _report.ResolveSublayoutReferences(); TraceLayoutActivity("Validate conditions"); _report.ValidateConditions(); TraceLayoutActivity("Apply static conditions"); _report.ApplyStaticLayoutConditions(); // Load content TraceLayoutActivity("Load content"); _report.LoadContent(); _report.MergeContent(null); // Remove content based on conditions TraceLayoutActivity("Apply dynamic conditions"); _report.ApplyDynamicConditions(); // TraceLayoutActivity("Remove empty layouts"); // layout.RemoveEmptyLayouts(); // TraceLayoutActivity("Redraft"); // layout.Redraft(); // // Measure and cut content // TraceLayoutActivity("Measure and cut content"); // List<PageLayout> pages = layout.LayOut(); ReportRenderer renderer = null; switch (_reportMimeType) { case Demon.Core.MimeType.PDF: renderer = new PDF(); break; case Demon.Core.MimeType.Word: renderer = new Word(); break; case Demon.Core.MimeType.HTML: renderer = new HTML(); break; case Demon.Core.MimeType.SVG: renderer = new SVG(); break; default: throw new ArgumentOutOfRangeException($"Unsupported report content type '{_reportMimeType}'."); } Stream report = renderer.Render( _report, _documentId, _design.Id, _design.Name, _documentVersion, _timestamp, photoUri, resourceUri, drawRules, drawPageBoxes, this, this); return(report); }
public override Stream Render( ReportLayout report, string documentId, string designId, string title, int version, DateTimeOffset timestamp, string photoUri, string resourceUri, bool drawRules, bool drawPageBoxes, Generator generator, ITrace tracer) { AssemblyName assName = Assembly.GetExecutingAssembly().GetName(); string creator = $"Demon report generator {assName.Name} version {assName.Version.Major}.{assName.Version.Minor}.{assName.Version.Revision}"; _generator = generator; Dictionary <string, string> docInfo = new Dictionary <string, string>(); docInfo.Add("Title", title); docInfo.Add("Creator", creator); docInfo.Add("Producer", creator); docInfo.Add("CreationDate", $"D:{timestamp:yyyyMMddHHmmssZ}"); docInfo.Add("Version", $"{version}"); docInfo.Add("DocumentId", documentId); docInfo.Add("ReportDesignId", designId); // In case we're going to draw rules on at least one page, make // sure that we've got a font prepared for that _rulesFont = _generator.GetFont("Helvetica", 400, false, false, false, false); string ruleChars = "0123456789"; foreach (char c in ruleChars) { _rulesFont.MapCharacter(c); } // Lay out the content and apply page breaks _generator.TraceLayoutActivity("Measure and cut content"); List <PageLayout> pageLayouts = report.LayOut(); // Subset the fonts. First map characters actually used by the // layouts into the fonts' glyph character maps, and then create // the subsets using only those glyphs. Do this after laying out // because header and footer content isn't loaded until the layout // phase. See the note in TextLayout.LoadContent before the call // to ExpandProperties. //TODO: find a better way to handle PageNumber and PageCount so that we //can include them in the page body, and so that we can lay out the //header and footer at the same time as the body. report.MapFontCharacters(); _generator.FontCache.Subset(); Demon.PDF.Document doc = new Demon.PDF.Document(docInfo, _generator.FontCache); // Write the content to the PDF tracer.TraceLayoutActivity("Generate document"); foreach (PageLayout pageLayout in pageLayouts) { RenderPageLayout(pageLayout, doc, drawRules); } Stream file = doc.Write(); return(file); }
public ReportLayout(ReportLayout src) : base(src) { }