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

相关问题