/// <inheritdoc /> public async Task <MemoryStream> Save() { MemoryStream stream = DocxFilePath.Create(); stream = await Document.WriteInto(stream, "word/document.xml"); stream = await Footnotes.WriteInto(stream, "word/footnotes.xml"); stream = await ContentTypes.WriteInto(stream, ContentTypesInfo.Path); stream = await DocumentRelations.WriteInto(stream, DocumentRelsInfo.Path); stream = await FootnoteRelations.WriteInto(stream, "word/_rels/footnotes.xml.rels"); stream = await Styles.WriteInto(stream, "word/styles.xml"); stream = await Numbering.WriteInto(stream, "word/numbering.xml"); stream = await Theme1.WriteInto(stream, "word/theme/theme1.xml"); foreach (ChartInformation item in Charts) { stream = await item.Chart.WriteInto(stream, $"word/{item.Name}"); } return(stream); }
public virtual IOpenXmlVisitor Visit(DocxFilePath file) { if (file is null) { throw new ArgumentNullException(nameof(file)); } IOpenXmlVisitor subject = new OpenXmlVisitor(file); IOpenXmlVisitor documentVisitor = VisitDocument(subject, NextRevisionId); IOpenXmlVisitor footnoteVisitor = VisitFootnotes(documentVisitor, NextFootnoteId, NextRevisionId); IOpenXmlVisitor documentRelationVisitor = VisitDocumentRelations(footnoteVisitor, NextDocumentRelationId); IOpenXmlVisitor footnoteRelationVisitor = VisitFootnoteRelations(documentRelationVisitor, NextFootnoteRelationId); IOpenXmlVisitor styleVisitor = VisitStyles(footnoteRelationVisitor); IOpenXmlVisitor numberingVisitor = VisitNumbering(styleVisitor); return(numberingVisitor); }
/// <inheritdoc /> public void Save(DocxFilePath result) { if (result is null) { throw new ArgumentNullException(nameof(result)); } Document.WriteInto(result, "word/document.xml"); Footnotes.WriteInto(result, "word/footnotes.xml"); ContentTypes.WriteInto(result, ContentTypesInfo.Path); DocumentRelations.WriteInto(result, DocumentRelsInfo.Path); FootnoteRelations.WriteInto(result, "word/_rels/footnotes.xml.rels"); Styles.WriteInto(result, "word/styles.xml"); Numbering.WriteInto(result, "word/numbering.xml"); Theme1.WriteInto(result, "word/theme/theme1.xml"); foreach (ChartInformation item in Charts) { item.Chart.WriteInto(result, $"word/{item.Name}"); } }
/// <inheritdoc /> /// <summary> /// Initialize a <see cref="ReportVisitor"/> based on the supplied <see cref="DocxFilePath"/>. /// </summary> /// <param name="result"> /// The base path used to initialize the new <see cref="ReportVisitor"/>. /// </param> public ReportVisitor([NotNull] DocxFilePath result) : base(result) { }
public IActionResult Index( [NotNull] [ItemNotNull] IEnumerable<IFormFile> files, [CanBeNull] string format, [CanBeNull] string title, [CanBeNull] string publisher, [CanBeNull] string website, [CanBeNull] string stylesheetUrl, [CanBeNull] IFormFile stylesheet) { if (files is null) throw new ArgumentNullException(nameof(files)); IFormFile[] uploadedFiles = files.ToArray(); if (uploadedFiles.Length == 0) return BadRequest("No files uploaded."); if (uploadedFiles.Any(x => x.Length <= 0)) return BadRequest("Invalid file length."); if (uploadedFiles.Any(x => x.ContentType != MicrosoftWordDocument.ToString() && x.FileName.EndsWith(".docx", StringComparison.OrdinalIgnoreCase) && x.FileName.EndsWith(".md", StringComparison.OrdinalIgnoreCase))) return BadRequest("Invalid file format."); if (stylesheet is IFormFile s && !s.FileName.EndsWith(".css")) return BadRequest($"Invalid stylesheet:{stylesheet.FileName}."); Queue<Package> packagesQueue = new Queue<Package>(uploadedFiles.Length); foreach (IFormFile file in uploadedFiles) { if (file.FileName.EndsWith(".docx", StringComparison.OrdinalIgnoreCase)) { packagesQueue.Enqueue(Package.Open(file.OpenReadStream())); } else if (file.FileName.EndsWith(".md", StringComparison.OrdinalIgnoreCase)) { MDocument mDocument = new MDocument(); using (StreamReader reader = new StreamReader(file.OpenReadStream())) { MarkdownVisitor visitor = new MarkdownVisitor(); ReadOnlySpan<char> span; while ((span = reader.ReadLine()) != null) { mDocument.Append(visitor.Visit(in span)); } } Package package = DocxFilePath.Create().ToPackage(FileAccess.ReadWrite); mDocument.ToOpenXml().WriteTo(package.GetPart(Document.PartUri)); packagesQueue.Enqueue(package); } } Package output = Process( packagesQueue, title ?? "[REPORT TITLE]", publisher ?? "[PUBLISHER]", website ?? "[PUBLISHER WEBSITE]"); foreach (Package package in packagesQueue) { package.Close(); } switch (format) { case "docx": { return File(output.ToStream(), MicrosoftWordDocument, $"{title ?? "result"}.docx"); } case "html": { string styles = stylesheet is null ? null : new StreamReader(stylesheet.OpenReadStream()).ReadToEnd(); OpenXmlPackageVisitor ooxml = new OpenXmlPackageVisitor(output); HtmlVisitor html = new HtmlVisitor(ooxml.Document.ChartReferences, ooxml.Document.ImageReferences); XObject htmlResult = html.Visit(ooxml.Document.Content, ooxml.Footnotes.Content, title, stylesheetUrl, styles); return File(Encoding.UTF8.GetBytes(htmlResult.ToString()), "text/html", $"{title ?? "result"}.html"); } case "xml": { OpenXmlPackageVisitor xml = new OpenXmlPackageVisitor(output); XElement xmlResult = xml.Document.Content; return File(Encoding.UTF8.GetBytes(xmlResult.ToString()), "application/xml", $"{title ?? "result"}.xml"); } default: { return BadRequest(ModelState); } } }
/// <summary> /// Initializes an <see cref="OpenXmlVisitor"/> by reading document parts into memory. /// </summary> /// <param name="result"> /// The file to which changes can be saved. /// </param> /// <exception cref="ArgumentNullException"/> public OpenXmlVisitor([NotNull] DocxFilePath result) { if (result is null) { throw new ArgumentNullException(nameof(result)); } ContentTypes = result.ReadAsXml(ContentTypesInfo.Path) ?? throw new FileNotFoundException(ContentTypesInfo.Path); Document = result.ReadAsXml() ?? throw new FileNotFoundException("word/document.xml"); DocumentRelations = result.ReadAsXml(DocumentRelsInfo.Path) ?? throw new FileNotFoundException(DocumentRelsInfo.Path); Footnotes = result.ReadAsXml("word/footnotes.xml") ?? new XElement(W + "footnotes"); FootnoteRelations = result.ReadAsXml("word/_rels/footnotes.xml.rels") ?? new XElement(P + "Relationships"); Styles = result.ReadAsXml("word/styles.xml") ?? throw new FileNotFoundException("word/styles.xml"); Numbering = result.ReadAsXml("word/numbering.xml"); Theme1 = result.ReadAsXml("word/theme/theme1.xml"); if (Numbering is null) { Numbering = new XElement(W + "numbering"); DocumentRelations = new XElement( DocumentRelations.Name, DocumentRelations.Attributes(), DocumentRelations.Elements() .Where(x => !x.Attribute("Tartget")?.Value.Equals("numbering.xml", StringComparison.OrdinalIgnoreCase) ?? true), new XElement( P + "Relationship", new XAttribute("Id", $"rId{NextDocumentRelationId}"), new XAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"), new XAttribute("Target", "numbering.xml"))); ContentTypes = new XElement( ContentTypes.Name, ContentTypes.Attributes(), ContentTypes.Elements() .Where(x => !x.Attribute("PartName")?.Value.Equals("/word/numbering.xml", StringComparison.OrdinalIgnoreCase) ?? true), new XElement(T + "Override", new XAttribute("PartName", "/word/numbering.xml"), new XAttribute("ContentType", "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"))); } Charts = result.ReadAsXml(DocumentRelsInfo.Path) .Elements() .Select(x => x.Attribute("Target")?.Value) .Where(x => x?.StartsWith("charts/") ?? false) .Select(x => new ChartInformation(x, result.ReadAsXml($"word/{x}"))) .ToImmutableList(); }
/// <inheritdoc /> /// <summary> /// Initializes an <see cref="T:AD.OpenXml.Visitors.OpenXmlVisitor" /> by reading document parts into memory from a default <see cref="MemoryStream"/>. /// </summary> public OpenXmlVisitor() : this(DocxFilePath.Create()) { }