背景
在我们的开发中。团队我们正在将 SSRS 2005 升级到 SSRS 2012,我正在尝试对我们的代码进行适当的更改以使其正常工作。我们的主要问题是我们之前使用 Dundas 生成图表,自从 Microsoft 购买了 Dundas 并在 2008 年之前将该组件合并到 SSRS 中,我们需要在我们的解决方案中解决这个问题。在 Internetz 上进行一些阅读后,我得出的结论是,我当前的任务任务是实现一个运行时组件,我称之为 MReport(生产中的另一个名称),它实现位于 OnDemandReportingRendering 命名空间中的 ICustomReportItem 接口。
在我们使用 SSRS 2005 的解决方案中,我们使用 Dundas 生成图表,并且在 Dundas.ReportingServices 命名空间中,有一个以前使用过的名为 DundasChart 的类,它实现了 ICustomReportItem 的另一个(旧?)版本,它与我试图遵守的接口完全不同和。此较旧的 ICustomReportItem 位于 ReportRendering 命名空间中,而不是 OnDemandReportRendering 命名空间中。我认为我应该使用后者的唯一原因是因为微软让我知道首先我应该使用运行时组件来实现我想要的。
自定义报表项的运行时组件由报表处理器在运行时调用。运行时组件接受报表处理器在运行时传递的数据,处理此数据,并返回包含呈现的自定义报表项的图像。(5)
试图确切地找到应该如何完成我没有找到太多但在 Technet (1) 上它清楚地指出感兴趣的 ICustomReportItem 位于 SQL Server 2012 的 OnDemandReportRendering 命名空间中。如果选择“其他版本”和 SQL在 Server 2005 中,ICustomReportItem 指的是位于 ReportRendering 下的另一个接口。
问题
加载程序集
我遇到的第一个问题是,在部署后,我在调用 ReportExecutionService(生成的代理类)上的 Render 方法时收到以下警告: “MReport”扩展无法加载扩展程序集。如果没有明确定义 AltReportItem,自定义报告项“CustomMarcusChart”将呈现 AltReportItem 或保留空白。
EventViewer 完成: 报表服务器 (SQL2012) 无法加载 MReport 扩展。
请注意,虽然我收到此警告,但当我将调试器附加到 ReportingServices 进程时,我仍然可以在为其加载符号的 MReport 类中设置断点,这暗示程序集毕竟以某种方式加载。
我已经按照我认为可能的程度执行了部署 CustomReportItem 的程序,如果我犯了任何错误,请纠正我:
- 在名为 MarcusReports 的类库中实现了 MReport 类(我的代码直接取自 Microsoft (1)(4))
- 将类库构建为 .NET 3.5 程序集
- 将 DLL 和 PDB 文件复制到 C:\Program Files\Microsoft SQL Server\MSRS11.SQL2012\Reporting Services\ReportServer\bin\ 、 C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies 和C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies
- 向 rssrvpolicy.config 添加了 CodeGroup 元素 (2)
- 向 rsreportserver.config (3) 添加了 ReportItem 元素 - 这是我不确定如何正确指定类型的阶段
从作为参数提供给 GenerateReportItemDefinition 和 EvaluateReportItemInstance 的 CustomReportItem 中检索数据
以前,Dundas 只是给了我们生成的图像,但现在看来我必须在这个新的 ICustomReportItem 接口的帮助下自己实现该行为,这导致了第二个问题。在较旧的 ICustomerReportItem 中有一个属性 CustomData,它是由 SSRS 在调用 Process 方法之前直接设置的(我认为)。CustomData 包含所有必要的数据以生成图形并返回它。在新的 ICustomerReportItem 接口中没有这样的成员,只有两个方法存根。但是,CustomerReportItem 实例作为参数传递给这些方法,人们会认为 CustomerReportItem 上的 CustomData 将保存必要的图形数据,但它没有,或者至少不在我们期望的结构中,具有系列和 x/y标签。
是否有任何地方可以阅读有关如何实现这一点的信息。对于如何实际使用新的 ICustomerReportItem 接口来生成自定义图形图像,我还没有找到任何好的材料或好的解释。
资料来源:
1) http://technet.microsoft.com/en-us/library/ms345254(v=sql.110).aspx
2)
<CodeGroup
class="UnionCodeGroup"
version="1"
PermissionSetName="FullTrust"
Description="This code group grants MyCustomReportItem.dll FullTrust permission. ">
<IMembershipCondition class="UrlMembershipCondition" version="1" Url="C:\Program Files\Microsoft SQL Server\MSRS11.SQL2012\Reporting Services\ReportServer\bin\MarcusReports.dll" />
</CodeGroup>
3)
<ReportItems>
<ReportItem Name="MReport" Type="MarcusReports.MReport,MReport"/>
</ReportItems>
4)
using System.Drawing.Imaging;
using System.IO;
using Microsoft.ReportingServices.OnDemandReportRendering;
namespace MarcusReports
{
public class MReport : ICustomReportItem
{
public void GenerateReportItemDefinition(CustomReportItem cri)
{
// Create the Image object that will be
// used to render the custom report item
cri.CreateCriImageDefinition();
var polygonImage = (Image )cri.GeneratedReportItem;
}
public void EvaluateReportItemInstance(CustomReportItem cri)
{
// Get the Image definition
var polygonImage = (Image )cri.GeneratedReportItem;
// Create the image for the custom report item
polygonImage.ImageInstance.ImageData = DrawImage(cri);
}
/// <summary>
/// Creates an image of the CustomReportItem's name
/// </summary>
private static byte[] DrawImage( ReportItem customReportItem)
{
var width = 1; // pixels
var height = 1; // pixels
const int resolution = 75; // dpi
var bitmap = new System.Drawing.Bitmap(width, height);
bitmap.SetResolution(resolution, resolution);
var graphics = System.Drawing.Graphics .FromImage(bitmap);
graphics.PageUnit = System.Drawing. GraphicsUnit.Pixel;
// Get the Font for the Text
var font = new System.Drawing.Font(System.Drawing.FontFamily .GenericMonospace, 12, System.Drawing.FontStyle.Regular);
// Get the Brush for drawing the Text
var brush = new System.Drawing.SolidBrush(System.Drawing.Color .LightGreen);
// Get the measurements for the image
var maxStringSize = graphics.MeasureString(customReportItem.Name, font);
width = ( int)(maxStringSize.Width + 2 * font.GetHeight(resolution));
height = ( int)(maxStringSize.Height + 2 * font.GetHeight(resolution));
bitmap.Dispose();
bitmap = new System.Drawing.Bitmap (width, height);
bitmap.SetResolution(resolution, resolution);
graphics.Dispose();
graphics = System.Drawing. Graphics.FromImage(bitmap);
graphics.PageUnit = System.Drawing. GraphicsUnit.Pixel;
// Draw the text
graphics.DrawString(customReportItem.Name, font, brush, font.GetHeight(resolution),font.GetHeight(resolution));
// Create the byte array of the image data
var memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);
memoryStream.Position = 0;
var imageData = new byte[memoryStream.Length];
memoryStream.Read(imageData, 0, imageData.Length);
return imageData;
}
}
}