none
Copy chart from one presentation to another presentation

    Question

  • Sorry for my English :)

    I try to copy a chart element from one presentation to another with the same position

    using C = DocumentFormat.OpenXml.Drawing.Charts;
    
    namespace OpenXmlApp
    {
        public class ShapeReader
        {
            public static void CopyChart(string sourPrePath, string destPrePath)
            {
                using (var sourDoc = PresentationDocument.Open(sourPrePath, false))
                {
                    using (var destDoc = PresentationDocument.Open(destPrePath, true))
                    {
                        // Get copy of graphic frame.
                        var sourGraphicFrameCopy = sourDoc.PresentationPart.SlideParts.First().Slide.CommonSlideData.ShapeTree
                                                          .GetFirstChild<P.GraphicFrame>().CloneNode(true);
    
                        // Add copy of graphic frame to destinition slide.
                        var destSlidePart = destDoc.PresentationPart.SlideParts.First();
                        var destShapeTree = destSlidePart.Slide.CommonSlideData.ShapeTree;
                        destShapeTree.Append(sourGraphicFrameCopy);
    
                        // Add chart part to destinition slide.
                        var sourChartPart = sourDoc.PresentationPart.SlideParts.First().ChartParts.First();
                        var addedChartPart = destSlidePart.AddNewPart<ChartPart>();
                        addedChartPart.FeedData(sourChartPart.GetStream());                    
    
                        // Link added graphic frame and added chart part.
                        var chartRef = sourGraphicFrameCopy.Descendants<C.ChartReference>().SingleOrDefault();                    
                        var addedChartPartId = destSlidePart.GetIdOfPart(addedChartPart);
                        chartRef.Id = addedChartPartId;
    
                        destDoc.Save();
                    }
                }
            }

    but this code just broke presentation - PowerPoint tries to restore the result presentation.

    How correctly copy chart element?

    vendredi 22 juin 2018 10:28

Réponses

  • Hi adamShakhabov,

    The code above only copy the chartPart and the graphicFrame, but it doesn't copy the data for the chart. Below is an example works well for me to copy a chart from one presentation to another. 

            static void Main(string[] args)
            {
                string fromPresentation1 = @"source.pptx";
                string toPresentation2 = @"target.pptx";
                string toPresentation2Backup = @"target - Copy.pptx";
                File.Delete(toPresentation2);
                File.Copy(toPresentation2Backup, toPresentation2);
                CopyChart(fromPresentation1, toPresentation2);
    
                Process.Start(toPresentation2);
            }
    
            private static void CopyChart(string fromPresentation1, string toPresentation2)
            {
                
                using (PresentationDocument ppt1 = PresentationDocument.Open(fromPresentation1, false))
                using (PresentationDocument ppt2 = PresentationDocument.Open(toPresentation2, true))
                {
    
                    SlideId fromSlideId = ppt1.PresentationPart.Presentation.SlideIdList.GetFirstChild<SlideId>();
                    string fromRelId = fromSlideId.RelationshipId;
    
                    SlideId toSlideId = ppt2.PresentationPart.Presentation.SlideIdList.GetFirstChild<SlideId>();
                    string toRelId = fromSlideId.RelationshipId;
    
                    SlidePart fromSlidePart = (SlidePart)ppt1.PresentationPart.GetPartById(fromRelId);
                    SlidePart toSlidePart = (SlidePart)ppt2.PresentationPart.GetPartById(fromRelId);
    
                    var graphFrame=fromSlidePart.Slide.CommonSlideData.ShapeTree.GetFirstChild<GraphicFrame>().CloneNode(true);
                    GroupShapeProperties groupShapeProperties = toSlidePart.Slide.CommonSlideData.ShapeTree.GetFirstChild<GroupShapeProperties>();
                    toSlidePart.Slide.CommonSlideData.ShapeTree.InsertAfter(graphFrame, groupShapeProperties);
    
                    ChartPart fromChartPart = fromSlidePart.ChartParts.First();
                    ChartPart toChartPart = toSlidePart.AddNewPart<ChartPart>("rId2");
    
    
                    using (StreamReader streamReader = new StreamReader(fromChartPart.GetStream()))
                    using (StreamWriter streamWriter = new StreamWriter(toChartPart.GetStream(FileMode.Create)))
                    {
                        streamWriter.Write(streamReader.ReadToEnd());
                    }
    
                    EmbeddedPackagePart fromEmbeddedPackagePart1 = fromChartPart.EmbeddedPackagePart;
                    EmbeddedPackagePart toEmbeddedPackagePart1 = toChartPart.AddNewPart<EmbeddedPackagePart>("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "rId3");
    
                    using (StreamReader streamReader = new StreamReader(fromEmbeddedPackagePart1.GetStream()))
                        toEmbeddedPackagePart1.FeedData(streamReader.BaseStream);
                
                }
            }

    In-addition, to troubleshoot the problem when developing with OpenXML, I recommend you valid/compare the file generated by using code via Open XML SDK 2.5 Productivity Tool for Microsoft Office(This tool is very helpful). The full test sample code you can download from here.

    Please feel free to let me know if you have any problem about this issue.

    Regards & Fei



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    jeudi 28 juin 2018 07:03
    Modérateur

Toutes les réponses

  • Hello adamShakhabov,

    Based on my current test, addedChartPart.FeedData(sourChartPart.GetStream()) failed to copy all the sourChartPart to addedChartPart. For  instance, a ChartPart contains ChartStyleParts, ColorStyleParts, EmbeddedPackagePart and a ChartSpace. The FeedData could only copy the ChartSpace and other Parts are missed.

    I'm trying to involve some senior engineers into this issue and it will take some time. Your patience will be greatly appreciated.

    Sorry for any inconvenience and have a nice day! 

    Best Regards,

    Terry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    mardi 26 juin 2018 01:42
    Modérateur
  • Hi adamShakhabov,

    The code above only copy the chartPart and the graphicFrame, but it doesn't copy the data for the chart. Below is an example works well for me to copy a chart from one presentation to another. 

            static void Main(string[] args)
            {
                string fromPresentation1 = @"source.pptx";
                string toPresentation2 = @"target.pptx";
                string toPresentation2Backup = @"target - Copy.pptx";
                File.Delete(toPresentation2);
                File.Copy(toPresentation2Backup, toPresentation2);
                CopyChart(fromPresentation1, toPresentation2);
    
                Process.Start(toPresentation2);
            }
    
            private static void CopyChart(string fromPresentation1, string toPresentation2)
            {
                
                using (PresentationDocument ppt1 = PresentationDocument.Open(fromPresentation1, false))
                using (PresentationDocument ppt2 = PresentationDocument.Open(toPresentation2, true))
                {
    
                    SlideId fromSlideId = ppt1.PresentationPart.Presentation.SlideIdList.GetFirstChild<SlideId>();
                    string fromRelId = fromSlideId.RelationshipId;
    
                    SlideId toSlideId = ppt2.PresentationPart.Presentation.SlideIdList.GetFirstChild<SlideId>();
                    string toRelId = fromSlideId.RelationshipId;
    
                    SlidePart fromSlidePart = (SlidePart)ppt1.PresentationPart.GetPartById(fromRelId);
                    SlidePart toSlidePart = (SlidePart)ppt2.PresentationPart.GetPartById(fromRelId);
    
                    var graphFrame=fromSlidePart.Slide.CommonSlideData.ShapeTree.GetFirstChild<GraphicFrame>().CloneNode(true);
                    GroupShapeProperties groupShapeProperties = toSlidePart.Slide.CommonSlideData.ShapeTree.GetFirstChild<GroupShapeProperties>();
                    toSlidePart.Slide.CommonSlideData.ShapeTree.InsertAfter(graphFrame, groupShapeProperties);
    
                    ChartPart fromChartPart = fromSlidePart.ChartParts.First();
                    ChartPart toChartPart = toSlidePart.AddNewPart<ChartPart>("rId2");
    
    
                    using (StreamReader streamReader = new StreamReader(fromChartPart.GetStream()))
                    using (StreamWriter streamWriter = new StreamWriter(toChartPart.GetStream(FileMode.Create)))
                    {
                        streamWriter.Write(streamReader.ReadToEnd());
                    }
    
                    EmbeddedPackagePart fromEmbeddedPackagePart1 = fromChartPart.EmbeddedPackagePart;
                    EmbeddedPackagePart toEmbeddedPackagePart1 = toChartPart.AddNewPart<EmbeddedPackagePart>("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "rId3");
    
                    using (StreamReader streamReader = new StreamReader(fromEmbeddedPackagePart1.GetStream()))
                        toEmbeddedPackagePart1.FeedData(streamReader.BaseStream);
                
                }
            }

    In-addition, to troubleshoot the problem when developing with OpenXML, I recommend you valid/compare the file generated by using code via Open XML SDK 2.5 Productivity Tool for Microsoft Office(This tool is very helpful). The full test sample code you can download from here.

    Please feel free to let me know if you have any problem about this issue.

    Regards & Fei



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    jeudi 28 juin 2018 07:03
    Modérateur