微軟的Reporting Services逐漸被大眾熟悉并接受。以前做過(guò)Reporting Services的項(xiàng)目,但是總結(jié)的不多。最近看到越多越多的報(bào)表項(xiàng)目是用Reporting Services來(lái)做,走出去看看才知道別人在做什么。
今天要涉及到的主題是Reporting Services Extension,報(bào)表擴(kuò)展。其實(shí)我是要搭建一個(gè)報(bào)表設(shè)計(jì),開(kāi)發(fā)的工具箱。在以前的一篇文章中,提到過(guò)用Reporting Services+Remoting做的報(bào)表設(shè)計(jì)平臺(tái)。Remoting客戶端向服務(wù)器發(fā)送SQL語(yǔ)句,其實(shí)不是SQL語(yǔ)句,準(zhǔn)確說(shuō)是類似如下的語(yǔ)句:程序集;類;方法 把這個(gè)查詢語(yǔ)句發(fā)送到Remoting服務(wù)器,服務(wù)器在GAC中去找對(duì)應(yīng)的程序集和方法,反射調(diào)用之,返回?cái)?shù)據(jù)集給報(bào)表設(shè)計(jì)器。這種結(jié)構(gòu)的報(bào)表設(shè)計(jì)靈活性很強(qiáng)。特別是一些計(jì)算,字符串方面的處理,用SQL語(yǔ)句可能不方便,要寫很多的T_SQL代碼。但是如果用這種方法,充分發(fā)揮程序語(yǔ)言(C#)和數(shù)據(jù)庫(kù)語(yǔ)言(T_SQL)的長(zhǎng)處,把集合運(yùn)算部分用T_SQL來(lái)處理,計(jì)算和字符文本的處理則留在C#代碼中。
萬(wàn)丈高樓平地起,要做這樣一個(gè)擴(kuò)展,需要先熟悉Reporting Services提供了哪些可以擴(kuò)展的方面。
如果您看過(guò)微軟的例子,它提供了下面幾個(gè)主要的例子(Extension Samples)
FormsAuthentication Sample 擴(kuò)展報(bào)表服務(wù)器的驗(yàn)證方式
FsiDataExtension Sample? 數(shù)據(jù)處理擴(kuò)展
PolygonsCustomReportItem? 自定義報(bào)表項(xiàng)
PrinterDelivery Sample? 打印傳送擴(kuò)展
我主要關(guān)注的是FsiDataExtension ,它的位置在
C:\Program Files\Microsoft SQL Server\90\Samples\Reporting Services\Extension Samples
代碼結(jié)構(gòu)如下圖
這里面有幾個(gè)主要的類:Connection,Command,DataParameter,DataReader,Transaction。
看到這幾個(gè)類,您可能會(huì)心的一笑,這不就是ADO.NET的結(jié)構(gòu)嗎?
編譯這個(gè)例子,生成程序集Microsoft.Samples.ReportingServices.FsiDataExtension.dll
部署這個(gè)例子
1)拷貝文件到報(bào)表服務(wù)器和設(shè)計(jì)器中,把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"/>
為了支持報(bào)表設(shè)計(jì)器,修改RSReportDesigner.config 的Designer元素,添加
<Extension Name="FSI" Type="Microsoft.ReportingServices.QueryDesigners.VDTQueryDesigner,
Microsoft.ReportingServices.QueryDesigners"/>
3)配置代碼訪問(wèn)安全性
修改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
添加一個(gè)CodeGroup 元素,內(nèi)容如下
<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>
不需要重啟動(dòng)電腦,打開(kāi)Visual Studio 2005 BIDS,新建一個(gè)Reporting Services項(xiàng)目
?
從圖中看到,數(shù)據(jù)源中有File Share Information,選擇它作為報(bào)表的數(shù)據(jù)源
新建數(shù)據(jù)集,輸入查詢字符串
\\XX-PCName\\2010
,XX-PCName是計(jì)算機(jī)的名字
這個(gè)擴(kuò)展的目的是讀取某臺(tái)計(jì)算機(jī)的共享文件夾中的信息,作為數(shù)據(jù)集的內(nèi)容。
執(zhí)行這個(gè)數(shù)據(jù)集,得到的結(jié)果如下
設(shè)計(jì)報(bào)表,使用Table控件
預(yù)覽報(bào)表,結(jié)果如預(yù)期所示
?
雖然這個(gè)擴(kuò)展沒(méi)有多大的意義,但是它展示了如何去擴(kuò)展Reporting Services的Data Process。
下面再來(lái)看看,F(xiàn)siDataExtension項(xiàng)目的代碼結(jié)構(gòu)
再看看類圖,大概了解有多少個(gè)類相互協(xié)作
再到代碼里面看看,各自的關(guān)系
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,實(shí)現(xiàn)它的接口
運(yùn)用熟悉的ADO.NET的知識(shí),打開(kāi)IDbConnection接口
?
IDbCommand的結(jié)構(gòu)如下
?
通過(guò)代碼中的注釋,一個(gè)查詢語(yǔ)句傳進(jìn)來(lái),它的流程應(yīng)該是這樣的
1)連接類型是FsiConnection,它是個(gè)空連接,不需要傳入任何連接字符串。
因?yàn)闄?quán)限的原因,設(shè)置當(dāng)前連接主體WindowsIdentity
2)引擎根據(jù)查詢代碼和連接類型,調(diào)用如下構(gòu)造方法
public FsiCommand(string cmdText, FsiConnection connection)? {
??????? m_cmdText = cmdText;?????? m_connection = connection;????
? }
最主要的還是IDbCommand.ExecuteReader(CommandBehavior behavior),它是執(zhí)行查詢命令的主要地方,它調(diào)用FsiDataReader,讀取數(shù)據(jù)記錄
reader = new FsiDataReader(m_cmdText);
reader.GetDirectory(m_cmdText);
進(jìn)入數(shù)據(jù)讀取類,它的讀取代碼如下
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];
它有一個(gè)方法,根據(jù)傳入的查詢字符串,讀取目錄信息
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();
}
這樣,借助于這些方法和接口,F(xiàn)si DataExtension Sample就可以部署到Reporting Services中,供報(bào)表設(shè)計(jì)和運(yùn)行時(shí)使用。更多的細(xì)節(jié)請(qǐng)查看具體的代碼。
我的主要目的是開(kāi)頭說(shuō)到的,做開(kāi)篇所說(shuō)的那樣的一個(gè)報(bào)表設(shè)計(jì)擴(kuò)展。
如果有不熟悉的接口,請(qǐng)查閱MSDN。我根據(jù)自己的理解來(lái)論述,不恰當(dāng)或錯(cuò)誤之處歡迎批評(píng)指正。
Reporting Services Extension:File Share Data Processing Extension全程指南
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

