Powershell 多个 SQL 查询到 Excel 工作簿
Powershell Multiple SQL queries into Excel workbook
首先,如果这是一个重复的问题,我深表歉意。我搜索了又搜索,但没有找到任何解决我遇到的问题的方法。
我的目标是将 7 个 Powershell 脚本从 SQL 查询输出 CSV 到 1 个 Excel 工作簿中,每个 CSV 在不同的工作表上。
我找到了这个 https://social.technet.microsoft.com/Forums/scriptcenter/en-US/ef70e191-1b2e-4ba8-8845-58c4b1159ab7/multiple-csvs-into-multiple-sheets-of-an-excel 可以工作 但是 Excel 工作簿结果的第一列是最后一列。
function Export-Excel{
[cmdletBinding()]
Param([Parameter(ValueFromPipeline=$true)]
[string]$junk)
begin{
$header=$null
$row=1
}
process{
if(!$header){
$i=0
$header=$_ | Get-Member -MemberType NoteProperty | select name
$header | %{$Global:ws.cells.item(1,++$i)=$_.Name}
}
$i=0
++$row
foreach($field in $header){
$Global:ws.cells.item($row,++$i)=$($_."$($field.Name)")
}
}
}
$xl=New-Object -ComObject Excel.Application
$wb=$xl.WorkBooks.add(1)
$Global:ws=$wb.WorkSheets.item(1)
$Global:ws.Name='Sunday'
import-csv 'C:\Sunday.csv' | Export-Excel
最终得出以下结论。如果有更有效的方法,请告诉我。 SQL 个结果发送到 Excel 以利用 EntireColumn.AutoFit()
并将每个 SQL 个查询结果放在它自己的工作表上。
$docs = "C:\Scripts\Output.xlsx"
If (Test-Path $docs){Remove-Item $docs}
Function Run-Query {
param([string[]]$queries,[string[]]$weekdays)
## - Create an Excel Application instance:
$xlsObj = New-Object -ComObject Excel.Application
$xlsObj.DisplayAlerts = $false
$xlsWb = $xlsobj.Workbooks.Add(1)
## - Create new Workbook and Sheet (Visible = 1 / 0 not visible)
$xlsObj.Visible = 0
$time = 7
for ($i = 0; $i -lt $queries.Count; $i++){
$percentage = $i / $time
$remaining = New-TimeSpan -Seconds ($time - $i)
$message = "{0:p0} complete" -f $percentage, $remaining
Write-Progress -Activity "Creating Daily Reboot Spreadsheet" -status $message -PercentComplete ($percentage * 100)
$query = $queries[$i]
$weekday = $weekdays[$i]
$xlsSh = $xlsWb.Worksheets.Add([System.Reflection.Missing]::Value, $xlsWb.Worksheets.Item($xlsWb.Worksheets.Count))
$xlsSh.Name = $weekday
### SQL query results sent to Excel
$SQLServer = 'ServerName'
$Database = 'DataBase'
## - Connect to SQL Server using non-SMO class 'System.Data':
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $Database; Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $query
$SqlCmd.Connection = $SqlConnection
## - Extract and build the SQL data object '$DataSetTable:
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSetTable= $DataSet.Tables["Table"]
## - Build the Excel column heading:
[Array] $getColumnNames = $DataSetTable.Columns | SELECT ColumnName
## - Build column header:
[Int] $RowHeader = 1
foreach ($ColH in $getColumnNames)
{
$xlsSh.Cells.item(1, $RowHeader).font.bold = $true
$xlsSh.Cells.item(1, $RowHeader) = $ColH.ColumnName
$RowHeader++
}
## - Adding the data start in row 2 column 1:
[Int] $rowData = 2
[Int] $colData = 1
foreach ($rec in $DataSetTable.Rows)
{
foreach ($Coln in $getColumnNames)
{
## - Next line convert cell to be text only:
$xlsSh.Cells.NumberFormat = "@"
## - Populating columns:
$xlsSh.Cells.Item($rowData, $colData) = $rec.$($Coln.ColumnName).ToString()
$ColData++
}
$rowData++; $ColData = 1
}
## - Adjusting columns in the Excel sheet:
$xlsRng = $xlsSH.usedRange
[void] $xlsRng.EntireColumn.AutoFit()
}#End For loop.
#Delete unwanted Sheet1.
$xlsWb.Sheets.Item('Sheet1').Delete()
#Set Monday to Active Sheet upon opening Workbook.
$xlsWb.Sheets.Item('Cert').Activate()
## ---------- Saving file and Terminating Excel Application ---------- ##
$xlsFile = "C:\Scripts\Output.xlsx"
[void] $xlsObj.ActiveWorkbook.SaveAs($xlsFile)
$xlsObj.Quit()
## - End of Script - ##
Start-Sleep -Milliseconds 700
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsRng)) {'cleanup xlsRng'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsSh)) {'cleanup xlsSh'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsWb)) {'cleanup xlsWb'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsObj)) {'cleanup xlsObj'}
[gc]::collect() | Out-Null
[gc]::WaitForPendingFinalizers() | Out-Null
}#End Function
$queries = @()
$queries += "Query1"
$queries += "Query2"
$queries += "Query3"
$queries += "Query4"
$queries += "Query5"
$queries += "Query6"
$queries += "Query7"
$weekdays = @("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday")
Run-Query -queries $queries -weekdays $weekdays
我会有一个生成 7 个结果集的存储过程,然后编写一个 Powershell 函数,将数据从 SQL 导出到 Excel 中的 7 个工作表,并在 1 个镜头中导出 CSV。在下面的代码中,我从 link 此处下载了模块 ImportExcel
https://github.com/dfinke/ImportExcel
函数 Export-7Tables {
<#
。概要
这是功能的总结
。描述
这是更详细的描述
.参数
>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$false)]
[string]$DBServerInstance='.\mssql14',
[Parameter(Mandatory=$false)]
[string]$DBName='MyDBName',
[Parameter(Mandatory=$false)]
[string]$DBSchema='dbo',
[Parameter(Mandatory=$false)]
[string[]]$DBStoredProcedure='StoredProcName',
[Parameter(Mandatory=$false)]
[string]$WorkSheetName1='Sheet1InExcel',
[Parameter(Mandatory=$false)]
[string]$WorkSheetName2='Sheet2InExcel',
[Parameter(Mandatory=$false)]
[string]$WorkSheetName3='Sheet3InExcel',
[Parameter(Mandatory=$false)]
[string]$OutputExcelFilePath = 'C:\Users\myPC\Documents\myExcelFile.xlsx',
[Parameter(Mandatory=$false)]
[string]$OutputCSVFilePath= 'C:\Users\myPC\Documents\myCSVFile.csv'
)
#$Verbose = $VerbosePreference -ne 'SilentlyContinue'
Try {
$ErrorActionPreference = 'Stop'
#Set Private Data from Psd1 to Shorter Variable
$PD=$MyInvocation.MyCommand.Module.PrivateData
$DBParams = @{
ServerInstance = $DBServerInstance
Database = $DBName
Credential = Import-Clixml -Path $PD.CredentialFile
Query = "EXEC [$DBName].[$DBSchema].[$DBStoredProcedure]"
}
#Call storedproc
$DataSet = Invoke-SqlCmd @DBParams -OutputAs DataSet
# assign the first result set of stored procedure to $Sheet1DataTable and so on so forth
$Sheet1DataTable = $DataSet.Tables[0]
$Sheet2DataTable = $DataSet.Tables[1]
$Sheet3DataTable = $DataSet.Tables[2]
#Filter just the properties we want, these would be column headers
$DesiredProperties1 = @(
'ColumnName1'
'ColumnName2'
'ColumnName3'
'ColumnName4'
'ColumnName5'
)
#Filter just the properties we want in $Sheet2DataTable
$DesiredPropertiesSheet2 = @(
'ColumnName1'
'ColumnName2'
'ColumnName3'
'ColumnName4'
'ColumnName5'
)
#Filter just the properties we want in $Sheet3DataTable
$DesiredPropertiesSheet3 = @(
'ColumnName1'
'ColumnName2'
'ColumnName3'
'ColumnName4'
'ColumnName5'
)
#writing headers for the first Excel sheet (Sheet1)
$ResultSP1 = $Sheet1DataTable | Select-Object -Property $DesiredPropertiesSheet1
$ResultSP2 = $Sheet2DataTable | Select-Object -Property $DesiredPropertiesSheet2
$ResultSP3 = $Sheet3DataTable | Select-Object -Property $DesiredPropertiesSheet3
#Output to Excel file, CSV file, or to the screen
if ($OutputExcelFilePath) {
if (Test-Path -Path $OutputExcelFilePath) {Remove-Item -Path $OutputExcelFilePath}
$ResultSP1 | Export-Excel -Path $OutputExcelFilePath -WorksheetName "Sheet1InExcel" -AutoSize
$ResultSP2 | Export-Excel -Path $OutputExcelFilePath -WorksheetName "Sheet2InExcel" -AutoSize
$ResultSP3 | Export-Excel -Path $OutputExcelFilePath -WorksheetName "Sheet3InExcel" -AutoSize
}
#at the same time, out put data from StoredProc to CSV
if ($OutputCSVFilePath) {
$Output | Export-Csv -Path $OutputCSVFilePath -NoTypeInformation
}
}
Catch {
$ErrorActionPreference = 'Continue'
$PSCmdlet.WriteError($_)
} }
希望对您有所帮助。
首先,如果这是一个重复的问题,我深表歉意。我搜索了又搜索,但没有找到任何解决我遇到的问题的方法。
我的目标是将 7 个 Powershell 脚本从 SQL 查询输出 CSV 到 1 个 Excel 工作簿中,每个 CSV 在不同的工作表上。
我找到了这个 https://social.technet.microsoft.com/Forums/scriptcenter/en-US/ef70e191-1b2e-4ba8-8845-58c4b1159ab7/multiple-csvs-into-multiple-sheets-of-an-excel 可以工作 但是 Excel 工作簿结果的第一列是最后一列。
function Export-Excel{
[cmdletBinding()]
Param([Parameter(ValueFromPipeline=$true)]
[string]$junk)
begin{
$header=$null
$row=1
}
process{
if(!$header){
$i=0
$header=$_ | Get-Member -MemberType NoteProperty | select name
$header | %{$Global:ws.cells.item(1,++$i)=$_.Name}
}
$i=0
++$row
foreach($field in $header){
$Global:ws.cells.item($row,++$i)=$($_."$($field.Name)")
}
}
}
$xl=New-Object -ComObject Excel.Application
$wb=$xl.WorkBooks.add(1)
$Global:ws=$wb.WorkSheets.item(1)
$Global:ws.Name='Sunday'
import-csv 'C:\Sunday.csv' | Export-Excel
最终得出以下结论。如果有更有效的方法,请告诉我。 SQL 个结果发送到 Excel 以利用 EntireColumn.AutoFit()
并将每个 SQL 个查询结果放在它自己的工作表上。
$docs = "C:\Scripts\Output.xlsx"
If (Test-Path $docs){Remove-Item $docs}
Function Run-Query {
param([string[]]$queries,[string[]]$weekdays)
## - Create an Excel Application instance:
$xlsObj = New-Object -ComObject Excel.Application
$xlsObj.DisplayAlerts = $false
$xlsWb = $xlsobj.Workbooks.Add(1)
## - Create new Workbook and Sheet (Visible = 1 / 0 not visible)
$xlsObj.Visible = 0
$time = 7
for ($i = 0; $i -lt $queries.Count; $i++){
$percentage = $i / $time
$remaining = New-TimeSpan -Seconds ($time - $i)
$message = "{0:p0} complete" -f $percentage, $remaining
Write-Progress -Activity "Creating Daily Reboot Spreadsheet" -status $message -PercentComplete ($percentage * 100)
$query = $queries[$i]
$weekday = $weekdays[$i]
$xlsSh = $xlsWb.Worksheets.Add([System.Reflection.Missing]::Value, $xlsWb.Worksheets.Item($xlsWb.Worksheets.Count))
$xlsSh.Name = $weekday
### SQL query results sent to Excel
$SQLServer = 'ServerName'
$Database = 'DataBase'
## - Connect to SQL Server using non-SMO class 'System.Data':
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $Database; Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $query
$SqlCmd.Connection = $SqlConnection
## - Extract and build the SQL data object '$DataSetTable:
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSetTable= $DataSet.Tables["Table"]
## - Build the Excel column heading:
[Array] $getColumnNames = $DataSetTable.Columns | SELECT ColumnName
## - Build column header:
[Int] $RowHeader = 1
foreach ($ColH in $getColumnNames)
{
$xlsSh.Cells.item(1, $RowHeader).font.bold = $true
$xlsSh.Cells.item(1, $RowHeader) = $ColH.ColumnName
$RowHeader++
}
## - Adding the data start in row 2 column 1:
[Int] $rowData = 2
[Int] $colData = 1
foreach ($rec in $DataSetTable.Rows)
{
foreach ($Coln in $getColumnNames)
{
## - Next line convert cell to be text only:
$xlsSh.Cells.NumberFormat = "@"
## - Populating columns:
$xlsSh.Cells.Item($rowData, $colData) = $rec.$($Coln.ColumnName).ToString()
$ColData++
}
$rowData++; $ColData = 1
}
## - Adjusting columns in the Excel sheet:
$xlsRng = $xlsSH.usedRange
[void] $xlsRng.EntireColumn.AutoFit()
}#End For loop.
#Delete unwanted Sheet1.
$xlsWb.Sheets.Item('Sheet1').Delete()
#Set Monday to Active Sheet upon opening Workbook.
$xlsWb.Sheets.Item('Cert').Activate()
## ---------- Saving file and Terminating Excel Application ---------- ##
$xlsFile = "C:\Scripts\Output.xlsx"
[void] $xlsObj.ActiveWorkbook.SaveAs($xlsFile)
$xlsObj.Quit()
## - End of Script - ##
Start-Sleep -Milliseconds 700
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsRng)) {'cleanup xlsRng'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsSh)) {'cleanup xlsSh'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsWb)) {'cleanup xlsWb'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsObj)) {'cleanup xlsObj'}
[gc]::collect() | Out-Null
[gc]::WaitForPendingFinalizers() | Out-Null
}#End Function
$queries = @()
$queries += "Query1"
$queries += "Query2"
$queries += "Query3"
$queries += "Query4"
$queries += "Query5"
$queries += "Query6"
$queries += "Query7"
$weekdays = @("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday")
Run-Query -queries $queries -weekdays $weekdays
我会有一个生成 7 个结果集的存储过程,然后编写一个 Powershell 函数,将数据从 SQL 导出到 Excel 中的 7 个工作表,并在 1 个镜头中导出 CSV。在下面的代码中,我从 link 此处下载了模块 ImportExcel https://github.com/dfinke/ImportExcel
函数 Export-7Tables { <# 。概要 这是功能的总结 。描述 这是更详细的描述 .参数
>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$false)]
[string]$DBServerInstance='.\mssql14',
[Parameter(Mandatory=$false)]
[string]$DBName='MyDBName',
[Parameter(Mandatory=$false)]
[string]$DBSchema='dbo',
[Parameter(Mandatory=$false)]
[string[]]$DBStoredProcedure='StoredProcName',
[Parameter(Mandatory=$false)]
[string]$WorkSheetName1='Sheet1InExcel',
[Parameter(Mandatory=$false)]
[string]$WorkSheetName2='Sheet2InExcel',
[Parameter(Mandatory=$false)]
[string]$WorkSheetName3='Sheet3InExcel',
[Parameter(Mandatory=$false)]
[string]$OutputExcelFilePath = 'C:\Users\myPC\Documents\myExcelFile.xlsx',
[Parameter(Mandatory=$false)]
[string]$OutputCSVFilePath= 'C:\Users\myPC\Documents\myCSVFile.csv'
)
#$Verbose = $VerbosePreference -ne 'SilentlyContinue'
Try {
$ErrorActionPreference = 'Stop'
#Set Private Data from Psd1 to Shorter Variable
$PD=$MyInvocation.MyCommand.Module.PrivateData
$DBParams = @{
ServerInstance = $DBServerInstance
Database = $DBName
Credential = Import-Clixml -Path $PD.CredentialFile
Query = "EXEC [$DBName].[$DBSchema].[$DBStoredProcedure]"
}
#Call storedproc
$DataSet = Invoke-SqlCmd @DBParams -OutputAs DataSet
# assign the first result set of stored procedure to $Sheet1DataTable and so on so forth
$Sheet1DataTable = $DataSet.Tables[0]
$Sheet2DataTable = $DataSet.Tables[1]
$Sheet3DataTable = $DataSet.Tables[2]
#Filter just the properties we want, these would be column headers
$DesiredProperties1 = @(
'ColumnName1'
'ColumnName2'
'ColumnName3'
'ColumnName4'
'ColumnName5'
)
#Filter just the properties we want in $Sheet2DataTable
$DesiredPropertiesSheet2 = @(
'ColumnName1'
'ColumnName2'
'ColumnName3'
'ColumnName4'
'ColumnName5'
)
#Filter just the properties we want in $Sheet3DataTable
$DesiredPropertiesSheet3 = @(
'ColumnName1'
'ColumnName2'
'ColumnName3'
'ColumnName4'
'ColumnName5'
)
#writing headers for the first Excel sheet (Sheet1)
$ResultSP1 = $Sheet1DataTable | Select-Object -Property $DesiredPropertiesSheet1
$ResultSP2 = $Sheet2DataTable | Select-Object -Property $DesiredPropertiesSheet2
$ResultSP3 = $Sheet3DataTable | Select-Object -Property $DesiredPropertiesSheet3
#Output to Excel file, CSV file, or to the screen
if ($OutputExcelFilePath) {
if (Test-Path -Path $OutputExcelFilePath) {Remove-Item -Path $OutputExcelFilePath}
$ResultSP1 | Export-Excel -Path $OutputExcelFilePath -WorksheetName "Sheet1InExcel" -AutoSize
$ResultSP2 | Export-Excel -Path $OutputExcelFilePath -WorksheetName "Sheet2InExcel" -AutoSize
$ResultSP3 | Export-Excel -Path $OutputExcelFilePath -WorksheetName "Sheet3InExcel" -AutoSize
}
#at the same time, out put data from StoredProc to CSV
if ($OutputCSVFilePath) {
$Output | Export-Csv -Path $OutputCSVFilePath -NoTypeInformation
}
}
Catch {
$ErrorActionPreference = 'Continue'
$PSCmdlet.WriteError($_)
} }
希望对您有所帮助。