/// <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); }
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); }