繁体   English   中英

以编程方式在电子邮件正文中发送SSRS报告

[英]Send SSRS report in email body programmatically

我有一个接受参数的SSRS报告,应基于此参数将报告通过电子邮件正文发送到特定地址。 这些地址可以发送到数百个不同的地址。 我们正在使用SQL Server标准版。

基于此,以下是正确的:

  • 我们无法使用数据驱动的订阅(仅在企业版中可用)
  • 我们无法为每个潜在收件人设置多个订阅(可能有数百个)
  • 我们不希望将报告作为附件发送(需要作为电子邮件的正文)

我知道我们可以从SQL Server或通过.Net代码调用预订,但是据我所知,我们无法更改收件人。 目前,我们最好的解决方案是在SSRS之外创建具有适当格式的HTML字符串,并将其添加到电子邮件正文中。 这样做意味着如果需要更改任何内容或需要创建新的报告,则开发人员需要手头来创建字符串,因此对于不熟悉HTML的任何人来说,它都不是很灵活。

那么,还有其他方法可以基于参数值在SSRS中创建报告并将其发送到电子邮件正文中到指定的电子邮件地址吗?

简短的答案是肯定的,但并不简单。 这是我为SQL 2008开发的。

首先,要使报告显示在电子邮件正文中,您只需要使用MHTML渲染器将其输出即可。 这也可以参数化。

接下来,您将需要一个带有脚本任务的SSIS包,该脚本任务可以运行报告并生成所需的输出。

这是SSIS需要的VB脚本的片段:

(巨魔原谅我使用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包变量来处理报表的生成方式,格式和来源。

在此处输入图片说明

然后,我创建了一个存储过程,以使用所需的值调用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:datamanagement@sshis.nhs.uk?subject=SSRS Report Auto Email">DataManagement@sshis.nhs.uk</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报告并将其发送给任何人。 但是要解决目前这种不灵活的即用型功能,需要花费大量的精力和精力。

最后,我建议按照上述步骤遍历包含电子邮件地址数据等的配置表。

当然,如果需要,可以使用此方法添加其他定制报告参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM