バックグラウンド
私たちの開発では。SSRS 2005 を SSRS 2012 にアップグレードしているチームで、適切な変更をコードに適用して機能させようとしています。私たちの主な問題は、Microsoft が Dundas を購入し、2008 年までにコンポーネントを SSRS に組み込んだ以前と、Dundas を使用してグラフを生成したことです。ソリューションでこれに注意する必要があります。Internetz を読んだ後、現在のタスク タスクは、OnDemandReportingRendering 名前空間にある ICustomReportItem インターフェイスを実装する MReport (実稼働環境では別の名前) と呼ばれるランタイム コンポーネントを実装することであるという結論に達しました。
SSRS 2005 のソリューションでは、Dundas を使用してグラフを生成しています。Dundas.ReportingServices 名前空間には、従おうとしているインターフェイスとは完全に異なる ICustomReportItem の別の (古い?) バージョンを実装する以前に使用された DundasChart というクラスがあります。と。この古い ICustomReportItem は、OnDemandReportRendering 名前空間ではなく ReportRendering 名前空間にあります。後者を使用する必要があると私が信じる唯一の理由は、Microsoft が、まず第一にランタイム コンポーネントを使用して目的を達成する必要があることを知らせてくれたからです。
カスタム レポート アイテムのランタイム コンポーネントは、実行時にレポート プロセッサによって呼び出されます。実行時コンポーネントは、実行時にレポート プロセッサから渡されたデータを受け取り、このデータを処理して、レンダリングされたカスタム レポート アイテムを含む画像を返します。(5)
これをどのように行うべきかを正確に見つけようとしても、あまり見つけられませんでしたが、Technet (1) では、対象の ICustomReportItem が SQL Server 2012 の OnDemandReportRendering 名前空間にあることが明確に示されています。 Server 2005 では、ICustomReportItem は ReportRendering の下にある他のインターフェイスを参照します。
問題
アセンブリのロード
最初の問題は、配置後、ReportExecutionService (生成されたプロキシ クラス) で Render メソッドを呼び出すと、次の警告が表示されることです: The 'MReport' extension failed to load the extension assembly. カスタム レポート アイテム 'CustomMarcusChart' は、AltReportItem をレンダリングするか、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
- CodeGroup 要素を rssrvpolicy.config に追加 (2)
- ReportItem 要素を rsreportserver.config に追加しました (3) - これは、タイプを正しく指定する方法が不明な段階の 1 つです。
GenerateReportItemDefinition および EvaluateReportItemInstance にパラメーターとして提供された CustomReportItem からデータを取得する
以前は、Dundas は単に生成された画像を提供してくれましたが、今では、この新しい ICustomReportItem インターフェイスを使用して自分で動作を実装する必要があるようです。これが 2 番目の問題につながります。以前の ICustomerReportItem には、Process メソッドを呼び出す前に SSRS によって直接設定された (私が思うに) CustomData というプロパティがありました。CustomData は、グラフを生成して返すために必要なすべてのデータを保持していました。新しい ICustomerReportItem インターフェイスには、そのようなメンバーはなく、2 つのメソッド スタブだけです。ただし、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;
}
}
}