none
Can't edit the table or chart data after merging the powerpoint slides using Open XML SDK

    Pregunta

  • Hi,

    I used Open XML SDK to merge multiple powerpoint documents into one.We have some of the tables and charts on these power point documents which can be editable.

    I used similar process which is described in the articleto merge powerpoint documents.

    http://openxmldeveloper.org/blog/b/openxmldeveloper/archive/2011/01/28/110420.aspx

    But once these are merged, I can't edit the tables / charts data and displays the error

    “The server application, source file, or item can’t be found, or returned an unknown error. You may need to reinstall the server application”

    I read in some places that it may happen if the document is in compressed format. I am not sure how to make it editable in open xml.

    I appreciate your help.

    Here is the sample code

     

      PresentationDocument myMonthlyDeck = null;
       myMonthlyDeck = PresentationDocument.Open("output.pptx", true);

       var inputFilePaths = Directory.GetFiles("\\input","*.pptx");

    foreach (string pptname in inputFilePaths)
                    {


                         MergeSlides(pptname, myMonthlyDeck);
          

                    }

           static void MergeSlides(string sourcePresentation, PresentationDocument myDestDoc)
            {
                int id = 0;

                {
                    PresentationPart destPresPart = myDestDoc.PresentationPart;

                     if (destPresPart.Presentation.SlideIdList == null)
                        destPresPart.Presentation.SlideIdList = new SlideIdList();

                    PresentationDocument mySourceDeck = PresentationDocument.Open(sourcePresentation, false);
                    // using ()
                    {
                        PresentationPart sourcePresPart = mySourceDeck.PresentationPart;

                        // Get unique ids for the slide master and slide lists for use later.
                        uniqueId = GetMaxSlideMasterId(destPresPart.Presentation.SlideMasterIdList);
                        uint maxSlideId = GetMaxSlideId(destPresPart.Presentation.SlideIdList);

                        // Copy each slide in the source presentation in order to the destination presentation.
                        foreach (SlideId slideId in sourcePresPart.Presentation.SlideIdList)
                        {
                            SlidePart sp;
                            SlidePart destSp;
                            SlideMasterPart destMasterPart;
                            string relId;
                            SlideMasterId newSlideMasterId;
                            SlideId newSlideId;

                            // Create a unique relationship id.
                            id++;
                            sp = (SlidePart)sourcePresPart.GetPartById(slideId.RelationshipId);
                            string filename = Path.GetFileName(sourcePresentation).Replace(" ", "c");
                            relId = "c" + filename.Trim() + id;

                            // Add the slide part to the destination presentation.
                            destSp = destPresPart.AddPart<SlidePart>(sp, relId);

                            // The master part was added. Make sure the relationship is in place.
                            destMasterPart = destSp.SlideLayoutPart.SlideMasterPart;
                            destPresPart.AddPart(destMasterPart);

                            // Add slide master to slide master list.
                            uniqueId++;
                            newSlideMasterId = new SlideMasterId();
                            newSlideMasterId.RelationshipId = destPresPart.GetIdOfPart(destMasterPart);
                            newSlideMasterId.Id = uniqueId;

                            // Add slide to slide list.
                            maxSlideId++;
                            newSlideId = new SlideId();
                            newSlideId.RelationshipId = relId;
                            newSlideId.Id = maxSlideId;

                            destPresPart.Presentation.SlideMasterIdList.Append(newSlideMasterId);
                            destPresPart.Presentation.SlideIdList.Append(newSlideId);
                        }

                        // Make sure all slide ids are unique.
                        FixSlideLayoutIds(destPresPart);
                    }

                    // Save the changes to the destination deck.
                    destPresPart.Presentation.Save();
                    mySourceDeck.Close();
                }

            }


    VM7258

    lunes, 30 de abril de 2012 20:08

Todas las respuestas

  • Hi VM7258,

    Thanks for posting in the MSDN Forum.

    You lost TableStylePart/ChartPart in your program.

    I hope it can help you.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    martes, 01 de mayo de 2012 7:55
  • Hi Tom_Xu,

    Thanks for the tip.

    Do you have any sample on how to carry over TableStylePart/ChartPart from source slide to target while copying?

    Thanks


    VM7258

    martes, 01 de mayo de 2012 9:55
  • Hivm7258,

    The following snippet will update TableStylePart, I have some trouble to add ChartPart. I will involve some experts into this thread to see whether them can help you. There might be some time delay, thanks for your patience.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Presentation;
    using DocumentFormat.OpenXml;
    using C = DocumentFormat.OpenXml.Drawing.Charts;
    using DocumentFormat.OpenXml.Drawing;
    using System.IO;
    
    namespace ConsoleApplication12
    {
        class Program
        {
            static void Main(string[] args)
            {
                string sourcePPTpath = @"C:\Users\v-yangxu\Desktop\Presentation1.pptx";
                string tragetPPTpath = @"C:\Users\v-yangxu\Desktop\Presentation2.pptx";
                File.Copy(tragetPPTpath, @"C:\Users\v-yangxu\Desktop\result.pptx", true);
                using (PresentationDocument pptd = PresentationDocument.Open(sourcePPTpath, false))
                {
                    PresentationPart pptp = pptd.PresentationPart;
                    using (PresentationDocument tppd = PresentationDocument
                        .Open(@"C:\Users\v-yangxu\Desktop\result.pptx", true))
                    {
                        PresentationPart tppt = tppd.PresentationPart;
                        List<SlideId> lsi = tppt.Presentation.SlideIdList.Descendants<SlideId>().ToList();
                        UInt32Value LastId = lsi.Last().Id;
                        TableStylesPart tsp = pptp.GetPartsOfType<TableStylesPart>().FirstOrDefault();
                        if (tsp != null)
                        {
                            CopyTableStylesPart(tsp, tppt);
                        }
                        Presentation p = pptp.Presentation;
                        foreach (SlideId srd in p.SlideIdList.Descendants<SlideId>().ToList())
                        {
                            SlidePart sp = pptp.GetPartById(srd.RelationshipId) as SlidePart;
                            if (sp != null)
                            {
                                CopySlidePart(sp, tppt,ref LastId);
                            }
                        }
                        tppt.Presentation.Save();
                    }
                }
            }
    
            private static void CopySlidePart(SlidePart sp, PresentationPart tppt,ref UInt32Value LastId)
            {
                SlidePart nsp = tppt.AddNewPart<SlidePart>();
                nsp.AddPart(sp.SlideLayoutPart);
                nsp.FeedData(sp.GetStream());
                SlideId newId = new SlideId()
                {
                    Id = (UInt32Value)(LastId.Value + 1),
                    RelationshipId = tppt.GetIdOfPart(nsp)
                };
                tppt.Presentation.SlideIdList.Append(newId);
                LastId.Value++;
                //List<ChartPart> cps = sp.ChartParts.ToList();
                //nsp.FeedData(sp.GetStream(FileMode.Open));
                //foreach (ChartPart cp in cps)
                //{
                //    ChartPart ncp = nsp.AddNewPart<ChartPart>();
                //    ncp.FeedData(cp.GetStream());
                //    EmbeddedPackagePart epp = ncp.AddNewPart<EmbeddedPackagePart>("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","MyID");
                //    epp.FeedData(cp.EmbeddedPackagePart.GetStream());
                //    C.ChartSpace cs = ncp.ChartSpace;
                //    C.ExternalData ed = cs.Descendants<C.ExternalData>().FirstOrDefault();
                //    ed.Id = ncp.GetIdOfPart(epp);
                //    ncp.ChartSpace.Save();
                //}
            }
    
            private static void CopyTableStylesPart(TableStylesPart tsp, PresentationPart tppt)
            {
                TableStylesPart ttsp = tppt.GetPartsOfType<TableStylesPart>().FirstOrDefault();
                ttsp.FeedData(tsp.GetStream());
            }
        }
    }

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    miércoles, 02 de mayo de 2012 10:31
  • Thanks TOM. I will wait for Chartstyle code and will test and let you know.

    VM7258

    miércoles, 02 de mayo de 2012 15:07
  • Hi VM7258,

    There is a blog by Brian Jones that gives you a working example of merging multiple decks with tables and charts, both types are editable, at:
    Open XML | Developer, Working with Microsoft PowerPoint
    http://msdn.microsoft.com/en-us/office/ee358825

    It has a link to download the project code, but before you do that read the entire blog page, and then build two PowerPoint 2010 presentations that roughly match the two he uses as examples. I added slides with table and another with a chart - the example already has one chart. The downloadable code will work with VS2008 or VS2010 (after conversion.) The code assumes the source and destination presentations are located in the project ..\bin\debug folder.


    Please remember to mark the replies as answer if they help and unmark them if the provide no help. and click "Vote as Helpful" this and other helpful posts, so other users will see your thread as useful. Chris Jensen

    martes, 15 de mayo de 2012 19:11