mirror of
https://github.com/dfinke/ImportExcel.git
synced 2025-12-06 00:23:20 +00:00
95 lines
5.7 KiB
PowerShell
95 lines
5.7 KiB
PowerShell
function Copy-ExcelWorkSheet {
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true,ValueFromPipeline=$true)]
|
|
[Alias('SourceWorkbook')]
|
|
$SourceObject,
|
|
$SourceWorkSheet = 1 ,
|
|
[Parameter(Mandatory = $true)]
|
|
$DestinationWorkbook,
|
|
$DestinationWorksheet,
|
|
[Switch]$Show
|
|
)
|
|
begin {
|
|
#For the case where we are piped multiple sheets, we want to open the destination in the begin and close it in the end.
|
|
if ($DestinationWorkbook -is [OfficeOpenXml.ExcelPackage] ) {
|
|
if ($Show) {$package2 = $DestinationWorkbook}
|
|
$DestinationWorkbook = $DestinationWorkbook.Workbook
|
|
}
|
|
elseif ($DestinationWorkbook -is [string] -and ($DestinationWorkbook -ne $SourceObject)) {
|
|
$package2 = Open-ExcelPackage -Create -Path $DestinationWorkbook
|
|
$DestinationWorkbook = $package2.Workbook
|
|
}
|
|
}
|
|
process {
|
|
#Special case - given the same path for source and destination worksheet
|
|
if ($SourceObject -is [System.String] -and $SourceObject -eq $DestinationWorkbook) {
|
|
if (-not $DestinationWorksheet) {Write-Warning -Message "You must specify a destination worksheet name if copying within the same workbook."; return}
|
|
else {
|
|
Write-Verbose -Message "Copying "
|
|
$excel = Open-ExcelPackage -Path $SourceObject
|
|
if (-not $excel.Workbook.Worksheets[$Sourceworksheet]) {
|
|
Write-Warning -Message "Could not find Worksheet $sourceWorksheet in $SourceObject"
|
|
Close-ExcelPackage -ExcelPackage $excel -NoSave
|
|
return
|
|
}
|
|
elseif ($excel.Workbook.Worksheets[$Sourceworksheet].name -eq $DestinationWorksheet) {
|
|
Write-Warning -Message "The destination worksheet name is the same as the source. "
|
|
Close-ExcelPackage -ExcelPackage $excel -NoSave
|
|
return
|
|
}
|
|
else {
|
|
$null = Add-WorkSheet -ExcelPackage $excel -WorkSheetname $DestinationWorksheet -CopySource ($excel.Workbook.Worksheets[$SourceWorkSheet])
|
|
Close-ExcelPackage -ExcelPackage $excel -Show:$Show
|
|
return
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if ($SourceObject -is [OfficeOpenXml.ExcelWorksheet]) {$sourceWs = $SourceObject}
|
|
elseif ($SourceObject -is [OfficeOpenXml.ExcelWorkbook]) {$sourceWs = $SourceObject.Worksheets[$SourceWorkSheet]}
|
|
elseif ($SourceObject -is [OfficeOpenXml.ExcelPackage] ) {$sourceWs = $SourceObject.Workbook.Worksheets[$SourceWorkSheet]}
|
|
else {
|
|
$SourceObject = (Resolve-Path $SourceObject).ProviderPath
|
|
try {
|
|
Write-Verbose "Opening worksheet '$Worksheetname' in Excel workbook '$SourceObject'."
|
|
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $SourceObject, 'Open', 'Read' , 'ReadWrite'
|
|
$package1 = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
|
|
$sourceWs = $Package1.Workbook.Worksheets[$SourceWorkSheet]
|
|
}
|
|
catch {Write-Warning -Message "Could not open $SourceObject - the error was '$($_.exception.message)' " ; return}
|
|
}
|
|
if (-not $sourceWs) {Write-Warning -Message "Could not find worksheet '$Sourceworksheet' in the source workbook." ; return}
|
|
else {
|
|
try {
|
|
if ($DestinationWorkbook -isnot [OfficeOpenXml.ExcelWorkbook]) {
|
|
Write-Warning "Not a valid workbook" ; return
|
|
}
|
|
#check if we have a destination sheet name and set one if not. Because we might loop round check $psBoundParameters, not the variable.
|
|
if (-not $PSBoundParameters['DestinationWorksheet']) {
|
|
#if we are piped files, use the file name without the extension as the destination sheet name, Otherwise use the source sheet name
|
|
if ($_ -is [System.IO.FileInfo]) {$DestinationWorksheet = $_.name -replace '\.xlsx$', '' }
|
|
else { $DestinationWorksheet = $sourceWs.Name}
|
|
}
|
|
if ($DestinationWorkbook.Worksheets[$DestinationWorksheet]) {
|
|
Write-Verbose "Destination workbook already has a sheet named '$DestinationWorksheet', deleting it."
|
|
$DestinationWorkbook.Worksheets.Delete($DestinationWorksheet)
|
|
}
|
|
Write-Verbose "Copying '$($sourcews.name)' from $($SourceObject) to '$($DestinationWorksheet)' in $($PSBoundParameters['DestinationWorkbook'])"
|
|
$null = Add-WorkSheet -ExcelWorkbook $DestinationWorkbook -WorkSheetname $DestinationWorksheet -CopySource $sourceWs
|
|
#Leave the destination open but close the source - if we're copying more than one sheet we'll re-open it and live with the inefficiency
|
|
if ($stream) {$stream.Close() }
|
|
if ($package1) {Close-ExcelPackage -ExcelPackage $package1 -NoSave }
|
|
}
|
|
catch {Write-Warning -Message "Could not write to sheet '$DestinationWorksheet' in the destination workbook. Error was '$($_.exception.message)'" ; return}
|
|
}
|
|
}
|
|
}
|
|
end {
|
|
#OK Now we can close the destination package
|
|
if ($package2) {Close-ExcelPackage -ExcelPackage $package2 -Show:$Show }
|
|
if ($Show -and -not $package2) {
|
|
Write-Warning -Message "-Show only works if the Destination workbook is given as a file path or an ExcelPackage object."
|
|
}
|
|
}
|
|
} |