小弟初用delphi作项目,设计的报表需要加上表格线,如果使用Qreport该怎么设置
或者给小弟推荐几个比较好的报表控件,不胜感谢

解决方案 »

  1.   

    两种方式:
       1. 字段分割线可以用QRShape,在Shape属性中选择对应的线状态即可
       2. DetailBand.Frame.DrawBottom, DrawLeft,DrawRight,DrawTop设置为true,可以加上下左右线,同样的其他的Bands也有这些属性
      

  2.   

    qrshape也可以设置为竖线,将qrshape的shape设置为qrsVertLine
      

  3.   

    我设置了,但是有一些问题,如果把DetailBand.Frame的DrawBottom,rawTop都设置位true那么表线肯定又重复画的,先很粗。如果只设置其中的一个为true则表线画得不全,很是奇怪,请各位仁兄指教
      

  4.   

    用底图啊,可以做套表的呵呵,打过发票吗?
    我们就是用底图做的。
    QReport.picture
      

  5.   

    就用QRshape, shape属性设为矩形,height设小为横线,Width设小为竖线,但是打印出来的线中间有细小的缝隙,因为是作为矩形打印的,还要将Brush.Color设为clBlack,这样打印出来的线形就是填实的.
      

  6.   

    小弟没有使用过底图,没做过套表,支票值类的,第一次使用delphi作项目,且时间紧迫。
    就请“青山情”为小弟解释详细一点怎么用,小弟将非常感谢各位大哥,我对QReport做的报表没有信心,能做出漂亮的统计报表吗?
      

  7.   

    gyx10311(fbi) ,您讲得我不太明白,怎么会是height设小为横线,width设小为竖线呢
      

  8.   

    FastReport好用吗?我从网上当了一个cell组件来做,感觉挺爽的,但是这个组件是收费的
      

  9.   

    QReport.picture支持很多种图形格式(BMP, Jpeg, wmf, emf...)
    所以,你可以先用绘图软件做出表格线,然后再load到Picture中.当然,一般这样的图形文件就比较大.
    所以最好用图元文件(wmf, emf)做表格线呢, 一般我们习惯用Word...怎么做成emf呢?
    我有一个工具http://sky8077.vip.sina.com/Doc2Emf.exe可以帮你把Word文件转成Emf文件,然后就可以用了...
      

  10.   

    我给你一篇好文章,你仔细学一下,我的报表加网格线就是从这儿学会的,文章全文如下:在Delphi中实现数据分析模块的动态报表 
    重庆 张仁平、双海军、卜淮原 
    一、问题的提出 
    ---- Delphi作为强大的数据库开发工具,正被愈来愈多的编程人员所采用,"聪明的程序员用Delphi"更形象生动的道出广大程序员的心声,但这并不意味着所有功能的实现都非常容易,例如,笔者在开发军队的某个信息系统中,就在为数据分析模块中DecisionGrid1控件的数据进行报表输出时走了不少的弯路。广大的Delphi的爱好者在今后的学习或工作中也有可能会遇到类似的问题,而在许多参考书中,很少有甚至没有关于它们的解决方法,于是,我想花费一点时间把它整理出来,以供大家参考。本文中报表动态生成的公用模块具有很大的灵活性和易操作性,其中的思路、实现的功能和通用性等方面的优缺点就由大家看了本文后自有定论。 
    二、建立报表的动态输出公用模块 
    ---- 下面,结合公司人事管理信息系统说明其实现的方法和技术。 
    ---- 1、基本思路:首先从DecisionGrid1中获得报表所需数据,放到二维数组PA中,然后在C:\DataWork中动态创建一个数据表tjb.dbf,存放报表数据,最后用T able1与tjb.dbf相连接,以后工作就与一般的动态输出报表(如查询报表)相类似,在这里我就无须赘述了。 
    ---- 2、建立窗体文件:放入六个用于数据分析的常用控件DecisionQuery1、DecisionSource1、DecisionCube1、DecisionGraph1、DecisionPivot1、DecisionGrid1,设置DecisionSource1的decisionCube属性为decisionCube1,decisionCube1的Dataset属性为decisionQuery1、decisionQuery1的DatabaseName属性为c:\datawork;一个Table1控件,用于连接数据表tjb.dbf;一个QuickRep1控件,用于数据的报表输出;两个Button1和Button2控件,其Caption分别设为"报表输出"和"返回"。分别设置decisionCube1的Dataset属性为decisionQuery1、decisionQuery1的DatabaseName属性为c:\datawork.。 
    ---- 3、单元文件的主要控件代码 Button1控件的代码如下(定义变量部分略),主要分以下8个功能块来加以说明: 
    ---- ⑴删除同名或上一次建立的数据表 
    if FileExists('c:\DataWork\tjb.dbf') then
      deletefile('c:\ DataWork \tjb.dbf');
    ---- ⑵根据DecisionGrid1控件的cells属性,获得报表所需数据,并将其默认的'Sum'值汉化成'总计'、'合计'、'小计'以符合汉语的习惯要求,所求得的数据存放于二维数组PA中 
    for i:=1-DecisionGrid1.FixedCols to DecisionGrid1.
    ColCount-DecisionGrid1.FixedCols-1 do
    for j:=0-DecisionGrid1.FixedRows to DecisionGrid1.
    RowCount-DecisionGrid1.FixedRows-1 do
        begin
    pa[i,j]:=DecisionGrid1.cells[i,j];
    //处理DecisionGrid1控件中固定列的值为'Sum'的数据项
    if ((i=1-DecisionGrid1.fixedcols) and (pa[i,j]='Sum')) then
        pa[i,j]:='总  计'
      else if ((i = -1) and (pa[i,j]='Sum')) then
        pa[i,j]:='小  计'
        else if ((i<-1) and (i>1-DecisionGrid1
    .FixedCols) and (pa[i,j]='Sum')) then
          pa[i,j]:='合  计';
    //处理DecisionGrid1控件中固定行的值为'Sum'的数据项
      if (pa[i,j]='Sum' ) and (j=-1) then
    pa[i,j]:='总   计';
    end;
    ---- ⑶用T able1动态创建数据表tjb.dbf 
    Table1.Active:=false;
    with Table1 do
    begin
       DatabaseName := 'c:\DataWork';
       TableName := 'tjb';
       TableType := ttDBase;
       with FieldDefs do
         begin
         Clear;
        for i:=1 to 40 do
          Add(IntToStr(i),ftString,30, False);
         end;
       CreateTable;
    end;
    //下面将DecisionGrid1控件中的数据放入数据表中
    Table1.Active:=true;
    for j:=1-DecisionGrid1.FixedRows to DecisionGrid1.RowCount-DecisionGrid1.FixedRows-1 do
      begin
      K:=0;
      Table1.Insert;
    for i:=1-DecisionGrid1.FixedCols to DecisionGrid1.ColCount-DecisionGrid1.FixedCols-1 do
        begin
        Table1.Fields[K].AsString:=pa[i,j];
        K:=K+1;
        end;
      Table1.Post;
      Table1.Next;
      end;
    ---- ⑷下面代码确定输出报表的每列宽度 
    SetLength(M,DecisionGrid1.ColCount);//动态设置数组
    copy(M,1-DecisionGrid1.FixedCols,DecisionGrid1.ColCount-DecisionGrid1.FixedCols-1);
    //重新设置动态数组的起始位置
    for i:=1-DecisionGrid1.FixedCols to DecisionGrid1.ColCount-DecisionGrid1.FixedCols-1 do
       begin
       M[i]:=0;
    for j:=1-DecisionGrid1.FixedRows to DecisionGrid1.RowCount-DecisionGrid1.FixedRows-1 do
       IF M[i]< Length (Trim (PA[I,J]))*8 THEN  M[i]:= Length (Trim (PA[I,J]))*8;
       end;
    ---- ⑸如果要求输出报表的列宽相同(除DecisionGrid1控件的固定列,下同),可将数据项的最大列宽作为输出报表的列度,如果不要求,可跳过下面代码 
    max:=0;
    for i:=0 to DecisionGrid1.ColCount
    -DecisionGrid1.FixedCols-1 do
       if m[i]>max then   max:=m[i];
    for i:=0 to DecisionGrid1.ColCount-DecisionGrid1.FixedCols-1 do
       m[i]:=max;
    ZK:=0;//报表总宽
    for i:=1-DecisionGrid1.FixedCols to DecisionGrid1
    .ColCount-DecisionGrid1.FixedCols-1 do
      ZK:=ZK+M[i]+1;
    ---- ⑹判断报表的宽度,超宽?横向报表?还是纵向报表? 
    if ZK>1123 then
       begin
    Application.MessageBox('报表超宽,
    请调整再输出!','警告', 1);//输出对话框
       exit;
       end
    else if ZK>794 then
      QuickRep.Page.Orientation:=poLandscape //横向
      else
    QuickRep.Page.Orientation:=poPortrait;//纵向

    ---- ⑺以下代码完成了动态数据报表,与一般的动态输出报表功能相类似, 
    for i:=1 to QuickRep.Bands.TitleBand.
    ControlCount DO//取消系统对控件的控制,下同
       QuickRep.Bands.TitleBand.RemoveControl
       (QuickRep.Bands.TitleBand.Controls[0]);
    for i:=1 to QuickRep.Bands.DetailBand.ControlCount DO
      QuickRep.Bands.DetailBand.RemoveControl
      (QuickRep.Bands.DetailBand.Controls[0]);
    SetLength(QRShape,DecisionGrid1.ColCount); //动态设置数组
    SetLength(QRDBText, DecisionGrid1.ColCount); //动态设置数组
    K:=0;//动态生成对象的数,
    Lx:=(QuickRep.Width-ZK)DIV 2;//生成对象的左坐标
    //报表的动态生成
    For j:=1-DecisionGrid1.FixedCols to DecisionGrid1.ColCount-DecisionGrid1.FixedCols-1 do
       begin
       QRShape[K]:=TQRSHAPE.Create(tj1);//自定义对象的创建(下同)
       QRShape[K].Parent:=QuickRep.Bands.DetailBand;// 自定义对象的父类对象(下同)
       QRDBText[K]:=TQRDBText.Create(tj1);
       QRDBText[K].parent :=QuickRep.Bands.DetailBand;
       QRShape[K].LEFT:=Lx;//生成对象的左坐标
       QRShape[K].WIDTH:=M[J]+2; //生成对象的宽度
       QRShape[K].HEIGHT:=QuickRep.Bands.DetailBand.Height+1; //生成对象的高度
       QRShape[K].TOP:=-1; //生成对象的纵坐标
     QRDBText[K].WIDTH:=QRShape[K].WIDTH-10;
       QRDBText[K].Left :=QRShape[K].LEFT+1;
       QRDBText[K].HEIGHT:=QRShape[K].Height div 2;
       QRDBText[K].Top :=QRDBText[K].Height div 2+QRShape[K].Top;
       QRDBText[K].AutoSize:=false;
       QRDBText[K].Alignment:=taCenter; //生成对象居中
       QRDBText[K].DataSet:=Table1;
       QRDBText[K].DataField:=IntToStr(k+1);
       Lx:=Lx+M[J]+1;
       Inc(k);
       end;
    //动态生成报表的标题 
    Caption := TQRLabel.Create(tj1);
    Caption.Parent := QuickRep.Bands.TitleBand;
    Caption.Alignment:=taCenter;//标题居中
    Caption.Width:= Length (Trim (ptitle))*8; //标题的宽度
    Caption.Left:=(QuickRep.Width- Length (Trim (ptitle))*8)div 2; //标题的左坐标
    Caption.Height:=QuickRep.Bands.TitleBand.Height-1; //标题的高度
    Caption.Top:= 0;
    Caption.Caption:=ptitle; //标题的名称
    ,ptitle为调用该公用模块时的输入参数
    QuickRep.DataSet:=Table1;
    QuickRep.Preview;
    ⑻动态生成对象的内存释放
    k:=0;
    for j:=1-DecisionGrid1.FixedCols to DecisionGrid1
    .ColCount-DecisionGrid1.FixedCols-1 do
       begin
       QRShape[K].Free;
       QRDBText[K].Free;
       inc(k);
       end;
    Caption.Free;
    Table1.Active:=false;//关闭数据表
    end;
    ---- 以上程序是在Delphi 4.0中调试通过,其数据文件应放在C:\DataWork,类型为DB或DBF。 
    三、应注意以下几个问题 
    ---- 1、QuickRep1的Bands中的HasColumnHeader、HasDetail、HasTitle三个属性必须设置为true; 
    ---- 2、不能忘记公用模块中QuickRep对象的DataSet属性设置,即源代码中的QuickRep.DataSet:=Table1语句; 
    ---- 3、动态生成组件的宽度计算必须放在定义其字体属性完成后进行; 
    ---- 4、另外,动态数组给定的内存(即数组容量)以及指定动态数组的起始位置(不一定为0,根据DecisionGrid1控件的固定列确定)很重要,因为一方面当数据库很大时它会大大减少内存的消耗,另一方面便于操作该数组,大大增强了程序的灵活性和通用性。 
    ---- 5、如果让QRDBText控件的数据居中,必须先设置其AutoSize属性为false,然后才能设置其Alignment属性为taCenter。这一点往往容易忽略,直接设置Alignment属性为taCenter,往往达不到数据居中的目的。 
    四、结束语 
    ---- 当然,由于客户对数据报表的可能特殊要求,此公用模块或许不能完全解决。但是,作为公用模块,能实现实现代码的重复利用,提高我们开发程序的效率,当然可以在此模块的基础上进行一些修改或补充,以满足大多数用户的要求,用以下两点加以说明。 
    ---- 1、如果要对数据表的字段进行动态选择输出,则可
      

  11.   

    给个电子信箱地址吧,我给你发一个我改进后的FastReport控件吧,可以直接输出Excel表格(Word、html格式的也可以输出,但用起来用些问题被我屏蔽了。你有兴趣可以自己改)
      

  12.   

    荒原:
    谢谢您!我的信箱地址是[email protected]
      

  13.   

    huangyuansj(荒原)你好
    我现在正需要一个能输出EXCEL文件的FR,你能给我发一份。 非常感谢!!!!
    [email protected]
    [email protected]