Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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
        }
Esempio n. 3
0
        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));
        }