Recently I had a client that wanted to load an Excel File from a SQL query from an SSIS package. Since the Data Flows in SSIS are pretty rigid in terms of columns and data types it can not just add or delete columns on the fly. So I developed a script task in a package to accept a SQL command and dynamically build the excel file.
' Microsoft SQL Server Integration Services Script Task
' Write scripts using Microsoft Visual Basic 2008.
' The ScriptMain is the entry point class of the script.
Imports System
Imports System.IO
Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Text.RegularExpressions
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.Threading
Imports Microsoft.Office.Interop.Owc11
<System.AddIn.AddIn("ScriptMain", Version:="1.0", Publisher:="", Description:="")> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
Public Sub Main()
'Load Package variables
Dim FileName As String = Dts.Variables("strDestinationFileName").Value
Dim connectString As String = Dts.Variables("strSourceConnection").Value
Dim sqlQuery As String = Dts.Variables("strExportQuery").Value
Dim worksheet As String = Dts.Variables("strDestinationWorksheet").Value
GenerateExcelSheet(connectString, sqlQuery, FileName, worksheet)
Dts.TaskResult = ScriptResults.Success
End Sub
Public Sub GenerateExcelSheet(ByVal ConnectString As String, ByVal sqlQuery As String, ByVal FileName As String, ByVal worksheet As String)
Try
Using sqlCon As SqlConnection = GetSqlConnection(ConnectString) 'get the SqlConnection
Dim sqlCommand As New SqlCommand(sqlQuery, sqlCon) 'create the sql command
Dim dr As SqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection) ' populate DataReader
Dim rowCount As Integer = 1 ' reset row counter
Dim spread As Spreadsheet = New SpreadsheetClass() ' create an instance of SpreadSheet Web Control
spread.ActiveSheet.Name = worksheet 'Change the Sheet name
For colCount As Integer = 0 To dr.FieldCount - 1 ' write out field headers
spread.Cells(rowCount, colCount + 1) = dr.GetName(colCount)
Next
While dr.Read() ' write out the actual data by looping thru the dataReader
rowCount += 1
For colCount As Integer = 0 To dr.FieldCount - 1
spread.Cells(rowCount, colCount + 1) = dr.GetValue(colCount).ToString().Replace(vbCr, "").Replace(vbLf, "") ' filter out any \r & \n in the data
Next
End While
spread.Export(FileName, SheetExportActionEnum.ssExportActionNone) ' generate the XLS file
spread = Nothing ' de-reference the SpreadSheet Control
End Using
Catch ex As Exception
MsgBox(ex.ToString)
Throw ex
End Try
End Sub
Private Function GetSqlConnection(ByVal ConnectString As String) As SqlConnection
Dim sqlCon As New SqlConnection(ConnectString)
Try
' make sure the time-out value specified is acceptable
If Not (sqlCon.ConnectionTimeout = 0) OrElse (sqlCon.ConnectionTimeout > 60) Then
sqlCon.Open()
Return sqlCon
Else
Throw New Exception("Invalid Connection Time Out Value Specified")
End If
Catch ex As Exception
'MsgBox(ex.ToString)
Throw ex
End Try
End Function
End Class