예제 #1
0
        internal ExportTripleSet(IDataPart dataPart, ExportPart exportPart, Template template)
        {
            if (dataPart == null)
            {
                throw new ArgumentNullException("dataPart");
            }
            if (exportPart == null)
            {
                throw new ArgumentNullException("exportPart");
            }
            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            this.DataPart = dataPart;
            this.Part     = exportPart;
            this.Template = template;
        }
        /// <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);
        }