예제 #1
0
        /// <summary>
        /// Creates a deep copy of this <see cref="ChartModel"/> and associated chart in the worksheet.
        /// </summary>
        /// <param name="targetWorksheet">The worksheet into which the clone will be placed. If null, the cloned <see cref="ChartModel"/> will be based on the original <see cref="Worksheet"/>/></param>
        /// <returns>The <see cref="ChartModel"/> that represents the chart</returns>
        public ChartModel Clone(Worksheet targetWorksheet)
        {
            // If no target worksheet is supplied, clone in situ (ie. on the current worksheet)
            Worksheet cloneToWorksheet = targetWorksheet == null ? this.worksheet : targetWorksheet;

            // Name of the source and target worksheet (for debugging)
            string sourceWorksheetName = this.worksheet.WorksheetPart.GetSheetName();
            string targetWorksheetName = cloneToWorksheet.WorksheetPart.GetSheetName();

            System.Diagnostics.Debug.Print("ChartModel - Cloning chart on worksheet '{0}' into '{1}'", sourceWorksheetName, targetWorksheetName);

            // Create a DrawingPart in the target worksheet if it does not already exist
            if (cloneToWorksheet.WorksheetPart.DrawingsPart == null)
            {
                var drawingsPart = cloneToWorksheet.WorksheetPart.AddNewPart <DrawingsPart>();
                drawingsPart.WorksheetDrawing = new DrawingSpreadsheet.WorksheetDrawing();

                // if a drawings part is being created then we need to add a Drawing to the end of the targetworksheet
                DocumentFormat.OpenXml.Spreadsheet.Drawing drawing = new DocumentFormat.OpenXml.Spreadsheet.Drawing()
                {
                    Id = cloneToWorksheet.WorksheetPart.GetIdOfPart(cloneToWorksheet.WorksheetPart.DrawingsPart)
                };

                cloneToWorksheet.Append(drawing);
            }

            // Take copy elements
            ChartPart chartPart2 = cloneToWorksheet.WorksheetPart.DrawingsPart.AddNewPart <ChartPart>();

            chartPart2.FeedData(this.chartPart.GetStream());

            // Clone the anchor for the template chart to get a new chart anchor
            DrawingSpreadsheet.TwoCellAnchor anchor2 = (DrawingSpreadsheet.TwoCellAnchor) this.anchor.CloneNode(true);

            // Insert the cloned anchor into the worksheet drawing of the DrawingsPart.
            cloneToWorksheet.WorksheetPart.DrawingsPart.WorksheetDrawing.Append(anchor2);

            // Update the ChartReference in the Anchor 2 (TwoCellAnchor -> GraphicFrame -> Graphic -> GraphicData -> ChartReference)
            DrawingCharts.ChartReference chartReference2 = anchor2.Descendants <DrawingCharts.ChartReference>().FirstOrDefault();
            chartReference2.Id = cloneToWorksheet.WorksheetPart.DrawingsPart.GetIdOfPart(chartPart2);

            // Get information about the cloned chart
            IEnumerable <OpenXmlCompositeElement> chartElements = GetChartElements(chartPart2);

            // Wrap and return as a model
            ChartModel chartModel = new ChartModel(chartPart2, anchor2)
            {
                Worksheet     = cloneToWorksheet,
                ChartId       = this.ChartId,
                ChartElements = chartElements,
                IsValid       = true,
            };

            return(chartModel);
        }
예제 #2
0
        public static ChartPart cloneChart(WorksheetPart worksheetPart, string chartTitle, int posLi, int posCol, int largeLi, int largeCol)
        {
            //Obtention de tous les ChartParts dans une enumeration
            DrawingsPart            dp  = worksheetPart.DrawingsPart;
            IEnumerable <ChartPart> cps = dp.ChartParts;

            //Recherche la ChartPart qui porte le titre correspondant
            ChartPart b = null;

            foreach (ChartPart cp in cps)
            {
                if (cp.ChartSpace.Descendants <Chart.Chart>().First().Descendants <Chart.Title>().First().Descendants <DocumentFormat.OpenXml.Drawing.Run>().First().Text.Text == chartTitle)
                {
                    b = cp;
                }
            }

            DrawingsPart a = worksheetPart.DrawingsPart;

            //Ajout de la nouvelle partie et copie
            ChartPart x      = a.AddNewPart <ChartPart>();
            Stream    stream = b.GetStream();

            x.FeedData(stream);

            string id = a.GetIdOfPart(b);

            //Copie de l'ancre associée au graph original
            Draw.TwoCellAnchor newAnchor = null;
            DocumentFormat.OpenXml.Drawing.Spreadsheet.WorksheetDrawing wsd = a.WorksheetDrawing;
            foreach (Draw.TwoCellAnchor tca in wsd.Elements <Draw.TwoCellAnchor>())
            {
                string tmp = tca.Descendants <Chart.ChartReference>().First().Id;
                if (tmp == id)
                {
                    newAnchor = (Draw.TwoCellAnchor)tca.CloneNode(true);
                }
            }

            //positionnement de la nouvelle ancre
            int r = Convert.ToInt32(newAnchor.ToMarker.RowId.Text) - Convert.ToInt32(newAnchor.FromMarker.RowId.Text);
            int c = Convert.ToInt32(newAnchor.ToMarker.ColumnId.Text) - Convert.ToInt32(newAnchor.FromMarker.ColumnId.Text);

            newAnchor.FromMarker.ColumnId = new Draw.ColumnId()
            {
                Text = "" + largeCol * posCol
            };
            newAnchor.ToMarker.ColumnId = new Draw.ColumnId()
            {
                Text = "" + (c + largeCol * posCol)
            };

            newAnchor.FromMarker.RowId = new Draw.RowId()
            {
                Text = "" + largeLi * posLi
            };
            newAnchor.ToMarker.RowId = new Draw.RowId()
            {
                Text = "" + (r + largeLi * posLi)
            };
            newAnchor.Descendants <Chart.ChartReference>().First().Id = a.GetIdOfPart(x);
            wsd.Append(newAnchor);

            return(x);
        }