/// <summary> /// Creates a deep copy of this <see cref="ShapeModel"/> and associated shape in the worksheet. /// </summary> /// <param name="targetWorksheet">The worksheet into which the clone will be placed. If null, the cloned <see cref="ShapeModel"/> will be based on the original <see cref="Worksheet"/>/></param> /// <returns>The <see cref="ShapeModel"/> that represents the shape</returns> public ShapeModel Clone(Worksheet targetWorksheet) { // If no target worksheet is supplied, clone in sit (ie. on the current worksheet) Worksheet cloneToWorksheet = targetWorksheet == null ? this.Worksheet : targetWorksheet; if (cloneToWorksheet.WorksheetPart.DrawingsPart == null) { var drawingsPart = cloneToWorksheet.WorksheetPart.AddNewPart <OpenXmlPackaging.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); } // Clone the anchor for the template chart to get a new anchor + shape DrawingSpreadsheet.TwoCellAnchor clonedAnchor = (DrawingSpreadsheet.TwoCellAnchor) this.Anchor.CloneNode(true); DrawingSpreadsheet.Shape clonedShape = clonedAnchor.Descendants <DrawingSpreadsheet.Shape>().FirstOrDefault(); // Insert the cloned anchor. cloneToWorksheet.WorksheetPart.DrawingsPart.WorksheetDrawing.Append(clonedAnchor); // Insert the cloned anchor. return(new ShapeModel(cloneToWorksheet, clonedAnchor)); }
/// <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> /// Gets the Name of a visual graphic element which is hosted in a <see cref="DrawingSpreadsheet.TwoCellAnchor"/> /// </summary> /// <param name="twoCellAnchor">The <see cref="DrawingSpreadsheet.TwoCellAnchor"/></param> /// <returns>The name of the hosted element, or null if not found.</returns> private static string GetHostedPartName(DrawingSpreadsheet.TwoCellAnchor twoCellAnchor) { // This horrendous block of code is there to find the id of an element in a GraphicFrame, // which hosts a GraphicElement, such as a ChartPart or a shate - There must be a simpler way...! string name = null; var graphicFrame = twoCellAnchor.Descendants <DrawingSpreadsheet.GraphicFrame>().FirstOrDefault(); if (graphicFrame != null && graphicFrame.NonVisualGraphicFrameProperties != null && graphicFrame.NonVisualGraphicFrameProperties.NonVisualDrawingProperties != null && graphicFrame.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name.HasValue) { name = graphicFrame.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name.Value; } return(name); }
/// <summary> /// Initializes a new instance of the <see cref="PictureModel"/> class. /// </summary> /// <param name="imagePart">The <see cref="ImagePart"/> on which the model is based</param> /// <param name="anchor">The <see cref="DrawingSpreadsheet.TwoCellAnchor"/> which hosts the image</param> private PictureModel(ImagePart imagePart, DrawingSpreadsheet.TwoCellAnchor anchor) : base(anchor) { this.imagePart = imagePart; // Grab the picture and store the height and width DrawingSpreadsheet.Picture picture = anchor.Descendants <DrawingSpreadsheet.Picture>().FirstOrDefault(); // Shape properties and extents.... Drawing.Extents extents = picture.Descendants <Drawing.Extents>().FirstOrDefault(); if (extents != null) { if (extents.Cx.HasValue) { this.WidthInEmus = extents.Cx.Value; } if (extents.Cy.HasValue) { this.HeightInEmus = extents.Cy.Value; } } }
/// <summary> /// Initializes a new instance of the <see cref="ShapeModel" /> class.<br/> /// Private ctor. Prevents public construction. /// </summary> /// <param name="ws">The <see cref="Worksheet"/></param> /// <param name="anchor">A <see cref="DrawingSpreadsheet.TwoCellAnchor"/></param> private ShapeModel(Worksheet ws, DrawingSpreadsheet.TwoCellAnchor anchor) : base(anchor) { if (ws == null) { throw new ArgumentNullException("ws"); } if (anchor == null) { throw new ArgumentNullException("anchor"); } this.Worksheet = ws; this.drawingsPart = ws.WorksheetPart.DrawingsPart; this.Shape = anchor.Descendants <DrawingSpreadsheet.Shape>().FirstOrDefault(); // Shape properties and extents.... if (this.Shape != null) { DocumentFormat.OpenXml.Drawing.Extents extents = this.Shape.Descendants <DocumentFormat.OpenXml.Drawing.Extents>().FirstOrDefault(); if (extents != null) { if (extents.Cx.HasValue) { this.WidthInEmus = extents.Cx.Value; } if (extents.Cy.HasValue) { this.HeightInEmus = extents.Cy.Value; } } } // Get the name of the Shape this.Name = GetShapeName(this.Shape); this.IsValid = true; }
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); }