关于动态报表,大家用的都是什么控件(方法)?(100分)

  • 主题发起人 主题发起人 base7
  • 开始时间 开始时间
B

base7

Unregistered / Unconfirmed
GUEST, unregistred user!
老板要求做一个动态报表,功能有点类似brio报表工具的那种
用户可以自己定义选择哪些数据项(列)和哪些内容(行)...
还要求能够分小项合计, 总计.... 要求可以保存,打印....
天,大家知道该如何实现吗?
我试过fastReport,XLgrid, EnhGrid都不是很好(会不会是我不会用?)
而devExpress grid什么的又因为版权不太敢用,还有别的办法吗?
 
找不到合适的,就自己写一个动态报表,我就是自己写的,不同用户在使用中均非常满意。
 
to zhanggm:
自己写的?什么意思?包括预览,打印的实现你都是自己写的吗?
太牛了,我自认办不到...
 
弄到Excel好了,随便你要什么格式,我觉的不错,而且我的用户都会接受。
 
我也在做一个类似的冬冬啊,各位大侠指点一下?jstkof@21cn.com
 
就用QuickReport
其实指定列(Field Visiable)和合计(Aggregate Field)在Table/Query中搞定就行了
我写过一个根据Gird的列数,顺序,宽度来打印的。
 
to Tuatara:
是不是在Excel里做好模版吗,能否告诉你的做法?
 
我研究过XLGrid的Demo,它就是先做好Excel的模板
可是..如果所选的列是动态的,这个模板该怎么做呢?[:(]
 
前不久我也要这样一个控件,但一直没有找到,我有一个员工表,有许多字段,要根据
用户的选来进行打印,比如我只要输出: 姓名,性别,出生所月,家庭住址,电话
则就选则这几个开始打印。
起先我也认为自己写太麻烦,但后来没办法也只动手搞,还是完成了,建议你也动手写吧!
我先写一个函数
如:PrintField(Left:string;f:String);
Left :控制字段的左边距
F:字段名
这样如果我要打印某个字段到某个位置开始用
PrintField(100,'姓名')
然后用多个这样的printField就可以搞出一个动态报表来。
当然要在中间合理的控制每个字段的位置。。
试试吧,定会搞出来的。
 
>我研究过XLGrid的Demo,它就是先做好Excel的模板
>可是..如果所选的列是动态的,这个模板该怎么做呢?[:(]
>是不是在Excel里做好模版吗,能否告诉你的做法?
既然是模板通常列都相对固定的。也可以不用模板,这样做列就可以动态变化了
delphi和Excel连上后,可以很方便容易的控制格式(包括字体,字号,画各种线条...)
只要你的用户能接受,我觉得这种方式比任何报表控件都好。
 
有很大部分的系统不可以用Excel的:防止操作人修改数据
除非你可以控制其只读,偶想过还没实现。
 
to zhanggm:你确实牛~~~~~~
to base7:用ehlib,控制grid的columns的visible属性,你的问题很容易解决,方便省事
 
强烈关注中。
 
to peakliu:
enlib可以自定义报表的标题什么的吗?
我看了它的例子,打印部分好像只有表格部分(包括列名)?
 
自己写报表控件
写控件时间 三个月 3*22*8=528 小时
自己画报表
现有报表系统画报表 2小时/个
如果报表较多,自己写控件,报表制作很轻松,但前期投入较大
如果报表较少,就不必如此了,将数据导入Excel 或F1 BOOK 控件就可以实现动态.

 
to: Tuatara,请教怎样将dbgrid中的数据导到excel中
 
仔细看看这里,对你非常有帮助的。记住一定要仔细看。:)
http://www.delphibbs.com/delphibbs/dispq.asp?lid=737517
 
明细型用RM或fastreport.
统计型用cell控件。画表格比较方便。自己定义公式来取数。
 
我前二天写了一个工资管理程序,就是可以随时动态打印,在报表生成过程中可自动分析
哪些是应该打的,哪些是不应该的要,并可以根据本列中最长的字符长度自动设置该栏
宽度。可现在改成report machine的了。
请看部分源码:
procedure Tmain.BitBtn3Click(Sender: TObject);
var
i:integer;
begin
table_name:=edit1.Text+combobox1.Text;
title_rep:=edit1.Text+'年'+combobox1.Text+'月份'+'工资发放汇总表'+'('+combobox3.text+')';
hz_tmp:='';
for i := 0 to adoquery1.FieldCount - 1do
begin
if (adoquery1.Fields.FieldName<>'ID') and (adoquery1.Fields.FieldName<>'排序') and (adoquery1.Fields.FieldName<>'编制') and (adoquery1.Fields.FieldName<>'姓名') then
if (adoquery1.Fields.FieldName='科室') then
if hz_tmp='' then
hz_tmp:='科室,count(科室) as 人数' else
hz_tmp:=hz_tmp+','+'科室,count(科室) as 人数' else
if hz_tmp='' then
hz_tmp:='sum('+adoquery1.Fields.FieldName+') as '+adoquery1.Fields.FieldName else
hz_tmp:=hz_tmp+','+'sum('+adoquery1.Fields.FieldName+') as '+adoquery1.Fields.FieldName;
end;

with gzdo
begin
close;
sql.Clear;
sql.Add('select '+hz_tmp+' from '+edit1.Text+combobox1.Text);
if combobox3.text<>'全部人员' then
sql.Add('where 编制='+''''+combobox3.text+'''');
sql.add('group by 科室');
open;
end;

rmReport1.Pages.Clear;
rmReport1.Pages.Add;
rmReport1.pages.Pages[0].ChangePaper(256,3800,2800, 0,poPortrait);
Page := rmReport1.Pages[0];

gz_x:=40;
b := TrmBandView(rmCreateObject(gtBand, ''));
b.SetBounds(20, 20, 0, 60);
b.BandType := btpageheader;
Page.Objects.Add(b);
v := rmCreateObject(gtMemo, '');
v.SetBounds(20,40, 700, 32);
v.Memo.Add(title_rep);
TrmMemoView(v).Font.Name:='黑体';
TrmMemoView(v).Font.Size:=14;
TrmMemoView(v).BandAlign:=rmbacenter;
Page.Objects.Add(v);
b := TrmBandView(rmCreateObject(gtBand, ''));
b.SetBounds(20, 100, 0, 40);
b.BandType := btMasterheader;
Page.Objects.Add(b);

b := TrmBandView(rmCreateObject(gtBand, ''));
b.SetBounds(20, 160, 0, 16);
b.BandType := btMasterData;
b.Dataset := 'rmDBDataSet1';
Page.Objects.Add(b);
b := TrmBandView(rmCreateObject(gtBand, ''));
b.SetBounds(20, 220, 0, 16);
b.BandType := btMasterfooter;
Page.Objects.Add(b);

for I:=0 to gz.FieldCount-1do
begin
gz_xm:=gz.Fields.FieldName;
gzjg.locate('项目',gz_xm,[loCaseInsensitive]);
if gzjg.FieldByName('是否打印').asstring='Y' then
begin
if gz_xm='科室' then
fie_len:=40 else
if gz_xm='人数' then
fie_len:=30 else
begin
with chddo
begin
close;
sql.Clear;
sql.add('select sum('+gz_xm+') from '+table_name);
if combobox3.text<>'全部人员' then
sql.Add('where 编制='+''''+combobox3.text+'''');
open;
end;
fie_len:=length(formatfloat('0.00',chd.Fields[0].asfloat))*6+5;
if fie_len<40 then
fie_len:=40;
if odd(fie_len)=false then
fie_len:=fie_len+1;
end;

v := rmCreateObject(gtMemo, '');
v.SetBounds(gz_x,100, fie_len, 40);
v.Memo.Add(gz_xm);
v.Prop['WordWrap']:=true;
TrmMemoView(v).Font.Name:='宋体';
TrmMemoView(v).Font.Size:=9;
v.TopFrame.Visible:=true;v.BottomFrame.Visible:=true;v.rightFrame.Visible:=true;v.LeftFrame.Visible:=true;
TrmMemoView(v).Alignment:=rmtamiddle+rmtacenter;
Page.Objects.Add(v);

v := rmCreateObject(gtMemo, '');
v.SetBounds(gz_x,160, fie_len, 16);
v.Memo.Add('[gz."'+gz_xm+'"]');
TrmMemoView(v).Font.Name:='宋体';
TrmMemoView(v).Font.Size:=9;
v.TopFrame.Visible:=true;v.BottomFrame.Visible:=true;v.rightFrame.Visible:=true;v.LeftFrame.Visible:=true;
if gz.Fields.DataType in [ftFloat,ftCurrency,ftBCD] then
begin
TrmMemoView(v).Format:=1 * $01000000 + 4 * $00010000+2*$00000100;
TrmMemoView(v).Format := TrmMemoView(v).Format + Ord('.');
TrmMemoView(v).FormatStr:='0.00';
end;
if gz_xm='科室' then
TrmMemoView(v).Alignment:=rmtamiddle
else
TrmMemoView(v).Alignment:=rmtamiddle+rmtaright;
Page.Objects.Add(v);

v := rmCreateObject(gtMemo, '');
v.SetBounds(gz_x,220, fie_len, 16);
if gz.Fields.DataType in [ftFloat,ftCurrency,ftBCD] then
begin
TrmMemoView(v).Format:=1 * $01000000 + 4 * $00010000+2*$00000100;
TrmMemoView(v).Format := TrmMemoView(v).Format + Ord('.');
TrmMemoView(v).FormatStr:='0.00';
end;
if gz_xm='科室' then
v.Memo.Add('合计') else
v.Memo.Add('[sum('+gz_xm+')]');
TrmMemoView(v).Font.Name:='宋体';
TrmMemoView(v).Font.Size:=9;
v.TopFrame.Visible:=true;v.BottomFrame.Visible:=true;v.rightFrame.Visible:=true;v.LeftFrame.Visible:=true;
if gz_xm='科室' then
TrmMemoView(v).Alignment:=rmtamiddle+rmtacenter
else
TrmMemoView(v).Alignment:=rmtamiddle+rmtaright;
Page.Objects.Add(v);
gz_x:=gz_x+fie_len;
end;
end;

rmReport1.ShowReport;

end;
 

Similar threads

回复
0
查看
852
不得闲
D
回复
0
查看
897
DelphiTeacher的专栏
D
D
回复
0
查看
854
DelphiTeacher的专栏
D
D
回复
0
查看
829
DelphiTeacher的专栏
D
后退
顶部