From 91da711635e1c498b02228b2b0bf6e4ca6a9e683 Mon Sep 17 00:00:00 2001 From: Josh Hendricks Date: Tue, 1 Feb 2022 21:37:55 -0800 Subject: [PATCH] docs: add Add-ExcelImage example --- Examples/AddPicture/Add-ExcelImage.ps1 | 115 +++++++++++++++++++++++++ Examples/AddPicture/AddPicture.ps1 | 34 ++++++++ Examples/AddPicture/Octocat.jpg | Bin 0 -> 6272 bytes Examples/AddPicture/README.md | 19 ++++ 4 files changed, 168 insertions(+) create mode 100644 Examples/AddPicture/Add-ExcelImage.ps1 create mode 100644 Examples/AddPicture/AddPicture.ps1 create mode 100644 Examples/AddPicture/Octocat.jpg create mode 100644 Examples/AddPicture/README.md diff --git a/Examples/AddPicture/Add-ExcelImage.ps1 b/Examples/AddPicture/Add-ExcelImage.ps1 new file mode 100644 index 0000000..c3e6d17 --- /dev/null +++ b/Examples/AddPicture/Add-ExcelImage.ps1 @@ -0,0 +1,115 @@ +function Add-ExcelImage { + <# + .SYNOPSIS + Adds an image to a worksheet in an Excel package. + .DESCRIPTION + Adds an image to a worksheet in an Excel package using the + `WorkSheet.Drawings.AddPicture(name, image)` method, and places the + image at the location specified by the Row and Column parameters. + + Additional position adjustment can be made by providing RowOffset and + ColumnOffset values in pixels. + .EXAMPLE + $image = [System.Drawing.Image]::FromFile($octocat) + $xlpkg = $data | Export-Excel -Path $path -PassThru + $xlpkg.Sheet1 | Add-ExcelImage -Image $image -Row 4 -Column 6 -ResizeCell + + Where $octocat is a path to an image file, and $data is a collection of + data to be exported, and $path is the output path for the Excel document, + Add-Excel places the image at row 4 and column 6, resizing the column + and row as needed to fit the image. + .INPUTS + [OfficeOpenXml.ExcelWorksheet] + .OUTPUTS + None + #> + [CmdletBinding()] + param( + # Specifies the worksheet to add the image to. + [Parameter(Mandatory, ValueFromPipeline)] + [OfficeOpenXml.ExcelWorksheet] + $WorkSheet, + + # Specifies the Image to be added to the worksheet. + [Parameter(Mandatory)] + [System.Drawing.Image] + $Image, + + # Specifies the row where the image will be placed. Rows are counted from 1. + [Parameter(Mandatory)] + [ValidateRange(1, [int]::MaxValue)] + [int] + $Row, + + # Specifies the column where the image will be placed. Columns are counted from 1. + [Parameter(Mandatory)] + [ValidateRange(1, [int]::MaxValue)] + [int] + $Column, + + # Specifies the name to associate with the image. Names must be unique per sheet. + # Omit the name and a GUID will be used instead. + [Parameter()] + [string] + $Name, + + # Specifies the number of pixels to offset the image on the Y-axis. A + # positive number moves the image down by the specified number of pixels + # from the top border of the cell. + [Parameter()] + [int] + $RowOffset = 1, + + # Specifies the number of pixels to offset the image on the X-axis. A + # positive number moves the image to the right by the specified number + # of pixels from the left border of the cell. + [Parameter()] + [int] + $ColumnOffset = 1, + + # Increase the column width and row height to fit the image if the current + # dimensions are smaller than the image provided. + [Parameter()] + [switch] + $ResizeCell + ) + + begin { + <# + These ratios work on my machine but it feels fragile. Need to better + understand how row and column sizing works in Excel and what the + width and height units represent. + #> + $widthFactor = 1 / 7 + $heightFactor = 3 / 4 + } + + process { + if ([string]::IsNullOrWhiteSpace($Name)) { + $Name = (New-Guid).ToString() + } + if ($null -ne $WorkSheet.Drawings[$Name]) { + Write-Error "A picture with the name `"$Name`" already exists in worksheet $($WorkSheet.Name)." + return + } + + <# + The row and column offsets of 1 ensures that the image lands just + inside the gray cell borders at the top left. + #> + $picture = $WorkSheet.Drawings.AddPicture($Name, $Image) + $picture.SetPosition($Row - 1, $RowOffset, $Column - 1, $ColumnOffset) + + if ($ResizeCell) { + <# + Adding 1 to the image height and width ensures that when the + row and column are resized, the bottom right of the image lands + just inside the gray cell borders at the bottom right. + #> + $width = $widthFactor * ($Image.Width + 1) + $height = $heightFactor * ($Image.Height + 1) + $WorkSheet.Column($Column).Width = [Math]::Max($width, $WorkSheet.Column($Column).Width) + $WorkSheet.Row($Row).Height = [Math]::Max($height, $WorkSheet.Row($Row).Height) + } + } +} \ No newline at end of file diff --git a/Examples/AddPicture/AddPicture.ps1 b/Examples/AddPicture/AddPicture.ps1 new file mode 100644 index 0000000..5230641 --- /dev/null +++ b/Examples/AddPicture/AddPicture.ps1 @@ -0,0 +1,34 @@ +Add-Type -AssemblyName System.Drawing + +. $PSScriptRoot\Add-ExcelImage.ps1 + +$data = ConvertFrom-Csv @" +Region,State,Units,Price +West,Texas,927,923.71 +North,Tennessee,466,770.67 +East,Florida,520,458.68 +East,Maine,828,661.24 +West,Virginia,465,053.58 +North,Missouri,436,235.67 +South,Kansas,214,992.47 +North,North Dakota,789,640.72 +South,Delaware,712,508.55 +"@ + +$path = "$PSScriptRoot/Add-Picture-test.xlsx" +Remove-Item $path -ErrorAction SilentlyContinue + + +try { + $octocat = "$PSScriptRoot/Octocat.jpg" + $image = [System.Drawing.Image]::FromFile($octocat) + $xlpkg = $data | Export-Excel -Path $path -PassThru + $xlpkg.Sheet1 | Add-ExcelImage -Image $image -Row 4 -Column 6 -ResizeCell +} finally { + $image.Dispose() + if ($xlpkg) { + Close-ExcelPackage -ExcelPackage $xlpkg -Show + } +} + + diff --git a/Examples/AddPicture/Octocat.jpg b/Examples/AddPicture/Octocat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a48c3499c8f316eae14f1722c2fa2004d06e8b69 GIT binary patch literal 6272 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 ix?hH#H(+CXxz*IWU;X2Ky8Eo literal 0 HcmV?d00001 diff --git a/Examples/AddPicture/README.md b/Examples/AddPicture/README.md new file mode 100644 index 0000000..ff36c37 --- /dev/null +++ b/Examples/AddPicture/README.md @@ -0,0 +1,19 @@ +# Add-ExcelImage Example + +Adding pictures to an Excel worksheet is possible by calling the `AddPicture(name, image)` +method on the `Drawings` property of an `ExcelWorksheet` object. + +The `Add-ExcelImage` example here demonstrates how to add a picture at a given +cell location, and optionally resize the row and column to fit the image. + +Care has been taken in this example to get the image placement to be just inside +the cell border, and if the `-ResizeCell` switch is present, the height and width +of the row and column will be increased, if needed, so that the bottom right of +the image also lands just inside the cell border. + +The Excel row and column sizes are measured in "point" units rather than pixels, +and at the moment a fixed multiplication factor is used to convert the size of +the image in pixels, to the corresponding height and width values in Excel. + +You may find that images with a different DPI, or different resolution, DPI, or +text scaling options result in imperfect row and column sizing. \ No newline at end of file