2

我有一個接受參數的SSRS報告,根據此參數報告應該在電子郵件正文中發送到特定地址。可以將數百個不同的地址發送到這些地址。我們正在使用SQL Server標準版。以編程方式在電子郵件正文中發送SSRS報告

在此基礎上,符合下列條件:

  • 我們不能用(在企業版僅適用)驅動的訂閱數據
  • 我們不能設置多個訂閱每個潛在接收者(有可能是數百個)
  • 我們不想發送報告作爲附件(需要在電子郵件正文)

我知道我們可以稱之爲從SQL Server訂閱或通過.Net代碼,但我們無法改變收件人,據我所知。我們當前的最佳解決方案是在SSRS之外創建一個HTML字符串,並使用適當的格式並將其添加到電子郵件的正文中。這樣做意味着開發人員需要隨時創建字符串,如果需要更改任何內容或需要創建新報告,那麼對於不熟悉HTML的任何人都不太靈活。

那麼有沒有其他方法可以在SSRS中創建報告,並根據參數值將其發送到電子郵件正文中指定的電子郵件地址?

回答

3

簡短的回答是肯定的,但它並不簡單。這是我爲SQL 2008開發的一些東西。

首先,爲了使報告出現在電子郵件正文中,您只需使用MHTML渲染器輸出它。這也可以參數化。

接下來,您需要一個包含腳本任務的SSIS包,該腳本任務可以運行報告並生成所需的輸出。

這裏的VB腳本,你將需要使用SSIS的一個片段:(巨魔原諒我用VB我只曾經使用C#這些天)

第一種方法用於保存文件。

Protected Sub SaveFile(ByVal url As String, ByVal localpath As String) 
    Dim loRequest As System.Net.HttpWebRequest 
    Dim loResponse As System.Net.HttpWebResponse 
    Dim loResponseStream As System.IO.Stream 
    Dim loFileStream As New System.IO.FileStream(localpath, System.IO.FileMode.Create, System.IO.FileAccess.Write) 
    Dim laBytes(256) As Byte 
    Dim liCount As Integer = 1 
    Try 

     loRequest = CType(System.Net.WebRequest.Create(url), System.Net.HttpWebRequest) 
     loRequest.Credentials = System.Net.CredentialCache.DefaultCredentials 
     loRequest.Timeout = 99999 '1 minute 
     loRequest.Method = "GET" 
     loResponse = CType(loRequest.GetResponse, System.Net.HttpWebResponse) 
     loResponseStream = loResponse.GetResponseStream 
     Do While liCount > 0 
      liCount = loResponseStream.Read(laBytes, 0, 256) 
      loFileStream.Write(laBytes, 0, liCount) 
     Loop 
     loFileStream.Flush() 
     loFileStream.Close() 
    Catch ex As Exception 
    End Try 
End Sub 

第二種方法以所需格式調用SSRS報告並使用第一種方法進行保存。

Public Sub Main() 
    Dim url, destination As String 
    Dim FileExtension As String 
    Dim RenderAs As String 

    'default to avoid nulls 
    FileExtension = ".NULL" 'http://msdn.microsoft.com/en-gb/library/ms154606.aspx 

    RenderAs = Dts.Variables("FileType").Value.ToString 

    If RenderAs = "EXCEL" Then 
     FileExtension = ".xls" 
    ElseIf RenderAs = "WORD" Then 
     FileExtension = ".doc" 
    ElseIf RenderAs = "PDF" Then 
     FileExtension = ".pdf" 
    ElseIf RenderAs = "MHTML" Then 
     FileExtension = ".mhtml" 
    ElseIf RenderAs = "CSV" Then 
     FileExtension = ".csv" 
    ElseIf RenderAs = "IMAGE" Then 
     FileExtension = ".tif" 
    End If 

    'create ssrs url 
    'url = "http://hisrs01/ReportServer/Pages/ReportViewer.aspx?%2fCombined+Reports+-+HIS%2f14-15+SSoTP+Staff+Level+Weekly+Activity&rs:Command=Render&StaffGroup=" + Dts.Variables("varRSParameter1").Value.ToString + "&Provider=" + Dts.Variables("varRSParameter2").Value.ToString + "&rs:Format=Excel" 
    url = Dts.Variables("ReportURL").Value.ToString + "&rs:Format=" + Dts.Variables("FileType").Value.ToString 

    'create destination 
    destination = Dts.Variables("TempFilePath").Value.ToString + "\Reports Created\" + Dts.Variables("FileName").Value.ToString + FileExtension 

    'System.Threading.Thread.Sleep(5000) 

    'write url out to test file (debugging) 
    'strFile = "D:\Test\" + Replace(Dts.Variables("varRSParameter1").Value.ToString, "+", " ") + " - " + Replace(Dts.Variables("varRSParameter2").Value.ToString, "+", " ") + ".txt" 
    'File.AppendAllText(strFile, url) 

    SaveFile(url, destination) 

    Dts.TaskResult = ScriptResults.Success 

End Sub 

您需要使用SSIS包變量來處理報表的生成方式,格式和位置。

enter image description here

然後創建了一個存儲過程來調用SSIS包與所需要的值。然後使用SQL Server數據庫郵件收集SSIS生成的文件,附加它,然後使用dbmail處理的收件人而不是來自SSRS訂閱的SMTP調用。

這是一個程序。

CREATE PROCEDURE [dbo].[EmailSSRSReport] 
    (
    @Event VARCHAR(50) = 'Test', 
    @ReportURL NVARCHAR(500), 
    @FileType VARCHAR(10) = 'MHTML', 
    @FileName VARCHAR(100) = 'Rendered SSRS Report', 
    @Debug BIT = 0 
    ) 
AS 

BEGIN 

    --local variables 
    DECLARE @Cmd NVARCHAR(500) 
    DECLARE @EmailAddresses NVARCHAR(500) 
    DECLARE @PackagePath NVARCHAR(255) 
    DECLARE @FullFilePath NVARCHAR(500) 
    DECLARE @FinalBodyText VARCHAR(MAX) 
    DECLARE @FinalSubject VARCHAR(MAX) 
    DECLARE @CmdOutput TABLE 
     (
     [Output] NVARCHAR(500) NULL 
     ) 

    --set and get parts for report and email  
    SELECT 
     @EmailAddresses = [Notifications].[dbo].[fn_GetEmailAddresses](@Event), 
     @PackagePath = [dbo].[fn_GetProperty]('SSISPackageLocation'), 
     @FullFilePath = [dbo].[fn_GetProperty]('ReportsOutputFolder') + @FileName + 
      CASE UPPER(@FileType) 
       WHEN 'EXCEL' THEN '.xls' 
       WHEN 'WORD' THEN '.doc' 
       WHEN 'PDF' THEN '.pdf' 
       WHEN 'MHTML' THEN '.mhtml' 
       WHEN 'CSV' THEN '.csv' 
       WHEN 'IMAGE' THEN '.tif' 
      END, 
     @FinalBodyText = 'Please see attached the requested SSRS report <strong>' + @FileName + '</strong>.<br/><br/>Kind regards<br/><br/>S&SHIS Data Management<br/><a href="mailto:[email protected]?subject=SSRS Report Auto Email">[email protected]</a>', 
     @FinalSubject = 'Auto Alert For ' + @FileName + '. ' + CONVERT(VARCHAR, GETDATE(), 103) 

    SET @Cmd = 'dtexec /f "' + @PackagePath + 'Run SSRS Report.dtsx" /set \package.variables[ReportURL].Value;"' + @ReportURL + '" /set \package.variables[FileName].Value;"' + @FileName + '" /set \package.variables[FileType].Value;"' + @FileType + '"' 

    --add styling 
    SET @FinalBodyText = 
    ' 
    <html> 
    <head> 
     <style type="text/css"> 
      body 
       { 
       font-family: "calibri"; 
       font-size: 16px; 
       } 
     </style> 
    </head> 
    <body> 
    ' + @FinalBodyText + 
    '</body> 
    </html>' 

    --run command to produce SSRS report with params 
    INSERT INTO @CmdOutput 
    EXEC [master].sys.xp_cmdshell @Cmd 

    --check cmd output for errors 
    IF EXISTS 
     ( 
     SELECT 
      * 
     FROM 
      @CmdOutput 
     WHERE 
      [Output] LIKE '%error%' 
     ) 
     BEGIN 
      RAISERROR('Error executing command, run procedure in debug mode o view output.',16,1) 
      RETURN; 
     END 

    --output details in debug mode 
    IF @Debug = 1 
     BEGIN 
      SELECT @Cmd AS 'Cmd' 

      SELECT 
       * 
      FROM 
       @CmdOutput 
     END 

    --send email 
    EXEC msdb.dbo.sp_send_dbmail 
     @recipients = @EmailAddresses, 
     @subject = @FinalSubject, 
     @body = @FinalBodyText, 
     @file_attachments = @FullFilePath, 
     @body_format = 'HTML'; 

END 
GO 

這給你完全靈活的方式來運行任何SSRS報告並將其發送給任何人。但是,要實現目前不靈活的即開即用功能的解決方案,需要付出很多努力和工程量。

最後,我建議使用上述過程遍歷包含電子郵件地址數據等的配置表。

當然,如果您願意,還可以使用此方法添加其他定製報告參數。

+0

糾正我,如果我錯了,但這*附加*報告,並沒有直接渲染到電子郵件正文?我已經能夠做到這一點,但按照規定,我們不想附上報告。 – anothershrubery

+0

GetEmailAddresses和GetProperty是否有代碼?或者至少數據(或字符串)在運行這些函數後應該如何看待? –

+0

無需安裝報告服務器即可生成報告嗎?還是需要作爲渲染的手段? – Utrolig

相關問題