Powershell:将数据从一个Excel工作簿复制到另一个工作簿

时间:2015-09-16 02:17:54

标签: c# powershell scripting powershell-v4.0

Hello stackoverflow朋友们好了!

我正在制作一个Powershell脚本,我正在尝试执行以下操作:

  • 选择Excel xlsx文件,其中包含仅包含标题的现有工作表
  • 选择文本文件
  • 从文本文件创建临时CSV文件并添加标题以匹配Excel文件
  • 将CSV文件中的信息复制到Excel文件中的工作表
  • 保存/退出

我已经完成了使用Excel对象的Range方面所需的一切。尝试从实例化为COM对象的CSV文件中复制数据时,然后激活xlsx文件,我收到错误说明

  

使用“1”参数调用“粘贴”的异常:“粘贴方法”   工作表类失败“在行:1个字符:1

     
    
        
  • $脚本:ExcelWorkSheet.Paste($ tempRange)
  •     
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~          
          
    • CategoryInfo:NotSpecified:(:) [],MethodInvocationException
    •     
    • FullyQualifiedErrorId:ComMethodTargetInvocation
    •     
  •     
  

以下是我的代码。任何帮助都会感激不尽,因为我不知所措:

BEGIN
{
    Function Set-ScriptVars()
    {
        Add-Type -AssemblyName System.Windows.Forms
    }

    Function Select-File($FileType)
    {
        ## Select file via selection dialog

        do {
            if($FileType -eq "xlsx")
            {
                Write-Host "`nPlease select the Excel file to import in the dialog"
            }
            elseif($FileType -eq "txt")
            {
                Write-Host "`nPlease select the Prescan or Postscan text file to import in the dialog"
            }

            Start-Sleep -Seconds 1
            $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{InitialDirectory = [Environment]::GetFolderPath('Desktop')}

            [void]$FileBrowser.ShowDialog()

            Write-Host "`nFile selected: " -NoNewline  
            Write-Host $FileBrowser.FileNames -ForegroundColor Yellow 

            $FileName = $FileBrowser.FileName
            if ($FileName.EndsWith(".$FileType"))
            {
                $selectionValid = $True
            }
            else
            {
                Write-Host "The file selected is not a .$FileType file."
                Write-Host "Restarting file selection loop."
                $selectionValid = $False
            }
        } until ($selectionValid -eq $True)

        if($FileType -eq "txt")
        {
            $Script:TextFile = $FileName
            $Script:TextParentPath = (Get-Item $FileName).Directory.FullName
        }
        elseif($FileType -eq "xlsx")
        {
            $Script:ExcelFile = $FileName
            $Script:ExcelParentPath = (Get-Item $FileName).Directory.FullName
        }
    }

    Function Open-Excel($Sheet)
    {
        $ActiveSheet = $Sheet

        $ExcelPath = $Script:ExcelFile
        $Script:Excel = New-Object -ComObject Excel.Application
        $Script:Excel.Visible = $True
        $Script:Excel.UserControl = $False
        $Script:Excel.Interactive = $False
        $Script:Excel.DisplayAlerts = $False

        $Script:ExcelWorkBook = $Script:Excel.Workbooks.Open($ExcelPath)
        $Script:ExcelWorkSheet = $Script:Excel.WorkSheets.item($ActiveSheet)
        $Script:ExcelWorkSheet.Activate()
    }

    Function Get-TextContent()
    {
        $Script:TextContent = Get-Content $Script:TextFile 
    }

    Function Copy-TextData()
    {
        # create a random file name

        $randomInt = @(0001..9999) | Get-Random
        $tempCSV = Import-CSV $Script:TextFile -Header "Server","Role","Type","Object","Path" 
        $tempCSV | Export-CSV -Path $ENV:USERPROFILE\Desktop\tempCSV_$randomInt.csv -NoTypeInformation
        $tempCSVPath = "$ENV:USERPROFILE\Desktop\tempCSV_$randomInt.csv"
        $tempCSVName = "tempCSV_$randomInt"

        # create a temporary file to copy from

        $TempExcel = New-Object -ComObject Excel.Application
        $TempExcel.Visible = $True
        $TempWorkBook = $TempExcel.WorkBooks.Open($tempCSVPath)
        $TempWorkSheet = $TempWorkBook.WorkSheets.Item($tempCSVName)

        $tempRange = $TempWorkSheet.Range("A2:E2").UsedRange
        $tempRange.Copy() | Out-Null

        $Script:ExcelWorkSheet.Activate()
        $Script:ExcelWorkSheet.Range("A2:E2").EntireColumn
        $Script:ExcelWorkSheet.Paste($tempRange)
        $Script:ExcelWorkBook.Save()
        $Script:Excel.Quit()

        [gc]::Collect()
        [gc]::WaitForPendingFinalizers()

        Write-Host "Break"
    }
}

PROCESS
{
    Set-ScriptVars
    Select-File -FileType "xlsx"
    Select-File -FileType "txt"
    if($Script:TextFile -match "Prescan")
    {
        Open-Excel -Sheet "Prescan"
    }
    elseif($Script:TextFile -match "Postscan")
    {
        Open-Excel -Sheet "Postscan"
    }

    Get-TextContent
    Copy-TextData
}

END
{

}

在这种情况下,不能使用VB宏。 如果通过利用.NET程序集或以@''@格式放入C#代码更容易完成这样的任务,我全都听见了!

1 个答案:

答案 0 :(得分:0)

花了很多时间后,我终于找到了一个可行的解决方案。 对于将来可能通过搜索引擎遇到此问题的任何人,我希望下面的代码有帮助!

Tools -> Deployment -> Browse Remote Host