/// <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); }
/// <summary> /// Creates a deep copy of this <see cref="PictureModel"/> 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="PictureModel"/> will be based on the original <see cref="Worksheet"/>/></param> /// <returns>The <see cref="PictureModel"/> that represents the chart</returns> public PictureModel 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("PictureModel - 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 var drawing = new DocumentFormat.OpenXml.Spreadsheet.Drawing() { Id = cloneToWorksheet.WorksheetPart.GetIdOfPart(cloneToWorksheet.WorksheetPart.DrawingsPart) }; cloneToWorksheet.Append(drawing); } // Take copy elements ImagePart imagePart2 = cloneToWorksheet.WorksheetPart.DrawingsPart.AddImagePart(this.imagePart.ContentType); imagePart2.FeedData(this.imagePart.GetStream()); // Clone the anchor for the template image to get a new image anchor var 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 BlipFill in the Anchor 2 (TwoCellAnchor -> GraphicFrame -> Graphic -> GraphicData -> Picture -> BlipFill) DrawingSpreadsheet.BlipFill blipFill = anchor2.Descendants <DrawingSpreadsheet.BlipFill>().FirstOrDefault(); blipFill.Blip.Embed = cloneToWorksheet.WorksheetPart.DrawingsPart.GetIdOfPart(imagePart2); // Wrap and return as a model PictureModel chartModel = new PictureModel(imagePart2, anchor2) { Worksheet = cloneToWorksheet, ImageId = this.ImageId, IsValid = true, }; return(chartModel); }