예제 #1
0
        /// <summary>
        /// Clones this cell cursor, but with a specified worksheet.
        /// </summary>
        /// <param name="worksheet">The worksheet.</param>
        /// <returns>
        /// A clone of this cell cursor, except with the worksheet swapped-out for the specified worksheet.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="worksheet"/> is null.</exception>
        public CellCursor CloneWithWorksheet(
            Worksheet worksheet)
        {
            if (worksheet == null)
            {
                throw new ArgumentNullException(nameof(worksheet));
            }

            var result = new CellCursor(worksheet)
            {
                RowNumber            = this.RowNumber,
                ColumnNumber         = this.ColumnNumber,
                StartRowNumber       = this.StartRowNumber,
                StartColumnNumber    = this.StartColumnNumber,
                MaxRowNumber         = this.MaxRowNumber,
                MaxColumnNumber      = this.MaxColumnNumber,
                markerNameToCellsMap = this.markerNameToCellsMap.ToDictionary(
                    _ => _.Key,
                    _ => _.Value.Select(cell => worksheet.Cells[cell.Row, cell.Column]).ToList()),
            };

            return(result);
        }
        public static Range InsertImages(
            this Cell cell,
            IReadOnlyCollection <string> imageUrls,
            int imageWidthScale  = 100,
            int imageHeightScale = 100,
            ImagesRelativeOrientation relativeOrientation = ImagesRelativeOrientation.Horizontal,
            ImagesCellSizeChanges cellSizeChanges         = ImagesCellSizeChanges.ExpandRowAndColumnToFitImages,
            int rowHeightInPixels   = Constants.DefaultRowHeightInPixels,
            int columnWidthInPixels = Constants.DefaultColumnWidthInPixels,
            ImagesAutoLayoutProcedures autoLayoutProcedures = ImagesAutoLayoutProcedures.AutoSpaceAndAutoAlign)
        {
            if (cell == null)
            {
                throw new ArgumentNullException(nameof(cell));
            }

            if (imageUrls == null)
            {
                throw new ArgumentNullException(nameof(imageUrls));
            }

            if (!imageUrls.Any())
            {
                throw new ArgumentException(Invariant($"'{nameof(imageUrls)}' is an empty enumerable"));
            }

            if (imageUrls.Any(string.IsNullOrWhiteSpace))
            {
                throw new ArgumentException(Invariant($"{nameof(imageUrls)} contains an element that is null or white space"));
            }

            if (imageWidthScale < 1)
            {
                throw new ArgumentOutOfRangeException(Invariant($"'{nameof(imageWidthScale)}' < '{1}'"), (Exception)null);
            }

            if (imageWidthScale > 500)
            {
                throw new ArgumentOutOfRangeException(Invariant($"'{nameof(imageWidthScale)}' > '{500}'"), (Exception)null);
            }

            if (imageHeightScale < 1)
            {
                throw new ArgumentOutOfRangeException(Invariant($"'{nameof(imageHeightScale)}' < '{1}'"), (Exception)null);
            }

            if (imageHeightScale > 500)
            {
                throw new ArgumentOutOfRangeException(Invariant($"'{nameof(imageHeightScale)}' > '{500}'"), (Exception)null);
            }

            if (relativeOrientation == ImagesRelativeOrientation.Unknown)
            {
                throw new ArgumentOutOfRangeException(Invariant($"'{nameof(relativeOrientation)}' == '{ImagesRelativeOrientation.Unknown}'"), (Exception)null);
            }

            if (rowHeightInPixels < 1)
            {
                throw new ArgumentOutOfRangeException(Invariant($"'{nameof(rowHeightInPixels)}' < '{1}'"), (Exception)null);
            }

            if (columnWidthInPixels < 1)
            {
                throw new ArgumentOutOfRangeException(Invariant($"'{nameof(columnWidthInPixels)}' < '{1}'"), (Exception)null);
            }

            if (relativeOrientation == ImagesRelativeOrientation.Vertical)
            {
                throw new NotImplementedException(Invariant($"This {nameof(ImagesRelativeOrientation)} is not yet implemented: {nameof(ImagesRelativeOrientation.Vertical)}"));
            }

            var worksheet = cell.Worksheet;

            var pictures = new List <Picture>();

            using (var webClient = new WebClient())
            {
                foreach (var imageUrl in imageUrls)
                {
                    var imageBytes = webClient.DownloadData(imageUrl);
                    using (var imageStream = new MemoryStream(imageBytes))
                    {
                        var pictureIndex = worksheet.Pictures.Add(cell.Row, cell.Column, imageStream);

                        var picture = worksheet.Pictures[pictureIndex];

                        var imageBitmap         = new Bitmap(imageStream);
                        var imageHeightInPixels = imageBitmap.Height;
                        var imageWidthInPixels  = imageBitmap.Width;

                        picture.Height      = imageHeightInPixels;
                        picture.Width       = imageWidthInPixels;
                        picture.HeightScale = imageHeightScale;
                        picture.WidthScale  = imageWidthScale;
                        pictures.Add(picture);
                    }
                }
            }

            var maxImageWidthInPixels   = pictures.Max(_ => _.Width);
            var maxImageHeightInPixels  = pictures.Max(_ => _.Height);
            var totalImageWidthInPixels = pictures.Sum(_ => _.Width);

            int resultEndRow, resultEndColumn;
            var resultStartRow    = resultEndRow = cell.GetRowNumber();
            var resultStartColumn = resultEndColumn = cell.GetColumnNumber();

            // setting the row height or column height could move the pictures so do that before positioning the pictures
            if (cellSizeChanges.HasFlag(ImagesCellSizeChanges.ExpandRowToFitImages))
            {
                var rowHeight = cell.GetHeightInPixels();
                if (maxImageHeightInPixels > rowHeight)
                {
                    cell.GetRange().SetTotalRowHeightInPixels(maxImageHeightInPixels);
                }
            }
            else
            {
                var cursor        = new CellCursor(worksheet, cell.GetRowNumber(), cell.GetColumnNumber());
                var pixelsCovered = 0;

                do
                {
                    if (cellSizeChanges.HasFlag(ImagesCellSizeChanges.ResizeRowsToFixedHeight))
                    {
                        cursor.CellRange.SetPerRowHeightInPixels(rowHeightInPixels);
                    }

                    pixelsCovered += cursor.Cell.GetHeightInPixels(includeMergedCells: false);
                    cursor.MoveDown();
                }while (pixelsCovered < maxImageHeightInPixels);

                resultEndRow = cursor.RowNumber - 1;
            }

            if (cellSizeChanges.HasFlag(ImagesCellSizeChanges.ExpandColumnToFitImages))
            {
                var columnWidth = cell.GetWidthInPixels();

                if (autoLayoutProcedures.HasFlag(ImagesAutoLayoutProcedures.AutoSpace))
                {
                    if (totalImageWidthInPixels > columnWidth)
                    {
                        cell.GetRange().SetTotalColumnWidthInPixels(totalImageWidthInPixels);
                    }
                }
                else
                {
                    if (maxImageWidthInPixels > columnWidth)
                    {
                        cell.GetRange().SetTotalColumnWidthInPixels(maxImageWidthInPixels);
                    }
                }
            }
            else
            {
                var cursor        = new CellCursor(worksheet, cell.GetRowNumber(), cell.GetColumnNumber());
                var pixelsCovered = 0;

                do
                {
                    if (cellSizeChanges.HasFlag(ImagesCellSizeChanges.ResizeColumnsToFixedWidth))
                    {
                        cursor.CellRange.SetPerColumnWidthInPixels(columnWidthInPixels);
                    }

                    pixelsCovered += cursor.Cell.GetWidthInPixels(includeMergedCells: false);
                    cursor.MoveRight();
                }while (pixelsCovered < maxImageWidthInPixels);

                resultEndColumn = cursor.ColumnNumber - 1;
            }

            if (autoLayoutProcedures.HasFlag(ImagesAutoLayoutProcedures.AutoSpace))
            {
                var horizontalMarginInPixels   = (cell.GetWidthInPixels() - totalImageWidthInPixels) / (pictures.Count + 1);
                var horizontalPositionInPixels = pictures[0].X;

                foreach (var picture in pictures)
                {
                    if (horizontalMarginInPixels >= 0)
                    {
                        picture.X = horizontalPositionInPixels + horizontalMarginInPixels;
                        horizontalPositionInPixels = picture.X + picture.Width;
                    }
                }
            }

            if (autoLayoutProcedures.HasFlag(ImagesAutoLayoutProcedures.AutoAlign))
            {
                foreach (var picture in pictures)
                {
                    picture.Y += (maxImageHeightInPixels - picture.Height) / 2;
                }
            }

            var result = worksheet.GetRange(resultStartRow, resultEndRow, resultStartColumn, resultEndColumn);

            return(result);
        }