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 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); }