Пример #1
0
        /// <summary>
        /// Sets a background picture for a table cell (a:tc).
        /// </summary>
        /// <remarks>
        /// <![CDATA[
        /// <a:tc>
        ///  <a:txBody>
        ///   <a:bodyPr/>
        ///   <a:lstStyle/>
        ///   <a:p>
        ///    <a:endParaRPr lang="fr-FR" dirty="0"/>
        ///   </a:p>
        ///  </a:txBody>
        ///  <a:tcPr> (TableCellProperties)
        ///   <a:blipFill dpi="0" rotWithShape="1">
        ///    <a:blip r:embed="rId2"/>
        ///    <a:srcRect/>
        ///    <a:stretch>
        ///     <a:fillRect b="12000" r="90000" t="14000"/>
        ///    </a:stretch>
        ///   </a:blipFill>
        ///  </a:tcPr>
        /// </a:tc>
        /// ]]>
        /// </remarks>
        private static void SetTableCellPropertiesWithBackgroundPicture(PptxSlide slide, A.TableCellProperties tcPr, Cell.BackgroundPicture backgroundPicture)
        {
            if (backgroundPicture.Content == null)
            {
                return;
            }

            ImagePart imagePart = slide.AddPicture(backgroundPicture.Content, backgroundPicture.ContentType);

            A.BlipFill blipFill = new A.BlipFill();
            A.Blip     blip     = new A.Blip()
            {
                Embed = slide.GetIdOfImagePart(imagePart)
            };
            A.SourceRectangle srcRect  = new A.SourceRectangle();
            A.Stretch         stretch  = new A.Stretch();
            A.FillRectangle   fillRect = new A.FillRectangle()
            {
                Top    = backgroundPicture.Top,
                Right  = backgroundPicture.Right,
                Bottom = backgroundPicture.Bottom,
                Left   = backgroundPicture.Left
            };
            stretch.AppendChild(fillRect);
            blipFill.AppendChild(blip);
            blipFill.AppendChild(srcRect);
            blipFill.AppendChild(stretch);
            tcPr.AppendChild(blipFill);
        }
Пример #2
0
        /// <summary>
        /// Replaces the cells from the table (tbl).
        /// </summary>
        /// <returns>The list of remaining rows that could not be inserted, you will have to create a new slide.</returns>
        public List <Cell[]> SetRows(IList <Cell[]> rows)
        {
            PptxSlide slide = this.slideTemplate;

            A.Table tbl = slide.FindTable(this.tblId);

            int tblRowsCount = RowsCount(tbl);

            // done starts at 1 instead of 0 because we don't care about the first row
            // The first row contains the titles for the columns
            int done = 1;

            for (int i = 0; i < rows.Count(); i++)
            {
                Cell[] row = rows[i];

                if (done < tblRowsCount)
                {
                    // a:tr
                    A.TableRow tr = GetRow(tbl, done);

                    // a:tc
                    foreach (A.TableCell tc in tr.Descendants <A.TableCell>())
                    {
                        foreach (Cell cell in row)
                        {
                            ReplaceTag(slide, tc, cell);
                        }
                    }

                    done++;
                }
                else
                {
                    break;
                }
            }

            // Remove the last remaining rows if any
            for (int row = tblRowsCount - 1; row >= done; row--)
            {
                A.TableRow tr = GetRow(tbl, row);
                tr.Remove();
            }

            // Save the latest slide
            // Mandatory otherwise the next time SetRows() is run (on a different table)
            // the rows from the previous tables will not contained the right data (from PptxParagraph.ReplaceTag())
            slide.Save();

            // Computes the remaining rows if any
            List <Cell[]> remainingRows = new List <Cell[]>();

            for (int row = done - 1; row < rows.Count; row++)
            {
                remainingRows.Add(rows[row]);
            }

            return(remainingRows);
        }
Пример #3
0
        /// <summary>
        /// Inserts this slide after a given target slide.
        /// </summary>
        /// <param name="newSlide">The new slide to insert.</param>
        /// <param name="prevSlide">The previous slide.</param>
        /// <remarks>
        /// This slide will be inserted after the slide specified as a parameter.
        /// <see href="http://startbigthinksmall.wordpress.com/2011/05/17/cloning-a-slide-using-open-xml-sdk-2-0/">Cloning a Slide using Open Xml SDK 2.0</see>
        /// </remarks>
        public static void InsertAfter(PptxSlide newSlide, PptxSlide prevSlide)
        {
            // Find the presentationPart
            var presentationPart = prevSlide.presentationPart;

            SlideIdList slideIdList = presentationPart.Presentation.SlideIdList;

            // Find the slide id where to insert our slide
            SlideId prevSlideId = null;

            foreach (SlideId slideId in slideIdList.ChildElements)
            {
                // See http://openxmldeveloper.org/discussions/development_tools/f/17/p/5302/158602.aspx
                if (slideId.RelationshipId == presentationPart.GetIdOfPart(prevSlide.slidePart))
                {
                    prevSlideId = slideId;
                    break;
                }
            }

            // Find the highest id
            uint maxSlideId = slideIdList.ChildElements.Cast <SlideId>().Max(x => x.Id.Value);

            // public override T InsertAfter<T>(T newChild, DocumentFormat.OpenXml.OpenXmlElement refChild)
            // Inserts the specified element immediately after the specified reference element.
            SlideId newSlideId = slideIdList.InsertAfter(new SlideId(), prevSlideId);

            newSlideId.Id             = maxSlideId + 1;
            newSlideId.RelationshipId = presentationPart.GetIdOfPart(newSlide.slidePart);
        }
Пример #4
0
        /// <summary>
        /// Inserts this slide after a given target slide.
        /// </summary>
        /// <param name="newSlide">The new slide to insert.</param>
        /// <param name="prevSlide">The previous slide.</param>
        /// <remarks>
        /// This slide will be inserted after the slide specified as a parameter.
        /// <see href="http://startbigthinksmall.wordpress.com/2011/05/17/cloning-a-slide-using-open-xml-sdk-2-0/">Cloning a Slide using Open Xml SDK 2.0</see>
        /// </remarks>
        public static void InsertAfter(PptxSlide newSlide, PptxSlide prevSlide)
        {
            // Find the presentationPart
            var presentationPart = prevSlide.presentationPart;

            SlideIdList slideIdList = presentationPart.Presentation.SlideIdList;

            // Find the slide id where to insert our slide
            SlideId prevSlideId = null;
            foreach (SlideId slideId in slideIdList.ChildElements)
            {
                // See http://openxmldeveloper.org/discussions/development_tools/f/17/p/5302/158602.aspx
                if (slideId.RelationshipId == presentationPart.GetIdOfPart(prevSlide.slidePart))
                {
                    prevSlideId = slideId;
                    break;
                }
            }

            // Find the highest id
            uint maxSlideId = slideIdList.ChildElements.Cast<SlideId>().Max(x => x.Id.Value);

            // public override T InsertAfter<T>(T newChild, DocumentFormat.OpenXml.OpenXmlElement refChild)
            // Inserts the specified element immediately after the specified reference element.
            SlideId newSlideId = slideIdList.InsertAfter(new SlideId(), prevSlideId);
            newSlideId.Id = maxSlideId + 1;
            newSlideId.RelationshipId = presentationPart.GetIdOfPart(newSlide.slidePart);
        }
Пример #5
0
        /// <summary>
        /// Replaces the cells from a table (tbl).
        /// Algorithm for a slide template containing multiple tables.
        /// </summary>
        /// <param name="slideTemplate">The slide template that contains the table(s).</param>
        /// <param name="tableTemplate">The table (tbl) to use, should be inside the slide template.</param>
        /// <param name="rows">The rows to replace the table's cells.</param>
        /// <param name="existingSlides">Existing slides created for the other tables inside the slide template.</param>
        /// <returns>The newly created slides if any.</returns>
        public static IEnumerable <PptxSlide> ReplaceTable_Multiple(PptxSlide slideTemplate, PptxTable tableTemplate, IList <PptxTable.Cell[]> rows, List <PptxSlide> existingSlides)
        {
            List <PptxSlide> slidesCreated = new List <PptxSlide>();

            string tag = tableTemplate.Title;

            PptxSlide lastSlide = slideTemplate;

            if (existingSlides.Count > 0)
            {
                lastSlide = existingSlides.Last();
            }

            PptxSlide lastSlideTemplate = lastSlide.Clone();

            foreach (PptxSlide slide in existingSlides)
            {
                PptxTable table = slide.FindTables(tag).First();
                List <PptxTable.Cell[]> remainingRows = table.SetRows(rows);
                rows = remainingRows;
            }

            // Force SetRows() at least once if there is no existingSlides
            // this means we are being called by ReplaceTable_One()
            bool loopOnce = existingSlides.Count == 0;

            while (loopOnce || rows.Count > 0)
            {
                PptxSlide newSlide = lastSlideTemplate.Clone();
                PptxTable table    = newSlide.FindTables(tag).First();
                List <PptxTable.Cell[]> remainingRows = table.SetRows(rows);
                rows = remainingRows;

                PptxSlide.InsertAfter(newSlide, lastSlide);
                lastSlide = newSlide;
                slidesCreated.Add(newSlide);

                if (loopOnce)
                {
                    loopOnce = false;
                }
            }

            lastSlideTemplate.Remove();

            return(slidesCreated);
        }
Пример #6
0
        /// <summary>
        /// Finds the slides matching a given note.
        /// </summary>
        /// <param name="note">Note to match the slide with.</param>
        /// <returns>The matching slides.</returns>
        public IEnumerable <PptxSlide> FindSlides(string note)
        {
            List <PptxSlide> slides = new List <PptxSlide>();

            for (int i = 0; i < this.SlidesCount(); i++)
            {
                PptxSlide            slide = this.GetSlide(i);
                IEnumerable <string> notes = slide.GetNotes();
                foreach (string tmp in notes)
                {
                    if (tmp.Contains(note))
                    {
                        slides.Add(slide);
                        break;
                    }
                }
            }

            return(slides);
        }
Пример #7
0
        /// <summary>
        /// Replaces a tag inside a given table cell (a:tc).
        /// </summary>
        /// <param name="slide">The PptxSlide.</param>
        /// <param name="tc">The table cell (a:tc).</param>
        /// <param name="cell">Contains the tag, the new text and a picture.</param>
        /// <returns><c>true</c> if a tag has been found and replaced, <c>false</c> otherwise.</returns>
        private static bool ReplaceTag(PptxSlide slide, A.TableCell tc, Cell cell)
        {
            bool replacedAtLeastOnce = false;

            // a:p
            foreach (A.Paragraph p in tc.Descendants <A.Paragraph>())
            {
                bool replaced = PptxParagraph.ReplaceTag(p, cell.Tag, cell.NewText);
                if (replaced)
                {
                    replacedAtLeastOnce = true;

                    // a:tcPr
                    if (cell.Picture != null)
                    {
                        A.TableCellProperties tcPr = tc.GetFirstChild <A.TableCellProperties>();
                        SetTableCellPropertiesWithBackgroundPicture(slide, tcPr, cell.Picture);
                    }
                }
            }

            return(replacedAtLeastOnce);
        }
Пример #8
0
        /// <summary>
        /// Replaces a tag inside the table (a:tbl).
        /// </summary>
        /// <param name="cell">Contains the tag, the new text and a pciture.</param>
        /// <returns><c>true</c> if a tag has been found and replaced, <c>false</c> otherwise.</returns>
        public bool ReplaceTag(Cell cell)
        {
            bool replacedAtLeastOnce = false;

            PptxSlide slide = this.slideTemplate;

            A.Table tbl = slide.FindTable(this.tblId);

            // a:tr
            foreach (A.TableRow tr in tbl.Descendants <A.TableRow>())
            {
                // a:tc
                foreach (A.TableCell tc in tr.Descendants <A.TableCell>())
                {
                    bool replaced = ReplaceTag(slide, tc, cell);
                    if (replaced)
                    {
                        replacedAtLeastOnce = true;
                    }
                }
            }

            return(replacedAtLeastOnce);
        }
Пример #9
0
 /// <summary>
 /// Replaces the cells from a table (tbl).
 /// Algorithm for a slide template containing one table.
 /// </summary>
 public static IEnumerable <PptxSlide> ReplaceTable_One(PptxSlide slideTemplate, PptxTable tableTemplate, IList <PptxTable.Cell[]> rows)
 {
     return(ReplaceTable_Multiple(slideTemplate, tableTemplate, rows, new List <PptxSlide>()));
 }
Пример #10
0
 internal PptxTable(PptxSlide slideTemplate, int tblId, string title)
 {
     this.slideTemplate = slideTemplate;
     this.tblId         = tblId;
     this.Title         = title;
 }
Пример #11
0
        /// <summary>
        /// Replaces a tag inside a paragraph (a:p) with parsed HTML
        /// </summary>
        /// <param name="p">The paragraph (a:p).</param>
        /// <param name="tag">The tag to replace by newText, if null or empty do nothing; tag is a regex string.</param>
        /// <param name="newText">The new text to replace the tag with, if null replaced by empty string and not visible.</param>
        /// <param name="fontName">Font name</param>
        /// <param name="fontSize">Font size. E.g. 800 is 8pt (small) font. If value is less than 100 it will be multiplied by 100 to keep up with PPT notation.</param>
        /// <param name="hyperlinks">URL Relationships dictionary. Relationship has to be defined on slide level.</param>
        /// <returns><c>true</c> if a tag has been found and replaced, <c>false</c> otherwise.</returns>
        internal static bool ReplaceTagWithHtml(A.Paragraph p, string tag, string newText, string fontName = null, int fontSize = 0, IDictionary <string, string> hyperlinks = null)
        {
            newText = CorrectUnhandledHtmlTags(newText); // e.g. deal with ul/li html tags
            bool isFirstLine = true;                     // avoiding unintentional empty line at the begining of the text
            bool replaced    = false;

            string[] closingTags = new string[] { "div", "p" }; // tags that force line break in PPTX paragraph

            if (string.IsNullOrEmpty(tag))
            {
                return(replaced);
            }

            if (newText == null)
            {
                newText = string.Empty;
            }
            newText = RemoveInvalidXMLChars(newText);

            while (true)
            {
                // Search for the tag
                Match match = Regex.Match(GetTexts(p), tag);
                if (!match.Success)
                {
                    break;
                }

                p.RemoveAllChildren(); // // remove exisitng children then add new

                HtmlParser hp = new HtmlParser(newText);
                MariGold.HtmlParser.IHtmlNode nodes = null;

                try
                {
                    nodes = hp.FindBodyOrFirstElement();
                }
                catch
                {
                    Console.WriteLine(String.Format("WARNING: HTML is empty or HTML schema has errors. Parsed HTML[]: [{0}]", newText));
                }

                while (nodes != null)
                {
                    foreach (var item in nodes.Children)
                    {
                        bool  skipLineBreak = false;
                        A.Run r             = new A.Run();
                        r.RunProperties = new A.RunProperties();

                        if (item.Html.Contains("<b>") || item.Html.Contains("<strong>"))
                        {
                            r.RunProperties.Bold = new DocumentFormat.OpenXml.BooleanValue(true);
                        }
                        if (item.Html.Contains("<i>") || item.Html.Contains("<em>"))
                        {
                            r.RunProperties.Italic = new DocumentFormat.OpenXml.BooleanValue(true);
                        }
                        if (item.Html.Contains("<u>") || item.Html.Contains("text-decoration: underline"))
                        {
                            r.RunProperties.Underline = new DocumentFormat.OpenXml.EnumValue <A.TextUnderlineValues>(A.TextUnderlineValues.Dash);
                        }
                        if (item.Html.Contains("<a"))
                        {
                            string uriId = null;
                            try
                            {
                                string url = PptxSlide.ParseHttpUrls(item.Html).First().Value;
                                uriId = hyperlinks.Where(q => q.Value == url).FirstOrDefault().Key;
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("URL is no available");
                            }
                            if (uriId != null)
                            {
                                A.HyperlinkOnClick link = new A.HyperlinkOnClick()
                                {
                                    Id = uriId
                                };
                                r.RunProperties.AppendChild(link);
                            }
                        }

                        A.Text at = new A.Text(PptxTemplater.TextTransformationHelper.HtmlToPlainTxt(item.InnerHtml) + " "); // clear not interpreted html tags
                        if (at.InnerText.Trim() == "" && isFirstLine)
                        {
                            at          = new A.Text(); // avoid excessive new lines
                            isFirstLine = false;
                        }
                        r.AppendChild(at);
                        p.Append(r);

                        // LINE BREAK -- if outer tag is div add line break
                        if (closingTags.Contains(item.Parent.Tag) && skipLineBreak == false)
                        {
                            p.Append(new A.Break());
                        }
                    }

                    // remove parsed html part
                    newText = newText.Substring(nodes.Html.Length);
                    if (newText.Trim() == "")
                    {
                        break;
                    }
                    hp    = new HtmlParser(newText);
                    nodes = hp.FindBodyOrFirstElement();
                }

                var run = p.Descendants <A.Run>();
                foreach (var item in run)
                {
                    if (fontName != null)
                    {
                        item.RunProperties.RemoveAllChildren <A.LatinFont>();
                        var latinFont = new A.LatinFont();
                        latinFont.Typeface = fontName;
                        item.RunProperties.AppendChild(latinFont);
                    }
                    if (fontSize > 0)
                    {
                        item.RunProperties.FontSize = (fontSize > 99) ? fontSize : fontSize * 100; // e.g. translate value 8 (Power Point UI font size) to 800 for API
                    }
                }

                replaced = true;
            }

            return(replaced);
        }
Пример #12
0
        /// <summary>
        /// Replaces the cells from a table (tbl).
        /// Algorithm for a slide template containing multiple tables.
        /// </summary>
        /// <param name="slideTemplate">The slide template that contains the table(s).</param>
        /// <param name="tableTemplate">The table (tbl) to use, should be inside the slide template.</param>
        /// <param name="rows">The rows to replace the table's cells.</param>
        /// <param name="existingSlides">Existing slides created for the other tables inside the slide template.</param>
        /// <returns>The newly created slides if any.</returns>
        public static IEnumerable<PptxSlide> ReplaceTable_Multiple(PptxSlide slideTemplate, PptxTable tableTemplate, IList<PptxTable.Cell[]> rows, List<PptxSlide> existingSlides)
        {
            List<PptxSlide> slidesCreated = new List<PptxSlide>();

            string tag = tableTemplate.Title;

            PptxSlide lastSlide = slideTemplate;
            if (existingSlides.Count > 0)
            {
                lastSlide = existingSlides.Last();
            }

            PptxSlide lastSlideTemplate = lastSlide.Clone();

            foreach (PptxSlide slide in existingSlides)
            {
                PptxTable table = slide.FindTables(tag).First();
                List<PptxTable.Cell[]> remainingRows = table.SetRows(rows);
                rows = remainingRows;
            }

            // Force SetRows() at least once if there is no existingSlides
            // this means we are being called by ReplaceTable_One()
            bool loopOnce = existingSlides.Count == 0;

            while (loopOnce || rows.Count > 0)
            {
                PptxSlide newSlide = lastSlideTemplate.Clone();
                PptxTable table = newSlide.FindTables(tag).First();
                List<PptxTable.Cell[]> remainingRows = table.SetRows(rows);
                rows = remainingRows;

                PptxSlide.InsertAfter(newSlide, lastSlide);
                lastSlide = newSlide;
                slidesCreated.Add(newSlide);

                if (loopOnce) loopOnce = false;
            }

            lastSlideTemplate.Remove();

            return slidesCreated;
        }
Пример #13
0
 /// <summary>
 /// Replaces the cells from a table (tbl).
 /// Algorithm for a slide template containing one table.
 /// </summary>
 public static IEnumerable<PptxSlide> ReplaceTable_One(PptxSlide slideTemplate, PptxTable tableTemplate, IList<PptxTable.Cell[]> rows)
 {
     return ReplaceTable_Multiple(slideTemplate, tableTemplate, rows, new List<PptxSlide>());
 }
Пример #14
0
        /// <summary>
        /// Sets a background picture for a table cell (a:tc).
        /// </summary>
        /// <remarks>
        /// <![CDATA[
        /// <a:tc>
        ///  <a:txBody>
        ///   <a:bodyPr/>
        ///   <a:lstStyle/>
        ///   <a:p>
        ///    <a:endParaRPr lang="fr-FR" dirty="0"/>
        ///   </a:p>
        ///  </a:txBody>
        ///  <a:tcPr> (TableCellProperties)
        ///   <a:blipFill dpi="0" rotWithShape="1">
        ///    <a:blip r:embed="rId2"/>
        ///    <a:srcRect/>
        ///    <a:stretch>
        ///     <a:fillRect b="12000" r="90000" t="14000"/>
        ///    </a:stretch>
        ///   </a:blipFill>
        ///  </a:tcPr>
        /// </a:tc>
        /// ]]>
        /// </remarks>
        private static void SetTableCellPropertiesWithBackgroundPicture(PptxSlide slide, A.TableCellProperties tcPr, Cell.BackgroundPicture backgroundPicture)
        {
            if (backgroundPicture.Content == null)
            {
                return;
            }

            ImagePart imagePart = slide.AddPicture(backgroundPicture.Content, backgroundPicture.ContentType);

            A.BlipFill blipFill = new A.BlipFill();
            A.Blip blip = new A.Blip() { Embed = slide.GetIdOfImagePart(imagePart) };
            A.SourceRectangle srcRect = new A.SourceRectangle();
            A.Stretch stretch = new A.Stretch();
            A.FillRectangle fillRect = new A.FillRectangle()
                {
                    Top = backgroundPicture.Top,
                    Right = backgroundPicture.Right,
                    Bottom = backgroundPicture.Bottom,
                    Left = backgroundPicture.Left
                };
            stretch.AppendChild(fillRect);
            blipFill.AppendChild(blip);
            blipFill.AppendChild(srcRect);
            blipFill.AppendChild(stretch);
            tcPr.AppendChild(blipFill);
        }
Пример #15
0
        /// <summary>
        /// Replaces a tag inside a given table cell (a:tc).
        /// </summary>
        /// <param name="slide">The PptxSlide.</param>
        /// <param name="tc">The table cell (a:tc).</param>
        /// <param name="cell">Contains the tag, the new text and a picture.</param>
        /// <returns><c>true</c> if a tag has been found and replaced, <c>false</c> otherwise.</returns>
        private static bool ReplaceTag(PptxSlide slide, A.TableCell tc, Cell cell)
        {
            bool replacedAtLeastOnce = false;

            // a:p
            foreach (A.Paragraph p in tc.Descendants<A.Paragraph>())
            {
                bool replaced = PptxParagraph.ReplaceTag(p, cell.Tag, cell.NewText);
                if (replaced)
                {
                    replacedAtLeastOnce = true;

                    // a:tcPr
                    if (cell.Picture != null)
                    {
                        A.TableCellProperties tcPr = tc.GetFirstChild<A.TableCellProperties>();
                        SetTableCellPropertiesWithBackgroundPicture(slide, tcPr, cell.Picture);
                    }
                }
            }

            return replacedAtLeastOnce;
        }
Пример #16
0
 internal PptxTable(PptxSlide slideTemplate, int tblId, string title)
 {
     this.slideTemplate = slideTemplate;
     this.tblId = tblId;
     this.Title = title;
 }