在Detail的事件中:

int i=0;
private void OnBeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) {
   //控制每页报表显示的条数
if (i!=0&&i%8==0) //每页显示8条
{
  Detail.PageBreak = DevExpress.XtraReports.UI.PageBreak.BeforeBand;  
}
else
{
  Detail.PageBreak = DevExpress.XtraReports.UI.PageBreak.None;   
}
i++;
}

在Table的事件中:

private void OnBeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) {
  //////////////////////////////////////////////////数据集“StorageBillMatItem”进行替换即可
 if(i==((System.Data.DataSet)(xtraReport1.DataSource)).Tables["StorageBillMatItem"].Rows.Count)
   {
      XRTable table = xrTable2;//Template Detail Band XRTable
      int iheight = table.Rows[table.Rows.Count - 1].Height;

int SpaceRowCount = 8-(i)%8;
      XRTableRow[] xrRow = new XRTableRow[SpaceRowCount];

for(int k=0;k<SpaceRowCount ;k++)
        {
            xrRow[k] = new XRTableRow();
            xrRow[k].Size = new Size(table.Width, iheight);
            xrRow[k].Location = new Point(table.Location.X, k * iheight);
            xrRow[k].Borders = (DevExpress.XtraPrinting.BorderSide)((BorderSide.Left | BorderSide.Right) | BorderSide.Top);
            xrRow[k].BorderWidth = 1;
            xrRow[k].BorderColor = table.Rows[table.Rows.Count - 1].BorderColor;
            //CreateCell
            XRTableRow row = table.Rows[table.Rows.Count - 1];
            CreateCellArray(xrRow[k], row);
       } 
      xrTable2.Rows.AddRange(xrRow); 
   }  
}

/// <summary>
/// CreateCell
/// </summary>
/// <param name="xrRow">Current Row</param>
/// <param name="xrRowTemplate">Row Template</param>
private void CreateCellArray(XRTableRow xrRow, XRTableRow xrRowTemplate)
{
    int Xmargin = 0;
    for (int i = 0; i < xrRowTemplate.Cells.Count; i++)
    {
        XRTableCell xrcell = new XRTableCell();
        xrcell.BorderWidth = 1;
        xrcell.Borders = (DevExpress.XtraPrinting.BorderSide)((BorderSide.Left | BorderSide.Right) | BorderSide.Top);
        xrcell.Width = xrRowTemplate.Cells[i].Width;
        xrcell.BackColor = xrRowTemplate.Cells[i].BackColor;
        xrcell.Height = xrRowTemplate.Height;
        if (i != 0)
        {
            xrcell.Location = new Point(Convert.ToInt32(Xmargin + xrRowTemplate.Cells[i].Width), 0);
        }
        else
        {
            xrcell.Location = new Point(0, 0);
        }
        xrRow.Cells.Add(xrcell);
    }
}

http://www.dxper.net/documents/html/DevExpressXtraReportsUIXtraReport_ScriptLanguagetopic.htm

我觉得首先需要了解打印的一些常识和DevExpress.XtraReports的打印逻辑:
      1.PageHeader和PageFooter高度是固定的,Detail高度是变的,所以嵌套的数据源一般放到Detail中;
      2.报表的分页按照两个原则:首先最外层的是根据Report的数据源的RowChanged,内层是根据数据源的每个Row的填充结果,如果数据填满整个页还没打印完,就会分页打印到下一页;

然后就说一下套打。套打比较麻烦的是单据内数据的定位,假如有N张报表,每张报表上又需要N个控件,通过打印测试比对修改的方式肯定行不通,在XtraReports中可以通过加背景图片的方式定位控件,分几个步骤:
      1.将所有单据报表按1:1扫描;
      2.在一张空的报表中拖入一个XRPictureBox控件,设置控件的Image属性为任一张报表图片,设置Sizing属性为ZoomImage,并将控件占满整个报表;
      3.打印测试比对,直到打印出的图片和实际单据完全一致,通过图片的长宽属性和XRPictureBox控件的长宽属性计算出比值;
      4.将3中计算出的比值应用到其他报表扫描图片上,再将图片作为报表背景定位各个数据控件的位置。

下面举一个我做的单据中一个比较复杂一点的例子,如下图:

这张单据的难点首先是存在两个高度不确定的部分:“托运人提供详细情况”和“运费与附加费”。这两部分的数据分别存在单独的表中,记录数不定。对于这种情况,为了使整体结构清晰,我一般把不确定的部分放到SubReport中。我尝试放了两个SubReport,然而XtraReports的打印逻辑是先打印完上面的SubReport然后才打印下面的SubReport,和单据情况不符,失败。(不知这种情况谁有比较好的解决方案)问题无法解决,我又分析了一下需求,问了客户的情况,了解到"运费与附加费"记录数很少,一般两三条,最多也不会到引起分页的地步,我调整了一下,把下面的SubReport改为包含6个Row的固定高度的XtrTable,并将“集装箱数或件数合计”一下全部并入PageFooter,问题一解决。

不久客户说红框框中的部分放一个主表的字段,是一个多行文本,且print per page,所以红框框中这部分不能放在SubReport中了,放在外面,因为在Report中SubReport没有Left属性(SubReport都是从Report的最左边开始打印),SubReport也不能用了,最后只好放了一个XtrTable,只包含一个Row,然后根据记录数在BeforePrint事件中动态添加Row。到这里整张单据基本完成了。

 
 

 
代码:
int i=0;
private void OnBeforePrint1(object sender, System.Drawing.Printing.PrintEventArgs e) {
   //控制每页报表显示的条数
if (i!=0&&i%19==0) //每页显示19条
{
  Detail.PageBreak = DevExpress.XtraReports.UI.PageBreak.BeforeBand;  
}
else
{
  Detail.PageBreak = DevExpress.XtraReports.UI.PageBreak.None;   
}
i++;
}

private void OnBeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) {
  
      Purchaseordersheet obj = (Purchaseordersheet)Report1.GetCurrentRow();
           //定义采购申请        
     //  Purchaserequisition ent;
     //     获取当前采购申请的行数
     // ent=(Purchaserequisition)Detail   Report.GetCurrentRow(); obj .Purchaserequisitions.Count
     //判断变量是否等于采购申请的行数
      if(i==obj.Purchaserequisitions.Count&& i<19)   {
      XRTable table = table1;//Template Detail Band XRTable
      //int iheight = table.Rows[table.Rows.Count-1].Height;
int iheight = table.Rows[0].Height;
      int SpaceRowCount = 19-(i)%19;
      XRTableRow[] xrRow = new XRTableRow[SpaceRowCount];
    
      for(int k=0;k<SpaceRowCount ;k++)
        {
            xrRow[k] = new XRTableRow();
            xrRow[k].Size = new Size(table.Width, iheight);
            xrRow[k].Location = new Point(table.Location.X, k * iheight);
            xrRow[k].Borders = (DevExpress.XtraPrinting.BorderSide)((BorderSide.Left | BorderSide.Right) | BorderSide.Top);
            xrRow[k].BorderWidth = 1;
            xrRow[k].BorderColor = table.Rows[table.Rows.Count - 1].BorderColor;
                     
            //CreateCell
            XRTableRow row = table.Rows[table.Rows.Count - 1];
            CreateCellArray(xrRow[k], row);
       } 
            table.Rows.AddRange(xrRow); 
   }  
}

/// <summary>
/// CreateCell
/// </summary>
/// <param name="xrRow">Current Row</param>
/// <param name="xrRowTemplate">Row Template</param>
private void CreateCellArray(XRTableRow xrRow, XRTableRow xrRowTemplate)
{
        int Xmargin = 0;
        for (int i = 0; i < xrRowTemplate.Cells.Count; i++)
       {
        XRTableCell xrcell = new XRTableCell();      
        xrcell.BorderWidth = 1;
        xrcell.Borders = (DevExpress.XtraPrinting.BorderSide)((BorderSide.Left | BorderSide.Right) | BorderSide.Top);
        xrcell.Width = xrRowTemplate.Cells.Width;
        xrcell.BackColor = xrRowTemplate.Cells.BackColor;
        //xrcell.Height =xrRowTemplate.Height;
       //xrcell.BackColor = Color.Red;
       
        xrcell.Text = " ";
        xrcell.Font = new System.Drawing.Font("宋体", 9.75F);
           if (i != 0)
        {
            xrcell.Location = new Point(Convert.ToInt32(Xmargin + xrRowTemplate.Cells.Width), 0);
        }
        else
        {
            xrcell.Location = new Point(0, 0);
        }
        xrRow.Cells.Add(xrcell);
    }
}

这是一个报表下明细的条目,为什么补出来的空格与我设置的不一样

 

本帖最后由 badboy518 于 2013-1-26 13:06 编辑

目测了一下楼主的报表,我觉得可能存在两个问题:

1.报表中如果要设置空行,根本不用指定每页有多少行,这是笨办法。正确的做法是添加区段(比如页脚,这样会产生每页固定高度的页脚),用区段来控制每页报表的行数、位置。
  宜采用 FillEmptySpace 事件来处理
2.报表的单元格线条问题,看上去像是重合的,是因为你将报表格都设定四周都有,这种方法也是不正确的,建议多看一下自带的示例

另外,你可以参考一下我发的示例 http://smartsoft.5d6d.net/thread-15200-1-1.html

这个是没有指定每页有多少行的,一样达到了目的,并且更加灵活。你只要把分组 GroupFooter 拉长一点,就达到你想要的目的了

xtrareport实现指定记录数以及填补空白行(网上整理)的更多相关文章

  1. 查看Oracle表中的指定记录在数据文件中的位置

    查看Oracle表中的指定记录位置select rowid,user_id from sshr.xx_user where user_id=3010586 select rowid,       db ...

  2. Core Data 更新某条指定记录数据

    一:流程 同样需要先查询出指定记录 更新指定记录 二:代码: //更新操作 - (void)updateThePersonData { NSFetchRequest *fetchRequest = [ ...

  3. 在DataTable和DataView中查找指定记录

    一.在DataTable中查找 1. 使用Select方法查找没有主键的表DataTable的Select方法返回一个DataRow数组,有四个重载的函数. DataRow[] drs = dt.Se ...

  4. [Mysql 查询语句]——查询指定记录

    #比较 等于; 大于; 小于; 小于或等于; 大于或等于; 不等于; 排除掉; #指定范围查询 BETWEEN IN ; ; #指定集合查询 IN ,); ,); 集合元素可以是字符串类型 selec ...

  5. Core Data 删除某条指定记录的数据

    一:操作流程 先查询得到某条要删除的数据 然后删除某记录 二:演示代码 //删除 - (void)deleteThePersonData { NSFetchRequest *fetchRequest ...

  6. ThinkPHP与EasyUI整合之三(searchbox):在datagrid中查询指定记录

    在datagrid中toolbar添加searchbox查询框,根据列范围查询数据,先看效果图: 1. searchbox采用easyui的Demo例子,再加以js扩展,根据datagrid中的列数据 ...

  7. 在MAC下使用Robotframework+Selenium2【第二枪】如何处理Table点击指定记录

    1.通过关键字Get Matching Xpath Count获取table中的记录 2.遍历Table所有记录 3.判断记录是否符合条件,做点击操作

  8. order by按照指定记录排序

    //按照id降序 并把name是小黑的排在最后SELECT * from dms_student order by name not like '小黑' desc,id desc; //按照id降序 ...

  9. nginx不记录指定文件类型的日志

    1.指定记录文件日志记录的内容. vim /usr/local/nginx/conf/nginx.conf如下部分: log_format dd '$remote_addr $http_x_forwa ...

随机推荐

  1. 自己用c语言实现字符串处理库函数以及扩展

    1.实现基本的c语言库函数: int myStrlen( const char* str);//根据传入的字符串首地址获取字符串长度:返回值为长度 int myStrlen(const char* s ...

  2. sax/dom/jdom/dom4j的区别

    sax/dom/jdom/dom4j的区别[转] 博客分类: xml   网上能够查到很多的4种解析方式的区别,我再做一下摘录和总结,顺带给自己做个备份. SAX sax分析器在对xml文档进行分析时 ...

  3. 修复HTTP 503错误

    要解决此问题,按照下列步骤操作: 1.验证是否已为虚拟服务器配置了应用程序池.默认的应用程序池是MSSharePointPortalAppPool. 请按照下列步骤来确定虚拟服务器正在使用的应用程序池 ...

  4. 读艾伦的jQuery的无new构建,疑惑分析——jquery源码学习一

    背景: 有心学习jquery源码,苦于自己水平有限,若自己研究,耗时耗力,且读懂之日无期. 所以,网上寻找高手的源码分析.再经过自己思考,整理,验证.以求有所收获. 此篇为读高手艾伦<jQuer ...

  5. Python全栈开发 线程和进程

    一.线程 线程是程序工作的最小单元,由进程生成,生成的线程间会共享内存空间.Python中创建线程比较简单,导入threading模块,创建线程实例.下面这段代码是一个简单的多线程例子 import ...

  6. android开发--下载图片

    1.背景介绍 网络上图片的请求,是我们最常见的网络请求之一,不亚于对json/xml数据的请求.一般要展示给用户看的,都不会是纯粹的文字,往往都是图文信息.而在移动互联网时代,图文又往往需要最新的资讯 ...

  7. java学习第15天(Linklist Vector)

    根据集合的分类(上一天有说),首先接触的是ArrayList但是和Collection一样,他没有什么特殊的功能,直接跳过,然后是Vector. 一   Vector A:有特有功能 a:添加 pub ...

  8. 初学python之urllib

    urllib.request urlopen()urllib.urlopen(url, data, proxies) :创建一个表示远程url的类文件对象,然后像本地文件一样操作这个类文件对象来获取远 ...

  9. PowerDesigner 逆向中 Name和Comment互换

    在使用PowerDesigner对数据库进行概念模型和物理模型设计时,一般在NAME或Comment中写中文,在Code中写英文.Name用来显 示,Code在代码中使用,但Comment中的文字会保 ...

  10. Mysql存储过程调用

    mysql存储过程实例教程 发布时间:2014-04-09编辑:JB01 这篇文章主要介绍了mysql存储过程的使用方法,mysql存储过程实例教程,有需要的朋友参考下.   1.1create  p ...