QReport还是不错的(对于一般应用来说),但你需要把他font设为宋体。至于自动换行即使换了也空了一块还不如把这个字段单独放在一列上。

解决方案 »

  1.   

    是啊,QReport其实还可以,复杂应用时就是写的代码多一点,而现在很多人都不喜欢写代码了。
      

  2.   

    其实报表控件只有两种:一种是QReport啦,它是你写程序时定义的,另一种是F1Book啦,它很像EXCEL,可以做出让用户自定义的各种报表,我是用F1的.
      

  3.   

    给你的应用系统加上用户自定义报表报表和打印是程序员公认的编程难点,困难之处在于:
    1、报表格式繁多以及格式的变化使得程序的编制与维护成为一件繁重的体力劳动。
    2、打印机的控制、套打打印、页面控制、分页打印等都是一般程序员较少涉猎的部分。
    3、计算公式的定制、自动计算、单元格的循环引用等,都需要做大量,细致的编程。
    4、打印,显示格式的控制,如常用的数位控制、财务栏的显示、日期时间的格式等。
    5、各种打印机的打印输出精确度,对于套打的表格往往要求较高。
    因此,作为许多应用软件重要部分的报表打印通常需要花费几个月,甚至更长的时间。
    这里向大家介绍一种使用免费的ActiveX控件WjTableOcx进行快速开发的具体方法。
    给你的应用系统加上用户自制报表只需一天时间就可以搞定。一、安装控件
    1、下载ActiveX控件,http://baobiao2000.home.sohu.com/WjTable.zip解压到c:\windows\system
    2、安装activeX控件,在delphi下Component -> Import ActiveX Control
    Add c:\windows\system\WjTableocx.ocx 
    install 到dclusr50.dpk二、编程
    1、New Application。
    放置两个TPanel,Align属性AlTop;Name属性分别为PanelBtn,PanelFomula。
    放置ActiveX tab上的TWjTableX控件,Name属性为WjTable,Align属性alClient。
    2、文件读写
    在PanelBtn上放置两个Button,Name属性分别为BtnReadFile、BtnSaveFile。
    在Form中放置TOpenDialog、TSaveDialog,Name属性分别为OpenDialog、saveDialog。
    BtnReadFile的OnClick事件:procedure TAppBuilder.BtnReadFileClick(Sender: TObject);
    begin
        OpenDialog.Filter := '千禧报表模板文件(*.wrr)|*.wrr';
        if not OpenDialog.Execute then Exit;
        try
            wjTable.ReadFromFile(OpenDialog.FileName);
        except
            ShowMessage('模板文件有损坏');
            exit;
        end;
        WjTable.Align := alClient;
        CheckDrawRuler.Checked := WjTable.bDrawRuler;
        CheckMaskGray.Checked := WjTable.bEditMaskGray;
        CheckFomulaSilver.Checked := WjTable.bFomulaSilver;
        CheckGrayLine.Checked := WjTable.bGrayLine;
        CheckTextOnly.Checked := WjTable.bTextOnly;
    end;
    BtnSaveFile的OnClick事件:
    procedure TAppBuilder.BtnSaveFileClick(Sender: TObject);
    begin
        SaveDialog.Filter := '千禧报表模板文件(*.wrr)|*.wrr';
        if not SaveDialog.Execute then Exit;
        try
            wjTable.SaveToFile(SaveDialog.FileName);
        except
        end;
    end;
    3、打印、预览、页面设置。
    在PanelBtn上放置三个Button,Name属性分别为BtnPrint、BtnPreview、BtnPrintPaper。
    BtnPrint的OnClick事件:
    procedure TAppBuilder.BtnPrintClick(Sender: TObject);
    begin
        WjTable.SetPrinterSettings;
        WjTable.BeginPrint;
        WjTable.Print(wjTable.PaperLeft, wjTable.PaperTop, 1, 1, wjTable.ColCount-2, wjTable.RowCount-2);
        WjTable.EndPrint;
    end;
    BtnPreview的OnClick事件:
    procedure TAppBuilder.BtnPreviewClick(Sender: TObject);
    begin
        WjTable.SetPrinterSettings;
        WjTable.Preview;
    end;
    BtnPrintPaper的OnClick事件:
    procedure TAppBuilder.BtnPrintPaperClick(Sender: TObject);
    begin
      wjTable.PrintPaper;
    end;
    4、合并、拆分表元,既然是中国式报表,当然少不了此项功能。
    在PanelBtn上放置两个Button,Name属性分别为BtnCombine、BtnDivide。
    BtnCombine的OnClick事件:
    procedure TAppBuilder.BtnCombineClick(Sender: TObject);
    begin
        WjTable.SetCellsCombine;
    end;
    BtnDivide的OnClick事件:
    procedure TAppBuilder.BtnDivideClick(Sender: TObject);
    begin
        WjTable.SetCellsDivide;
    end;
    5、行列的插入、删除和追加。
    在PanelBtn上放置六个Button,Name属性分别为BtnRowInsert、BtnRowDelete、BtnRowAdd、BtnColInsert、BtnColDelete、BtnColAdd。
    BtnRowInsert的OnClick事件:
    procedure TAppBuilder.BtnRowInsertClick(Sender: TObject);
    begin
        WjTable.InsertRow(WjTable.Row);
    end;
    BtnRowDelete的OnClick事件:
    procedure TAppBuilder.BtnRowDeleteClick(Sender: TObject);
    begin
        WjTable.DeleteRow(WjTable.Row);
    end;
    BtnRowAdd的OnClick事件:
    procedure TAppBuilder.BtnRowAddClick(Sender: TObject);
    begin
        WjTable.RowCount := WjTable.RowCount + 1;
    end;
    BtnColInsert的OnClick事件:
    procedure TAppBuilder.BtnColInsertClick(Sender: TObject);
    begin
        WjTable.InsertCol(WjTable.Col);
    end;
    BtnColDelete的OnClick事件:
    procedure TAppBuilder.BtnColDeleteClick(Sender: TObject);
    begin
        WjTable.DeleteCol(WjTable.Col);
    end;
    BtnColAdd的OnClick事件:
    procedure TAppBuilder.BtnColAddClick(Sender: TObject);
    begin
        WjTable.ColCount := WjTable.ColCount + 1;
    end;
    6、显示格式,输入格式。
    在PanelBtn上放置两个Button,Name属性分别为BtnFlag、BtnMask。
    BtnFlag的OnClick事件:
    procedure TAppBuilder.BtnFlagClick(Sender: TObject);
    begin
        WjTable.SetCellsFlag;
    end;
    BtnMask的OnClick事件:
    procedure TAppBuilder.BtnMaskClick(Sender: TObject);
    begin
        WjTable.SetCellsMask('999999');  //邮编
    end;
    其中显示格式有10种,包括常用的数值,货币,日期,时间,百分比等,另外还有会计专用格式,财务栏头,财务栏体,中文大写等等。
    输入格式可以自由定义。
    7、字体、颜色和对齐方式。
    在PanelBtn上放置八个Button,Name属性分别为BtnFont、BtnColor、BtnLeft、BtnCenter、BtnRight、BtnTop、BtnVCenter、BtnBottom。
    BtnFont的OnClick事件:
    procedure TAppBuilder.BtnFontClick(Sender: TObject);
    var
        SetFont : IFontDisp;
    begin
        if not FontDialog.Execute then exit;
        GetOleFont(FontDialog.Font,  SetFont);
        WjTable.SetCellsFont(SetFont);
    end;
    BtnColor的OnClick事件:
    procedure TAppBuilder.BtnColorClick(Sender: TObject);
    begin
        if not ColorDialog.Execute then exit;
        WjTable.SetCellsColor(ColorDialog.Color);
    end;
    BtnLeft、BtnCenter、BtnRight、BtnTop、BtnVCenter、BtnBottom的OnClick事件:
    procedure TAppBuilder.BtnLeftClick(Sender: TObject);
    begin
        WjTable.SetCellsAlignment(Ord(taLeftJustify));
    end;
    procedure TAppBuilder.BtnCenterClick(Sender: TObject);
    begin
        WjTable.SetCellsAlignment(Ord(taCenter));
    end;
    procedure TAppBuilder.BtnRightClick(Sender: TObject);
    begin
        WjTable.SetCellsAlignment(Ord(taRightJustify));
    end;
    procedure TAppBuilder.BtnTopClick(Sender: TObject);
    begin
        WjTable.SetCellsVAlignment(1);
    end;
    procedure TAppBuilder.BtnVCenterClick(Sender: TObject);
    begin
        WjTable.SetCellsVAlignment(0);
    end;
    procedure TAppBuilder.BtnBottomClick(Sender: TObject);
    begin
        WjTable.SetCellsVAlignment(2);
    end;
    8、表格线。
    在PanelBtn上放置2个TComboBox,Name属性分别为ComboLine、ComboLineWidth。
    ComboLine的Items属性为:   ComboLineWidth的Items属性为:
    外框线 1
    全部框线 2
    内部框线 3
    无框线






    ComboLine的OnChange事件:
    procedure TAppBuilder.ComboLineChange(Sender: TObject);
    begin
        Wjtable.SetCellsBorder(ComBoLine.ItemIndex);
    end;
    ComboLineWidth的OnChange事件:
    procedure TAppBuilder.ComboLineWidthChange(Sender: TObject);
    begin
        WjTable.LineWidth := ComboLineWidth.ItemIndex + 1;
    end;
    9、设置表格属性。
    在PanelBtn上放置5个TCheckBox,
    Name属性 Caption属性
    CheckDrawRuler 显示标尺
    CheckGrayLine 显示网线
    CheckFomulaSilver 显示公式
    CheckMaskGray 模板灰色
    CheckTextOnly 报表套打
    OnClick事件分别为:
    procedure TAppBuilder.CheckDrawRulerClick(Sender: TObject);
    begin
        WjTable.bDrawRuler := CheckDrawRuler.Checked;
        WjTable.Repaint;
    end;
    procedure TAppBuilder.CheckGrayLineClick(Sender: TObject);
    begin
        WjTable.bGrayLine := CheckGrayLine.Checked;
        WjTable.Repaint;
    end;
    procedure TAppBuilder.CheckFomulaSilverClick(Sender: TObject);
    begin
        WjTable.bFomulaSilver := CheckFomulaSilver.Checked;
        WjTable.Repaint;
    end;
    procedure TAppBuilder.CheckMaskGrayClick(Sender: TObject);
    begin
        WjTable.bEditMaskGray := CheckMaskGray.Checked;
        WjTable.Repaint;
    end;
    procedure TAppBuilder.CheckTextOnlyClick(Sender: TObject);
    begin
        WjTable.bTextOnly := CheckTextOnly.Checked;
        WjTable.Repaint;
    end;
    10、公式与计算。
    在PanelFomula上依次放置TLabel、TButton、TEdit。Name属性分别为LabelCell、BtnFomula、EditFomula。
    选中ActiveX控件WjTable在OnSelectCell事件中写如下代码:
    procedure TAppBuilder.WjTableSelectCell(Sender: TObject; Col, Row: Integer;
      var CanSelect: WordBool);
    var
        sFomula : String;
        nPos : Integer;
    begin
        LabelCell.Caption := WjTable.CellName(Col, row) + '=';
        sFomula := WjTable.GetCells(Col, Row);
        nPos := Pos(#128+'=', sFomula);
        if nPos > 0 then
        EditFomula.Text := Copy(sFomula, nPos + 2, 255)
        else EditFomula.Text := '';
    end;
    在BtnFomula的OnClick事件中写如下代码:
    procedure TAppBuilder.BtnFomulaClick(Sender: TObject);
    begin
        WjTable.SetCellsFomula('=' + EditFomula.Text);
    end;
    好了,一个功能强大的报表编辑软件已大功告成。
    慢,没有用户自定义函数功能如何与应用系统连接?比如财务报表中要求填写qm101得到现金数,
    并且要定义函数Tax计算个人所得税。
    这需要在两个事件中进行处理。OnQueryUserFunction和OnResolveUserFunction。
    OnQueryUserFunction中给出函数名称sFunctionName,要求ParamsCount返回参数个数。如果是非法函数,
    则保持ParamsCount为-1。
    OnResolveUserFunction中对函数进行处理,Params中是参数(以,分隔),结果以字符串形式存放在sResult中。
    procedure TAppBuilder.WjTableQueryUserFunction(Sender: TObject;
      const sFunctionName: WideString; var ParamsCount: Integer);
    begin
        if sFunctionName = 'TAX' THEN paramscount := 1;
        if sFunctionName = 'QM101' THEN paramscount := 0;
        if sFunctionName = '期末数101' THEN paramscount := 0;
        if sFunctionName = '期末数' THEN paramscount := 1;
    end;
    procedure TAppBuilder.WjTableResolveUserFunction(Sender: TObject;
      const sFunctionName, Params: WideString; var sResult: WideString);
    var
        dValue : Double;
    begin
        if sFunctionName = 'TAX' THEN
        begin
            try
            dValue := StrToFloat(Params);
            except
            end;
            if (dValue <= 800) then dValue := 0
            else if (dValue > 800) and (dValue < 1500) then dValue := dValue * 0.05
            else if (dValue > 1500) and (dValue < 3000) then dValue := dValue * 0.10
            else if (dValue > 3000) and (dValue < 5000) then dValue := dValue * 0.15
            else if (dValue > 5000) and (dValue < 10000) then dValue := dValue * 0.20
            else dValue := dValue * 0.25;
            sResult := FloatToStr(dValue);
        end;
        if sFunctionName = 'QM101' THEN
        begin
            sResult := '21343.56';//user get Database Values here
        end;
        if sFunctionName = '期末数101' THEN
        begin
            sResult := '21343.56';
        end;
        if sFunctionName = '期末数' THEN
        begin
            if Params = '101' then sResult := '21343.56'
            else if Params = '102' then sResult := '45767.56'
            else if Params = '103' then sResult := '645.56'
            else if Params = '104' then sResult := '4.56'
            else sResult := '******';
        end;
    end;
    运行程序,选择显示标尺,点A2表元,在公式栏输入Tax(A1),在A1中输入800,1000,2000等值A2中得到税值。
    运用TWjTable ActiveX控件可以方便、快捷的开发出财务,税务等各种复杂报表,还可以实现各种单据的
    仿真输入。有对报表制作感兴趣的朋友,可以发Email:[email protected]与我联系。