– Write XML directly to the ZIP entry's output stream using a XmlWriter (or equivalent) without retaining the entire tree.
var stream = new MemoryStream(); using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true)) // 1. [Content_Types].xml var ctEntry = archive.CreateEntry("[Content_Types].xml"); using (var ctWriter = new StreamWriter(ctEntry.Open())) ctWriter.Write(@"<?xml version='1.0' encoding='UTF-8'?> <Types xmlns='http://schemas.openxmlformats.org/package/2006/content-types'> <Default Extension='rels' ContentType='application/vnd.openxmlformats-package.relationships+xml'/> <Default Extension='xml' ContentType='application/xml'/> <Override PartName='/word/document.xml' ContentType='application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml'/> </Types>"); // 2. Relationships (.rels) var relsEntry = archive.CreateEntry("_rels/.rels"); using (var relsWriter = new StreamWriter(relsEntry.Open())) relsWriter.Write(@"<?xml version='1.0'?> <Relationships xmlns='http://schemas.openxmlformats.org/package/2006/relationships'> <Relationship Id='rId1' Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument' Target='word/document.xml'/> </Relationships>"); office open xml download
XmlReaderSettings settings = new XmlReaderSettings(); settings.DtdProcessing = DtdProcessing.Prohibit; settings.XmlResolver = null; A malicious .docx upload (if your system re-uploads user files) may contain a document.xml compressed from 1 KB to 1 GB inflated. When your server processes it for download generation, memory is exhausted. – Write XML directly to the ZIP entry's
Office Open XML, OOXML, Document Generation, File Download, XML Security, ZIP Compression, REST API. 1. Introduction In enterprise web applications, generating downloadable office documents from structured data (e.g., invoices, reports, spreadsheets) is a ubiquitous requirement. Prior to OOXML, server-side generation often relied on binary formats ( .doc , .xls ) via COM interop (unreliable and non-scalable) or HTML-to-PDF converters (loss of semantic fidelity). The introduction of OOXML solved this by providing an open, royalty-free, XML-based standard. Relationships (
// 3. Main document part - STREAMING XML (no DOM) var docEntry = archive.CreateEntry("word/document.xml"); using (var docStream = docEntry.Open()) using (var xmlWriter = XmlWriter.Create(docStream, new XmlWriterSettings Indent = true )) xmlWriter.WriteStartDocument(); xmlWriter.WriteStartElement("w:document", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); xmlWriter.WriteStartElement("w:body"); // Title paragraph xmlWriter.WriteStartElement("w:p"); xmlWriter.WriteStartElement("w:r"); xmlWriter.WriteStartElement("w:t"); xmlWriter.WriteString(title); xmlWriter.WriteEndElement(); // t xmlWriter.WriteEndElement(); // r xmlWriter.WriteEndElement(); // p // Content paragraph (sanitized) var safeContent = System.Security.SecurityElement.Escape(content); xmlWriter.WriteStartElement("w:p"); xmlWriter.WriteStartElement("w:r"); xmlWriter.WriteStartElement("w:t"); xmlWriter.WriteString(safeContent); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); // body xmlWriter.WriteEndElement(); // document xmlWriter.WriteEndDocument();
report.zip ├── [Content_Types].xml ├── _rels/ │ └── .rels ├── docProps/ │ ├── core.xml │ └── app.xml └── word/ ├── document.xml ├── styles.xml ├── _rels/ │ └── document.xml.rels └── media/ └── image1.png Logically, the file is composed of (XML, binary, image) linked by relationships using Relationship Id attributes. 2.2 Key Standards | Standard | Content | | :--- | :--- | | ECMA-376 1st ed. (2006) | Legacy "transitional" syntax. | | ISO/IEC 29500:2008 | Strict and transitional variants. | | ISO/IEC 29500:2016 | Added support for dynamic charts, accessibility features. |