public MemoryStream Generate(object model = null) { if (model != null) { SetModel(model); } var viewBytes = File.ReadAllBytes(ViewPath); MemoryStream outputstream = new MemoryStream(); outputstream.Write(viewBytes, 0, viewBytes.Length); #if NET35 && SUPPORT_MULTI_THREADING_AND_LARGE_DOCUMENTS_IN_NET35 // Due to a bug in System.IO.Packaging writing large uncompressed parts (>10MB) isn't thread safe in .NET 3.5. // Workaround: make writing in all threads and processes sequential. // Microsoft fixed this in .NET 4.5 (see https://maheshkumar.wordpress.com/2014/10/21/). PackageMutex.WaitOne(Timeout.Infinite, false); try { #endif using (Package = WordprocessingDocument.Open(outputstream, true)) { var codeBlockBuilder = new CodeBlockBuilder(Package); CodeBlocks = codeBlockBuilder.CodeBlocks; Map = codeBlockBuilder.BodyMap; InvokeDocumentCode(); foreach (var cb in CodeBlocks) { cb.RemoveEmptyParagraphs(); } } #if NET35 && SUPPORT_MULTI_THREADING_AND_LARGE_DOCUMENTS_IN_NET35 } finally { PackageMutex.ReleaseMutex(); } #endif // Reset position of stream. outputstream.Seek(0, SeekOrigin.Begin); return(outputstream); }
public void Generate(string documentPath, object model = null) { if (model != null) { SetModel(model); } documentPath = Path.GetFullPath(documentPath); File.Copy(ViewPath, documentPath, true); #if NET35 && SUPPORT_MULTI_THREADING_AND_LARGE_DOCUMENTS_IN_NET35 // Due to a bug in System.IO.Packaging writing large uncompressed parts (>10MB) isn't thread safe in .NET 3.5. // Workaround: make writing in all threads and processes sequential. // Microsoft fixed this in .NET 4.5 (see https://maheshkumar.wordpress.com/2014/10/21/). PackageMutex.WaitOne(Timeout.Infinite, false); try { #endif using (Package = WordprocessingDocument.Open(documentPath, true)) { var codeBlockBuilder = new CodeBlockBuilder(Package, true); CodeBlocks = codeBlockBuilder.CodeBlocks; Map = codeBlockBuilder.BodyMap; InvokeDocumentCode(); foreach (var cb in CodeBlocks) { cb.RemoveEmptyParagraphs(); } } #if NET35 && SUPPORT_MULTI_THREADING_AND_LARGE_DOCUMENTS_IN_NET35 } finally { PackageMutex.ReleaseMutex(); } #endif }
internal static Assembly Compile( string viewPath, string className, string baseClassName, Type modelType, List <string> usingDirectives, List <string> referencedAssemblies) { List <CodeBlock> codeBlocks; // Copy the template to a temporary file, so it can be opened even when the template is open in Word. // This makes testing templates a lot easier. var tempFilePath = $"{Path.GetTempPath()}{Guid.NewGuid():N}.cs.docx"; File.Copy(viewPath, tempFilePath, true); try { using (var package = WordprocessingDocument.Open(tempFilePath, false)) { var codeBlockBuilder = new CodeBlockBuilder(package, false); codeBlocks = codeBlockBuilder.CodeBlocks; } } finally { File.Delete(tempFilePath); } var invokeDocumentCodeBody = new StringBuilder(); for (var i = 0; i < codeBlocks.Count; ++i) { var cb = codeBlocks[i]; if (!string.IsNullOrEmpty(cb.Code)) { if (cb.Code[0] == '=') { // Expand <%=SomeVar%> into <% Write(SomeVar); %> invokeDocumentCodeBody.Append($" CurrentCodeBlock = CodeBlocks[{i}];{Environment.NewLine}"); invokeDocumentCodeBody.Append($" Write({cb.Code.Substring(1)});{Environment.NewLine}"); } else if (cb is Directive) { var directive = (Directive)cb; if (directive.Name.Equals("import")) { AddUsingDirective(directive, usingDirectives); } else if (directive.Name.Equals("assembly")) { AddReferencedAssembly(directive, referencedAssemblies); } } else if (cb is ConditionalText) { var ccb = (ConditionalText)cb; invokeDocumentCodeBody.Append($" CurrentCodeBlock = CodeBlocks[{i}];{Environment.NewLine}"); invokeDocumentCodeBody.Append($" if (!{ccb.Condition}) {{{Environment.NewLine}"); invokeDocumentCodeBody.Append($" DeleteConditionalContent();{Environment.NewLine}"); invokeDocumentCodeBody.Append($" }}{Environment.NewLine}"); invokeDocumentCodeBody.Append($" {cb.Code.TrimStart()}{Environment.NewLine}"); } else { invokeDocumentCodeBody.Append($" CurrentCodeBlock = CodeBlocks[{i}];{Environment.NewLine}"); invokeDocumentCodeBody.Append($" {cb.Code.TrimStart()}{Environment.NewLine}"); } } } var modelTypeName = modelType != null?FormatType(modelType) : "string"; var script = new StringBuilder(); script.Append(documentClassTemplate); script.Replace("{UsingDirectives}", FormatUsingDirectives(usingDirectives)); script.Replace("{Namespace}", Namespace); script.Replace("{ClassName}", className); script.Replace("{BaseClassName}", baseClassName); script.Replace("{ModelTypeName}", modelTypeName); script.Replace("{InvokeDocumentCodeBody}", invokeDocumentCodeBody.ToString()); return(Compile(script.ToString(), referencedAssemblies)); }