我有一个接受参数的SSRS报告,根据此参数,报告应该在电子邮件正文中发送到特定地址。可以有数百个不同的地址可以发送到这些地址。我们使用的是SQL Server标准版。
基于此,以下情况属实:
我知道我们可以通过SQL Server或.Net代码调用订阅,但我们无法根据需要更改收件人。我们最好的解决方案是在SSRS之外创建一个具有适当格式的HTML字符串,并将其添加到电子邮件正文中。在这样做时,这意味着如果需要更改任何内容,或者需要创建新报表,开发人员需要随时创建字符串,因此对于不熟悉HTML的人来说,它不是非常灵活。
那么还有其他方法可以在SSRS中创建报告,并根据参数值将其发送到指定电子邮件地址的电子邮件正文中吗?
答案 0 :(得分:3)
简短的回答是肯定的,但并不简单。这是我为SQL 2008开发的东西。
首先,要使报告显示在电子邮件正文中,您只需使用MHTML渲染器输出报告。这也可以参数化。
接下来,您需要一个带有脚本任务的SSIS包,该脚本任务可以运行报告并生成所需的输出。
以下是SSIS需要的VB脚本片段:
(Trolls原谅我使用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报告并将其发送给任何人。但要实现当前不灵活的开箱即用功能的解决方案需要付出很多努力和工程。
最后,我建议使用上述步骤迭代配置表包含电子邮件地址数据等。
当然,如果您愿意,可以使用此方法添加其他定制的报告参数。