需要帮助通过PowerShell模块“PSExcel”将工作表添加到现有的xlsx

时间:2016-09-15 05:21:11

标签: sql-server excel powershell

我正在开发一个项目,用MSSQL数据库中的数据创建一些Excel报告,并需要一些最终结果的帮助。

免责声明 - 我对PowerShell和MSSQL并不满意。

到目前为止,在互联网的帮助下,我设法创建了一个提升自身的.ps1文件,导入一个名为PSExcel(https://github.com/RamblingCookieMonster/PSExcel)的PS模块,导入SQLPS模块并运行三个单独的查询导出到三个单独的.xlsx文件。

我最后几部分的脚本是:

# Import PSExcel module
Import-Module C:\scripts-and-reports\Modules\PSExcel

# Import SQLPS module
Import-Module sqlps

# Import PSExcel module
Import-Module C:\scripts-and-reports\Modules\PSExcel

# Import SQLPS module
Import-Module sqlps

# Create individuals
invoke-sqlcmd -inputfile "C:\scripts-and-reports\individuals.sql" -serverinstance "SERVER\INSTANCE" -database "DATABASE" | 
Export-XLSX -WorksheetName "Individuals" -Path "C:\scripts-and-reports\Individuals.xlsx" -Table -Force

# Create joint parties
invoke-sqlcmd -inputfile "C:\scripts-and-reports\joint-parties.sql" -serverinstance "SERVER\INSTANCE" -database "DATABASE" | 
Export-XLSX -WorksheetName "Joint Parties" -Path "C:\scripts-and-reports\Joint Parties.xlsx" -Table -Force

# Create organisations
invoke-sqlcmd -inputfile "C:\scripts-and-reports\organisations.sql" -serverinstance "SERVER\INSTANCE" -database "DATABASE" | 
Export-XLSX -WorksheetName "Organisations" -Path "C:\scripts-and-reports\Organisations.xlsx" -Table -Force

我试图将最后两个查询导出组合成第一个查询的导出作为额外的工作表,因此我只有一个Excel工作簿交给我的老板,但我认为我必须正确接近它。

当我在../Export-XLSX.ps1第94行上阅读示例并尝试在我的方案中通过更改文件名以相互匹配来实现它时,最后一个查询将替换第一个查询中的第一个输出.xlsx文件。这必须是因为-Force。将其更改为-Append将无济于事,因为它表示该文件已存在。

任何人都可以帮助我,首先告诉我哪里出错,然后指出我正确的方向(这可能会在演练中结束)。

请,谢谢!

--- **更新** ---

使用@ gms0ulman对Export-XLSX.ps1的修复,看起来它会起作用,因为我用不同的SQL查询测试了它我需要的东西,并且它添加了工作表。 我用于测试的查询是

SELECT DISTINCT
case mt.[Status] 
    when 0 then 'In Progress' 
    When 1 then 'On Hold' 
    when 2 then 'Completed' 
    when 3 then 'Not Proceeding' 
else 'Unknown' end as MatterStatus,
mt.LastUpdatedOn as LastModified
from matter mt 
where mt.LastUpdatedOn >= '2016-07-01'  
    AND (mt.[status] = 0 or mt.[status] = 1)

虽然这个(以及我的PS脚本中的其他两次迭代)有效,但我的实际查询却没有。查询本身也可以工作,第一次导出也是如此,但是当PS -Appendinvoke-sqlcmd and invoke-sqlcmd -inputfile "query2.sql" -serverinstance "" -database "" | Export-XLSX -WorksheetName "Joint Parties" -Path "C:\scripts-and-reports\Matter Details.xlsx" -Table -Append一起使用时,两个附加的工作表会出错:

  

使用“1”参数调用“SaveAs”的异常:“保存文件C:\ scripts-and-reports \ Matter Details.xlsx时出错”

     

在C:\ scripts-and-reports \ Modules \ PSExcel \ Export-XLSX.ps1:496 char:13

     

$ Excel.SaveAs($路径)

     

~~~~~~~~~~~~~~~~~~~~

     

CategoryInfo:NotSpecified:(:) [],MethodInvocationException

     

FullyQualifiedErrorId:InvalidOperationException

1 个答案:

答案 0 :(得分:1)

问题在于您正在使用的模块。 -Append应该有效。在Export-XLSX.ps1文件中,查看 351 371 行。

当您提供现有路径时, 351 评估为true, 371 永远不会执行。 行 371 是模块为您创建新工作表的位置。

if (($Append -or $ClearSheet) -and ($PSBoundParameters.ContainsKey('Excel') -or (Test-Path $Path)) ) # line 351
{
    $WorkSheet=$Excel.Workbook.Worksheets | Where-Object {$_.Name -like $WorkSheetName}
    if($ClearSheet)
    {
        $WorkSheet.Cells[$WorkSheet.Dimension.Start.Row, $WorkSheet.Dimension.Start.Column, $WorkSheet.Dimension.End.Row, $WorkSheet.Dimension.End.Column].Clear()
    }
    if($Append)
    {
        $RealHeaderCount = $WorkSheet.Dimension.Columns
        if($Header.count -ne $RealHeaderCount)
        {
            $Excel.Dispose()
            Throw "Found $RealHeaderCount existing headers, provided data has $($Header.count)."
        }
        $RowIndex = 1 + $Worksheet.Dimension.Rows
    }
}
else
{
    $WorkSheet = $Workbook.Worksheets.Add($WorkSheetName)  #line 371
}

为了解决这个问题,我在Export-XLSX.ps1文件中添加了几行代码。 现在,即使路径存在,也会:

  • 检查是否提供了$ WorksheetName
  • 检查此工作表是否尚不存在
  • 如果两者都为真,则创建新工作表。

请注意,您必须Remove-ModuleImport-Module才能识别更改。您需要使用-Append。我在第一个工作表上使用了-Force,而不是第二个工作表。此外,您可能会发现-Verbose很有帮助,因为它在脚本运行时为您提供了更多信息 - 非常适合调试。

if (($Append -or $ClearSheet) -and ($PSBoundParameters.ContainsKey('Excel') -or (Test-Path $Path)) )
{

    # New line: even if path exists, check for $WorkSheetName and that this worksheet doesn't exist
    if($WorkSheetName -and $Excel.Workbook.Worksheets | Where-Object {$_.Name -like $WorkSheetName} -eq $null)
    {
      # if you have $WorksheetName and it doesn't exist, create worksheet.
      $WorkSheet = $Workbook.Worksheets.Add($WorkSheetName)
    }
    else
    {
        $WorkSheet=$Excel.Workbook.Worksheets | Where-Object {$_.Name -like $WorkSheetName}
        if($ClearSheet)
        {
            $WorkSheet.Cells[$WorkSheet.Dimension.Start.Row, $WorkSheet.Dimension.Start.Column, $WorkSheet.Dimension.End.Row, $WorkSheet.Dimension.End.Column].Clear()
        }
        if($Append)
        {
            $RealHeaderCount = $WorkSheet.Dimension.Columns
            if($Header.count -ne $RealHeaderCount)
            {
                $Excel.Dispose()
                Throw "Found $RealHeaderCount existing headers, provided data has $($Header.count)."
            }
            $RowIndex = 1 + $Worksheet.Dimension.Rows
        }
    } # this is also new.
}
else
{
    $WorkSheet = $Workbook.Worksheets.Add($WorkSheetName)
}