微軟的Reporting Services逐漸被大眾熟悉并接受。以前做過Reporting Services的項目,但是總結的不多。最近看到越多越多的報表項目是用Reporting Services來做,走出去看看才知道別人在做什么。
今天要涉及到的主題是Reporting Services Extension,報表擴展。其實我是要搭建一個報表設計,開發的工具箱。在以前的一篇文章中,提到過用Reporting Services+Remoting做的報表設計平臺。Remoting客戶端向服務器發送SQL語句,其實不是SQL語句,準確說是類似如下的語句:程序集;類;方法 把這個查詢語句發送到Remoting服務器,服務器在GAC中去找對應的程序集和方法,反射調用之,返回數據集給報表設計器。這種結構的報表設計靈活性很強。特別是一些計算,字符串方面的處理,用SQL語句可能不方便,要寫很多的T_SQL代碼。但是如果用這種方法,充分發揮程序語言(C#)和數據庫語言(T_SQL)的長處,把集合運算部分用T_SQL來處理,計算和字符文本的處理則留在C#代碼中。
萬丈高樓平地起,要做這樣一個擴展,需要先熟悉Reporting Services提供了哪些可以擴展的方面。
如果您看過微軟的例子,它提供了下面幾個主要的例子(Extension Samples)
FormsAuthentication Sample 擴展報表服務器的驗證方式
FsiDataExtension Sample? 數據處理擴展
PolygonsCustomReportItem? 自定義報表項
PrinterDelivery Sample? 打印傳送擴展
我主要關注的是FsiDataExtension ,它的位置在
C:\Program Files\Microsoft SQL Server\90\Samples\Reporting Services\Extension Samples
代碼結構如下圖
這里面有幾個主要的類:Connection,Command,DataParameter,DataReader,Transaction。
看到這幾個類,您可能會心的一笑,這不就是ADO.NET的結構嗎?
編譯這個例子,生成程序集Microsoft.Samples.ReportingServices.FsiDataExtension.dll
部署這個例子
1)拷貝文件到報表服務器和設計器中,把Microsoft.Samples.ReportingServices.FsiDataExtension.dll拷貝到C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportServer\bin.
和C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies
2)修改配置文件RSReportServer.config and RSReportDesigner.config的Data元素
RSReportDesigner.config 文件的位置是 C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies。RSReportServer.config 位置在C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportServer
添加如下元素
<Extension Name="FSI" Type="Microsoft.Samples.ReportingServices.FsiDataExtension.FsiConnection,
Microsoft.Samples.ReportingServices.FsiDataExtension"/>
為了支持報表設計器,修改RSReportDesigner.config 的Designer元素,添加
<Extension Name="FSI" Type="Microsoft.ReportingServices.QueryDesigners.VDTQueryDesigner,
Microsoft.ReportingServices.QueryDesigners"/>
3)配置代碼訪問安全性
修改rssrvpolicy.config和rspreviewpolicy.config文件,它們的位置分別在在
C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportServer
和C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies
添加一個CodeGroup 元素,內容如下
<CodeGroup class="UnionCodeGroup"
?? version="1"
?? PermissionSetName="FullTrust"
?? Name="FSICodeGroup"
?? Description="Code group for my FSI data processing extension">
????? <IMembershipCondition class="UrlMembershipCondition"
???????? version="1"
???????? Url="C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportServer\bin\Microsoft.Samples.ReportingServices.FsiDataExtension.dll"
?????? />
</CodeGroup>
不需要重啟動電腦,打開Visual Studio 2005 BIDS,新建一個Reporting Services項目
?
從圖中看到,數據源中有File Share Information,選擇它作為報表的數據源
新建數據集,輸入查詢字符串
\\XX-PCName\\2010
,XX-PCName是計算機的名字
這個擴展的目的是讀取某臺計算機的共享文件夾中的信息,作為數據集的內容。
執行這個數據集,得到的結果如下
設計報表,使用Table控件
預覽報表,結果如預期所示
?
雖然這個擴展沒有多大的意義,但是它展示了如何去擴展Reporting Services的Data Process。
下面再來看看,FsiDataExtension項目的代碼結構
再看看類圖,大概了解有多少個類相互協作
再到代碼里面看看,各自的關系
public sealed class FsiConnection : IDbConnectionExtension
public sealed class FsiCommand : IDbCommand
public sealed class FsiDataParameter : IDataParameter
public sealed class FsiDataParameterCollection : ArrayList, IDataParameterCollection
public sealed class FsiDataReader : IDataReader
public sealed class FsiTransaction : IDbTransaction
要正確編譯這些類,需要引用Microsoft.ReportingServices.Interfaces.dll,實現它的接口
運用熟悉的ADO.NET的知識,打開IDbConnection接口
?
IDbCommand的結構如下
?
通過代碼中的注釋,一個查詢語句傳進來,它的流程應該是這樣的
1)連接類型是FsiConnection,它是個空連接,不需要傳入任何連接字符串。
因為權限的原因,設置當前連接主體WindowsIdentity
2)引擎根據查詢代碼和連接類型,調用如下構造方法
public FsiCommand(string cmdText, FsiConnection connection)? {
??????? m_cmdText = cmdText;?????? m_connection = connection;????
? }
最主要的還是IDbCommand.ExecuteReader(CommandBehavior behavior),它是執行查詢命令的主要地方,它調用FsiDataReader,讀取數據記錄
reader = new FsiDataReader(m_cmdText);
reader.GetDirectory(m_cmdText);
進入數據讀取類,它的讀取代碼如下
bool IDataReader.Read()
?????? {
?????????? if (m_ie != null)
?????????? {
?????????????? bool notEOF = m_ie.MoveNext();
?????????????? if (notEOF == true)
?????????????? {
?????????????????? m_currentRow++;
?????????????????? if (m_fsi[m_currentRow] is FileInfo)
?????????????????? {
?????????????????????? FileInfo f = (FileInfo)m_fsi[m_currentRow];
?????????????????????? m_cols[0] = f.Name;
?????????????????????? m_cols[1] = f.Length.ToString(
?????????????????????????? System.Globalization.CultureInfo.InvariantCulture);
?????????????????????? m_cols[2] = "File";
?????????????????????? m_cols[3] = f.CreationTime.ToString();
?????????????????? }
?????????????????? else
?????????????????? {
?????????????????????? DirectoryInfo d = (DirectoryInfo)m_fsi[m_currentRow];
?????????????????????? m_cols[0] = d.Name;
?????????????????????? m_cols[1] = "0";
?????????????????????? m_cols[2] = "Directory";
?????????????????????? m_cols[3] = d.CreationTime.ToString();
?????????????????? }
?????????????? }
?????????????? return notEOF;
?????????? }
?????????? return false;
?????? }
FsiDataReader定義了如下成員
internal String[] m_names = { "Name", "Size", "Type", "CreationDate" };
internal Type[] m_types = { typeof(String), typeof(long), typeof(String), typeof(DateTime) };
internal object[] m_cols = new object[4];
它有一個方法,根據傳入的查詢字符串,讀取目錄信息
internal void GetDirectory(string cmdText)
{
?????????? ValidateCommandText(cmdText);?
?????????? m_dir = new DirectoryInfo(cmdText);
?????????? m_fsi = m_dir.GetFileSystemInfos();?
?????????? m_currentRow = -1;
?????????? m_ie = m_fsi.GetEnumerator();
}
這樣,借助于這些方法和接口,Fsi DataExtension Sample就可以部署到Reporting Services中,供報表設計和運行時使用。更多的細節請查看具體的代碼。
我的主要目的是開頭說到的,做開篇所說的那樣的一個報表設計擴展。
如果有不熟悉的接口,請查閱MSDN。我根據自己的理解來論述,不恰當或錯誤之處歡迎批評指正。
Reporting Services Extension:File Share Data Processing Extension全程指南
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
