Reporting Service报表设计常见技巧及问题解法

1、 对Table中的详细内容,以不同的背景色间隔开相邻的两行:
A:选择Table的Detail行,选择属性中的BackgroundColor,值选择表达式,输入:=iif(RowNumber(Nothing) Mod 2, "White", "Beige")。组内设置不同底色则将Nothing改为相应的组名,如“Table1_Group1”;

2、仅在组的外边框设置线颜色的方法(纵向合并单元格):
A:设置BorderStyle-Bottom表达式为:=iif(RowNumber("Table1_Group1") = CountRows("Table1_Group1") , "White", "Beige");

3、报表常常需要用到参数起始日期和结束日期,并且需要将起始日期默认为本月第一天,结束日期默认为本月最后一天:
参数OccurDateFrom的默认值设置为表达式=DateAdd("d", 1-Day(Today), Today);参数OccurDateTo的默认值设置为表达式=DateAdd("d", -1, DateSerial(IIf(Month(Today)=12,Year(Today)+1,Year(Today)), IIf(Month(Today)=12,1,Month(Today)+1), 1))就能满足需求咯;

4、在同一张报表上显示数据报表和图表(如直方图),并且根据“显示直方图”参数切换:
新增参数IsShowChart(Boolean型),默认值=false;然后将报表(Table1)和图表(Chart1)的Location设置为一样;
Table1的Visibility.Hidden设置为表达式=Parameters!IsShowChart.Value;Chart1的Visibility.Hidden设置为表达式=Not Parameters!IsShowChart.Value就可以实现根据参数切换报表和图表了;

5、设置每页显示Table表头或表尾:
A:选择Table Header或Table Footer,将属性中的RepeatOnNewpage设为True;

6、在每页都显示放入的图片或标题头等信息:
A:只须在Table Header中加行数,把你要显示的内容放到单元格中,然后再按第 5 点方式设置后就可以了;

7、报表插入图片的方法:
A:需要将插入的图像报表项的Source属性设置为extern,且将Value设置文件全路径(且以file://打头),譬如:file://E:/VSTS/SSRS/ReportServiceClient/Wave.jpg;并且需设置reportViewer1.LocalReport.EnableExternalImages = true;

B:对于动态获取图片则需要将Source属性设置为DataBase,Value=System.Convert.FromBase64String(Fields!BarCode.Value),上面示例是按数据源的属性BarCode(string类型),类属性代码见下面:

 
  
public string BarCode
{
get
{
BarcodeLib.Barcode b
= new BarcodeLib.Barcode();
b.IncludeLabel
= true ;
Image img
= b.Encode(BarcodeLib.TYPE.CODE39, BillNo);
return Convert.ToBase64String(BitmapToBytes(img as Bitmap));
}
}
private byte [] BitmapToBytes(Bitmap Bitmap)
{
MemoryStream ms
= null ;
try
{
ms
= new MemoryStream();
Bitmap.Save(ms, ImageFormat.Gif);
byte [] byteImage = new Byte[ms.Length];
byteImage
= ms.ToArray();
return byteImage;
}
catch (ArgumentNullException ex)
{
throw ex;
}
finally
{
ms.Close();
}
}

8、获取参数列表的方法
首先添加web引用:http://server/reportserver/reportservice.asmx

         private  RS2005.ReportParameter[] GetReportParameters( string  url,  string  reportPath)
        {
            
// 获取参数的方法之二(不能获取元数据)
            RS2005.ReportingService rService  =   new  RS2005.ReportingService(); // 创建报表服务实例
            rService.Credentials  =  System.Net.CredentialCache.DefaultCredentials; // 设置默认系统凭据

            rService.Url 
=  url;
            
string  historyID  =   null ;
            
bool  forRendering  =   true ;
            RS2005.ParameterValue[] values 
=   null ;
            RS2005.DataSourceCredentials[] credentials 
=   null ;
            RS2005.ReportParameter[] parameters;
            parameters 
=  rService.GetReportParameters(reportPath, historyID, forRendering, values, credentials);
            
return  parameters;
        }

 

9、获取参数及其元数据(如参数的默认值表达式等):

private  Dictionary < string string >  GetReportParamtersDefaultValue( string  url,  string  reportPath)
{
    Report report 
=   null ;
    RS2005.ReportingService rService 
=   new  RS2005.ReportingService(); // 创建报表服务实例
    rService.Credentials  =  System.Net.CredentialCache.DefaultCredentials; // 设置默认系统凭据
    rService.Url  =  url;
    
byte [] bytes  =  rService.GetReportDefinition(reportPath);
    
if  (bytes  !=   null )
    {
        XmlSerializer serializer 
=   new  XmlSerializer( typeof (Report));
        
using  (MemoryStream stream  =   new  MemoryStream(bytes))
        {
            report 
=  (Report)serializer.Deserialize(stream);
        }
    }
    List
< ItemsChoiceType37 >  reportItems  =   new  List < ItemsChoiceType37 > (report.ItemsElementName);
    
int  index  =  reportItems.IndexOf(ItemsChoiceType37.ReportParameters);
    ReportParametersType parametersType 
=  report.Items[index]  as  ReportParametersType;
    Dictionary
< string string >  ps  =   new  Dictionary < string string > ();
    
foreach  (ReportParameterType item  in  parametersType.ReportParameter)
    {
        ps.Add(item.Name, 
string .Empty);

        List
< ItemsChoiceType33 >  rptItems  =   new  List < ItemsChoiceType33 > (item.ItemsElementName);
        index 
=  rptItems.IndexOf(ItemsChoiceType33.DefaultValue);
        DefaultValueType dvt 
=  item.Items[index]  as  DefaultValueType;

        ValuesType vt 
=  dvt.Items[ 0 as  ValuesType;
        ps[item.Name] 
=  vt.Value[ 0 ];
    }
    
return  ps;
}

 

10、遍历报表项的方法:
首先添加web引用:http://server/reportserver/reportservice.asmx

ReportingService rService  =   new  ReportingService(); // 创建报表服务实例
rService.Credentials  =  System.Net.CredentialCache.DefaultCredentials; // 默认系统凭据
CatalogItem[] catalogItems;
catalogItems 
=  rService.ListChildren( " / " true ); // 对根路径检索
foreach (CatalogItem item  in  catalogItems)
{
    
if (item.Type  == ItemTypeEnum.Folder)
  {
    
// 遍历报表文件夹
  }
}
 
foreach (CatalogItem item  in  catalogItems)
{
  
if (item.Type  == ItemTypeEnum.Report)
  {
    
// 遍历报表
  }
}

// 搜索报表
ReportService.SearchCondition[] condition = new  SearchCondition[ 1 ];
condition[
0 ] = new  SearchCondition();
condition[
0 ].Name  = " Name " ;
condition[
0 ].Value  = this .TextBox1.Text ;
catalogItems
= rs.FindItems ( " / " ,WebReportSample.ReportService .BooleanOperatorEnum .And ,condition);

// 发布报表
byte [] reportData;
System.IO .FileStream fs
= System.IO .File.OpenRead ( " c:\\Report1.rdl " );
reportData
= new   byte  [fs.Length ];
fs.Read (reportData,
0 ,fs.Length );
rs.CreateReport (
" New Report " , " / " , false ,reportData, null );

// 删除报表
rs.DeleteItem ( " 报表名称 " );

 11、子报表部署问题:
由于主报表中跳转到子报表或嵌入子报表时仅设置子报表名称,所以部署时必须确保子报表与主报表的路径一致;

12、使用LocalReport.LoadSubreportDefinition 方法应注意的问题是如果主报表是通过ReportPath属性获取的则该方法将失效,原因是设置ReportPath的报表通过文件系统获取报表定义元数据时也一并加载了它需要的子报表定义元数据。可以看看MSDN的备注,换言之,使用该方法前必须使用LocalReport.LoadReportDefinition 方法,且不能设置ReportPath。
原文描述如下:The ReportViewer control requires the definitions for all subreports before it can process a report. If the local report was loaded from the file system by specifying the ReportPath property, the ReportViewer control automatically loads the subreports from the file system. In cases where the local report was not loaded from the file system, these methods may be used to load report definitions for subreports.

13、报表的无会话打印问题,报表定义文件没有设置“打印方向”的属性,实际上如果需要打印横向报表需要在创建PrintDocument时设置打印机参数,并且读取deviecInfo信息时需要将报表定义文件的PageWidth和PageHeight互换下,参考代码如下:

public   class  EmfPrintDocument : PrintDocument
{
    
private  EmfPrintDocument(PrinterInfo printerInfo)
    {
        
base .PrinterSettings.PrinterName  =  printerInfo.PrinterName;
        
base .DefaultPageSettings.Landscape  =  printerInfo.Landscape;
        
base .PrinterSettings.DefaultPageSettings.Landscape  =  printerInfo.Landscape;
    }

        
public   static  EmfPrintDocument Create(PrinterInfo printerInfo)
        {
            
if  ( string .IsNullOrEmpty(printerInfo.PrinterName))
            {
                printerInfo.PrinterName 
=  Printer.GetDeaultPrinterName();
            }
            
else
            {
                
bool  founded  =   false ;

                
foreach  ( string  pname  in  PrinterSettings.InstalledPrinters)
                {
                    
if  (pname.Equals(printerInfo.PrinterName, StringComparison.CurrentCultureIgnoreCase))
                    {
                        printerInfo.PrinterName 
=  pname;
                        founded 
=   true ;
                        
break ;
                    }
                }

                
if  ( ! founded)
                {
                    
throw   new  NotSupportedException( string .Format( " 找不到打印机 {0} "   +  printerInfo.PrinterName));
                }
            }
            
return   new  EmfPrintDocument(printerInfo);
        }
}

ReportPrintService的代码:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;
using System.IO;
using System.Drawing.Printing;
using System.Drawing.Imaging;
using System.Xml;
using System.Xml.Serialization;
using JetSun.Presentation;
using JetSun.Core.Library.Reports;
using JetSun.Infrastructure;

namespace JetSun.Core.Library.Reports
{
    
internal class ReportPrintService : IDisposable
    {
        
private static IList<Stream> _streams;
        
private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
        {
            
//Stream stream = new FileStream(Application.StartupPath + @"\" + name + "." + fileNameExtension, FileMode.Create);
            Stream stream = new MemoryStream();
            _streams.Add(stream);
            
return stream;
        }

        
private void Export(LocalReport report)
        {
            
string deviceInfo = LoadDeviceInfo(report.ReportPath);
            Warning[] warnings;
            _streams 
= new List<Stream>();
            report.Render(
"Image", deviceInfo, CreateStream, out warnings);

            
foreach (Stream stream in _streams)
                stream.Position 
= 0;
        }

        
private List<ItemsChoiceType37> _reportItems;
        
private string LoadDeviceInfo(string reportPath)
        {
            XmlSerializer serializer 
= new XmlSerializer(typeof(Report));
            _report 
= (Report)serializer.Deserialize(this.GenerateRdlc(reportPath));
            _reportItems 
= new List<ItemsChoiceType37>(_report.ItemsElementName);

            
string deviceInfo =
              
"<DeviceInfo>" +
              
"  <OutputFormat>EMF</OutputFormat>" +
              
"  <PageWidth>" + (_printerInfo.Landscape ? GetReportItem(ItemsChoiceType37.PageHeight) : GetReportItem(ItemsChoiceType37.PageWidth)) + "</PageWidth>" +
              
"  <PageHeight>" + (_printerInfo.Landscape ? GetReportItem(ItemsChoiceType37.PageWidth) : GetReportItem(ItemsChoiceType37.PageHeight)) + "</PageHeight>" +
              
"  <MarginTop>" + GetReportItem(ItemsChoiceType37.TopMargin) + "</MarginTop>" +
              
"  <MarginLeft>" + GetReportItem(ItemsChoiceType37.LeftMargin) + "</MarginLeft>" +
              
"  <MarginRight>" + GetReportItem(ItemsChoiceType37.RightMargin) + "</MarginRight>" +
              
"  <MarginBottom>" + GetReportItem(ItemsChoiceType37.BottomMargin) + "</MarginBottom>" +
              
"</DeviceInfo>";

            
//_printDoc.PrinterSettings.PrinterName = _printerInfo.PrinterName;
            
//_printDoc.DefaultPageSettings.Landscape = _printerInfo.Landscape;
            
//_printDoc.PrinterSettings.DefaultPageSettings.Landscape = _printerInfo.Landscape;

            
return deviceInfo;
        }

        
private MemoryStream GenerateRdlc(string reportPath)
        {
            XmlDocument sourceDoc 
= new XmlDocument();
            sourceDoc.Load(reportPath);

            MemoryStream ms 
= new MemoryStream();
            XmlSerializer serializer 
= new XmlSerializer(typeof(XmlDocument));
            serializer.Serialize(ms, sourceDoc);
            ms.Position 
= 0;
            
return ms;
        }

        
private string GetReportItem(ItemsChoiceType37 element)
        {
            
int ix = _reportItems.IndexOf(element);
            
if (ix == -1return "0.0cm";

            
return _report.Items[ix].ToString();
        }

        
private void PrintPage(object sender, PrintPageEventArgs ev)
        {
            Metafile pageImage 
= new Metafile(_streams[_currentPageIndex]);
            ev.Graphics.DrawImage(pageImage, ev.PageBounds);

            _currentPageIndex
++;
            ev.HasMorePages 
= (_currentPageIndex < _streams.Count);
        }

        
private int _currentPageIndex;
        
private void DoPrint()
        {
            
if (_streams == null || _streams.Count == 0)
                
return;

            _currentPageIndex 
= 0;
            _printDoc.PrintPage 
+= new PrintPageEventHandler(PrintPage);
            _printDoc.Print();
        }

        
private Report _report;
        
private EmfPrintDocument _printDoc;
        
private PrinterInfo _printerInfo;
        
public void Print(LocalReport report, PrinterInfo printerInfo)
        {
            _printDoc 
= EmfPrintDocument.Create(printerInfo);
            _printerInfo 
= printerInfo;

            Export(report);

            DoPrint();
        }

        
public void Dispose()
        {
            
if (_streams != null)
            {
                
foreach (Stream stream in _streams)
                    stream.Close();
                _streams 
= null;
            }
        }
    }
}

使用实例:

ContractedBlock.gif ExpandedBlockStart.gif Code
using (ReportPrintService rps = new ReportPrintService())
{
    rps.Print(lp, printerInfo);
}

14、服务器报表的方法SetParameters() 需要注意的问题:
(1)多值参数的类型是StringCollection而不是一个用逗号间隔的串;
(2)传入的参数值如果在服务器报表的参数数据源中不存在该方法将报错(报表的所有参数赋默认值);
(3)ReportViewer控件使用过程中如果发现展现出来的报表背景色全部变成了黑色,则需要将承载该控件的WindowsFormsHost设置其Background属性设置为White;
(4)导出pdf时可能遇到导出的内容为????,需要修改下字体为“宋体”或其他基本字体;如果报表包含子报表则子报表无法导出内容;

 

转载于:https://www.cnblogs.com/chriskwok/archive/2009/09/17/1568173.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值