示例#1
0
        public void ReplaceString(OpenXmlElement element, string val)
        {
            var text = element.Descendants <Word.Text>().FirstOrDefault();
            var run  = text == null?element.Descendants <Word.Run>().FirstOrDefault() : FindParent <Word.Run>(text);

            var runp      = run.Parent;
            var paragraph = FindParent <Word.Paragraph>(runp);

            run.RsidRunProperties = null;
            run.RemoveAllChildren <Word.Text>();
            run.RemoveAllChildren <Word.RunProperties>();
            runp.RemoveAllChildren <Word.Run>();
            runp.RemoveAllChildren <Word.Break>();

            if (paragraph.ParagraphProperties?.ParagraphMarkRunProperties != null)
            {
                run.RunProperties = new Word.RunProperties();
                foreach (var item in paragraph.ParagraphProperties.ParagraphMarkRunProperties)
                {
                    run.RunProperties.AppendChild(item.CloneNode(true));
                }
            }
            if (text == null)
            {
                text = new Word.Text();
            }
            else if (text.Parent != null)
            {
                text.Remove();
            }
            string[] pagesplit = val.TrimEnd("\r\n".ToCharArray()).Split("\f".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            for (int p = 0; p < pagesplit.Length; p++)
            {
                var lineSpit = pagesplit[p].Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
                if (lineSpit.Length > 0)
                {
                    for (int i = 0; i < lineSpit.Length; i++)
                    {
                        if (p == 0 && i == 0)
                        {
                            text.Text  = lineSpit[0];
                            text.Space = SpaceProcessingModeValues.Preserve;
                            run.Append(text);
                            runp.Append(run);
                            continue;
                        }
                        Word.Run r = run.Clone() as Word.Run;
                        r.RemoveAllChildren <Word.Text>();
                        r.Append(new Word.Text(lineSpit[i])
                        {
                            Space = SpaceProcessingModeValues.Preserve
                        });

                        Word.Paragraph pr = (Word.Paragraph)paragraph.Clone();
                        pr.RemoveAllChildren <Word.Run>();
                        pr.RemoveAllChildren <Word.Break>();
                        pr.RemoveAllChildren <Word.SdtBlock>();
                        pr.RemoveAllChildren <Word.SdtRun>();

                        pr.Append(r);

                        paragraph.Parent.InsertAfter <Word.Paragraph>(pr, paragraph);
                        paragraph = pr;
                    }
                }
                if (p < pagesplit.Length - 1)
                {
                    var bp = new Word.Break()
                    {
                        Type = Word.BreakValues.Page
                    };
                    paragraph.AppendChild(bp);
                }
            }
        }
        public static MemoryStream BuildReport(IConfigurationRoot config)
        {
            //Read the template from disk
            byte[] byteArray = File.ReadAllBytes(config["ReportConfiguration:TemplateFile"]);
            //Load it into memory
            MemoryStream mem = new MemoryStream();

            mem.Write(byteArray, 0, byteArray.Length);
            //Open the word document from memory
            using (WordprocessingDocument output = WordprocessingDocument.Open(mem, true))
            {
                var doc             = output.MainDocumentPart.Document;
                var contentControls = output.ContentControls().ToList();

                foreach (var cc in contentControls)
                {
                    wp.SdtProperties props           = cc.Elements <wp.SdtProperties>().FirstOrDefault();
                    string           controlTitle    = props.Elements <wp.SdtAlias>().FirstOrDefault().Val;
                    string           controlTag      = props.Elements <wp.Tag>().FirstOrDefault().Val;
                    string           configKeyResult = String.Format("{0}:Result", controlTitle);
                    string           queryResult     = config[configKeyResult];

                    Type           sdtType       = ((wp.SdtElement)cc).GetType();
                    OpenXmlElement targetContent = null;

                    //Determine if the content control is actually a docpart (Table of Contents, etc.), so we can ignore it.
                    bool isDocPart = false;
                    //If the content control document tag is a block tag and has docpart object children, it's a docpart.
                    if (sdtType == typeof(wp.SdtBlock) && (((wp.SdtBlock)cc).Descendants <wp.SdtContentDocPartObject>().Count() > 0))
                    {
                        isDocPart = true;
                    }

                    if (!isDocPart)
                    {
                        //Replace our ReportParameter placeholders.
                        if (controlTag.Equals("ReportParameter"))
                        {
                            if (config[controlTitle] != null)
                            {
                                targetContent = new wp.Text(config[controlTitle]);
                            }
                            else
                            {
                                targetContent = new wp.Text("No Result");
                            }
                        }

                        //Replace our SingleValue placeholders with tables containing the query results.
                        if (controlTag.Equals("SingleValue"))
                        {
                            if (queryResult != null)
                            {
                                dynamic svData = JsonConvert.DeserializeObject <dynamic>(queryResult);
                                if (svData.rows.Count == 1)
                                {
                                    targetContent = new wp.Text(svData.rows[0][0].ToString());
                                }
                                else
                                {
                                    throw new IndexOutOfRangeException(String.Format("The QueryResult for {0} contained {1} row/s but a single row was expected.", controlTitle, svData.rows.Count));
                                }
                            }
                            else
                            {
                                targetContent = new wp.Text("No Result");
                            }
                        }

                        //Special handling is needed if a SingleValue or ReportParameter content control is actually configured as a SdtBlock instead of SdtRun.
                        if (controlTag.Equals("ReportParameter") || controlTag.Equals("SingleValue"))
                        {
                            if (sdtType == typeof(wp.SdtBlock))
                            {
                                var targetContentParent = cc.GetFirstChild <wp.SdtContentBlock>().GetFirstChild <wp.Paragraph>().CloneNode(true);
                                targetContentParent.GetFirstChild <wp.Run>().InsertAfterSelf(new wp.Run(targetContent));
                                targetContentParent.GetFirstChild <wp.Run>().Remove();
                                targetContent = targetContentParent;
                            }
                        }

                        //Replace our Table placeholders with tables containing the query results.
                        if (controlTag.Equals("Table"))
                        {
                            targetContent = BuildTable(queryResult, config["ReportConfiguration:TableStyle"]);
                        }

                        //Update the charts in our Chart placeholders with the data from the query results.
                        if (controlTag.Equals("Chart"))
                        {
                            UpdateChart(
                                cc.Descendants <drc.ChartReference>().FirstOrDefault(),
                                output,
                                controlTitle.Split(':').Last(),
                                queryResult);
                            targetContent = cc.GetFirstChild <wp.SdtContentBlock>().GetFirstChild <wp.Paragraph>().CloneNode(true);
                        }

                        //Remove PlaceholderText styles from all Run elements
                        foreach (var item in cc.Descendants <wp.Run>())
                        {
                            var rPr = item.GetFirstChild <wp.RunProperties>();
                            if (rPr != null && rPr.RunStyle != null)
                            {
                                if (rPr.RunStyle.Val == "PlaceholderText")
                                {
                                    rPr.RunStyle.Remove();
                                }
                            }
                        }

                        if (targetContent != null)
                        {
                            //The content control is inline
                            if (sdtType == typeof(wp.SdtRun))
                            {
                                cc.InsertAfterSelf(new wp.Run(targetContent));
                                cc.Remove();
                            }
                            //The content control is a table cell
                            else if (sdtType == typeof(wp.SdtCell))
                            {
                                wp.TableCell tc = (wp.TableCell)((cc.Descendants <wp.TableCell>().FirstOrDefault()).CloneNode(true));

                                if (targetContent.GetType() == typeof(wp.Text))
                                {
                                    wp.Run targetRun = tc.Descendants <wp.Run>().FirstOrDefault();
                                    targetRun.RemoveAllChildren();
                                    targetRun.Append(targetContent);
                                }
                                else
                                {
                                    tc.Append(targetContent);
                                }

                                cc.InsertAfterSelf(tc);
                                cc.Remove();
                            }
                            //The content control is multi-line
                            else if (sdtType == typeof(wp.SdtBlock))
                            {
                                cc.InsertAfterSelf(targetContent);
                                cc.Remove();
                            }
                        }
                    }
                }

                foreach (var footer in output.MainDocumentPart.FooterParts)
                {
                    footer.Footer.Save();
                }

                doc.Save();
                output.Close();

                return(mem);
            }
        }