/// <summary> /// Processes the paragraph part. /// </summary> /// <param name="wkb">The WKB.</param> /// <param name="part">The part.</param> /// <param name="placeholder">The placeholder.</param> /// <param name="mapping">The mapping.</param> /// <param name="worksheetPart">The worksheet part.</param> /// <param name="reportWSPart">The report ws part.</param> /// <returns></returns> private static DrawingSpreadsheet.Shape ProcessParagraphPart(OpenXmlSpreadsheet.Workbook wkb, ExportPart part, MappingPlaceholder placeholder, ParagraphMapping mapping, WorksheetPart worksheetPart, WorksheetPart reportWSPart) { string SheetName = ""; uint RowStart = 0; uint RowEnd = 0; uint ColStart = 0; uint ColEnd = 0; // if no placeholder is specified then return now if (placeholder == null) { return(null); } DrawingSpreadsheet.Shape matchShape = worksheetPart.GetShapeByName(placeholder.Id); if (matchShape == null) { return(null); } // save the location of this shape, // this information will be used to position the incoming chart Extents extents = matchShape.ShapeProperties.Transform2D.Extents; Offset offset = matchShape.ShapeProperties.Transform2D.Offset; OpenXmlSpreadsheet.DefinedName rtfXmlDefinedName = wkb.GetDefinedNameByName(string.Format("{0}_{1}", part.DataSheetName, mapping.SourceFieldName)); wkb.BreakDownDefinedName(rtfXmlDefinedName, ref SheetName, ref RowStart, ref RowEnd, ref ColStart, ref ColEnd); WorksheetPart wksp = wkb.GetWorksheetPartByName(SheetName); OpenXmlSpreadsheet.SheetData sheetData = wksp.Worksheet.GetFirstChild <OpenXmlSpreadsheet.SheetData>(); OpenXmlSpreadsheet.Cell rtfXmlCell = sheetData.GetCell(ColStart, RowStart + 1); // Use the cell on the hidden data sheet as source for the XAML reader Section RTFSection = XamlSectionDocumentReader(rtfXmlCell.CellValue.InnerText); // The paragraph in the cell.inlinestring have a very different class structure to the paragraphs in the shape.textbody // So, the paragraph will need to go through a converter to do this. DrawingSpreadsheet.Shape targetShape = ConvertParagraph(worksheetPart, RTFSection, matchShape); // positon the new graphic frame after the shape its going to replace matchShape.Parent.InsertAfter <OpenXmlElement>(targetShape, matchShape); matchShape.Remove(); return(targetShape); }
/// <summary> /// Copies a chart from the source worksheet part to the report worksheet part /// The placeholder id in the drawing mapping information is used to /// </summary> /// <param name="part">The part.</param> /// <param name="placeholder">The placeholder.</param> /// <param name="mapping">The mapping.</param> /// <param name="worksheetPart">The worksheet part.</param> /// <param name="reportWSPart">The report ws part.</param> /// <returns></returns> private static ChartPart ProcessDrawingPart(ExportPart part, MappingPlaceholder placeholder, DrawingMapping mapping, WorksheetPart worksheetPart, WorksheetPart reportWSPart) { // if no placeholder is specified then return now if (placeholder == null) { return(null); } DrawingSpreadsheet.Shape matchShape = reportWSPart.GetShapeByName(placeholder.Id); if (matchShape == null) { return(null); } // save the location of this shape, // this information will be used to position the incoming chart Extents extents = matchShape.ShapeProperties.Transform2D.Extents; Offset offset = matchShape.ShapeProperties.Transform2D.Offset; // get the source chart.... if a source drawing id is specified use it // otherwise get the 1st one ChartPart sourceChartPart = null; if (string.IsNullOrEmpty(mapping.SourceDrawingId)) { // the 1st chart if there is one sourceChartPart = worksheetPart.DrawingsPart.GetPartsOfType <ChartPart>().FirstOrDefault(); } else { DrawingSpreadsheet.GraphicFrame sourceFrame = null; // we need to pull out the graphic frame that matches the supplied name foreach (var gf in worksheetPart.DrawingsPart.WorksheetDrawing.Descendants <DrawingSpreadsheet.GraphicFrame>()) { // need to check it has the various properties if (gf.NonVisualGraphicFrameProperties != null && gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties != null && gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name.HasValue) { // and then try and match if (mapping.SourceDrawingId.CompareTo(gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name.Value) == 0) { sourceFrame = gf; break; } } } // we have the graphics frame with data, so no pull out the chart part if (sourceFrame != null && sourceFrame.Graphic != null && sourceFrame.Graphic.GraphicData != null) { var sourceChartRef = sourceFrame.Graphic.GraphicData.Descendants <DrawingCharts.ChartReference>().FirstOrDefault(); if (sourceChartRef != null && sourceChartRef.Id.HasValue) { sourceChartPart = (ChartPart)worksheetPart.DrawingsPart.GetPartById(sourceChartRef.Id.Value); } } } // create a new one var targetChartPart = reportWSPart.DrawingsPart.AddNewPart <ChartPart>(); // and feed data from old to new targetChartPart.FeedData(sourceChartPart.GetStream()); // chart in now // just need the drawing to host it // get the graphic frame from the source anchor var sourceAnchor = worksheetPart.DrawingsPart.WorksheetDrawing.GetFirstChild <DrawingSpreadsheet.TwoCellAnchor>(); var sourceGraphicFrame = sourceAnchor.Descendants <DrawingSpreadsheet.GraphicFrame>().FirstOrDefault(); // add it to the target anchor (ie. the one with the shape removed) var targetGraphicFrame = sourceGraphicFrame.CloneNode(true); // positon the new graphic frame after the shape its going to replace matchShape.Parent.InsertAfter <OpenXmlElement>(targetGraphicFrame, matchShape); // and remove the shape, not needed anymore matchShape.Remove(); // update the extents and offsets that were saved above var transform = targetGraphicFrame.Descendants <DrawingSpreadsheet.Transform>().FirstOrDefault(); if (transform != null) { transform.Extents.Cx = extents.Cx; transform.Extents.Cy = extents.Cy; transform.Offset.X = offset.X; transform.Offset.Y = offset.Y; } // ensure that the id of the chart reference in the cloned graphic frame matches that of the new cloned chart // if this isnt done then no chart will appeat var chartReference = targetGraphicFrame.Descendants <DocumentFormat.OpenXml.Drawing.Charts.ChartReference>().FirstOrDefault(); chartReference.Id = reportWSPart.DrawingsPart.GetIdOfPart(targetChartPart); return(targetChartPart); }