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