如何在Delphi 2007应用程序中显示Crystal XI报告?

时间:2008-12-18 15:00:33

标签: delphi crystal-reports

最新的Delphi Crystal XI组件是为Delphi 7发布的。该VCL组件在D2007中编译,但在运行时给出了错误。在Delphi 2007应用程序中显示数据库连接Crystal Report的最佳方法是什么?

5 个答案:

答案 0 :(得分:4)

这是我使用ActiveX找到的解决方案:

首先,注册Active X控件,如下所示:

在Delphi中,选择Component - >导入组件

单击“类型库”,单击“下一步”

选择“Crystal ActiveX Report Viewer Library 11.5”

选择你想要的任何调色板页面(我使用“数据访问”)

选择导入位置

退出向导

将您选择的位置添加到项目搜索路径

现在这段代码应该有效:

...
uses
  CrystalActiveXReportViewerLib11_5_TLB, OleAuto;
...

procedure TForm1.Button1Click(Sender: TObject);
var
  cry : TCrystalActiveXReportViewer;
  oRpt, oApp : variant;
  i : integer;
  frm : TForm;
begin
  cry := TCrystalActiveXReportViewer.Create(Self);
  oApp := CreateOleObject('CrystalRuntime.Application');
  oRpt := oApp.OpenReport('c:\my_report.rpt',1);
  for i := 1 to oRpt.Database.Tables.Count do begin
    oRpt.Database.Tables[i].ConnectionProperties.Item['User ID'] := 'username';
    oRpt.Database.Tables[i].ConnectionProperties.Item['Password'] := 'password';
  end;

  frm := TForm.Create(Self);
  try
    cry.Parent := frm;
    cry.Align := alClient;
    cry.ReportSource := oRpt;
    cry.ViewReport;
    frm.Position := poOwnerFormCenter;
    frm.ShowModal;
  finally
    FreeAndNil(frm);
  end;  //try-finally
end;

procedure TForm1.btnExportClick(Sender: TObject);
var
  cry : TCrystalActiveXReportViewer;
  oRpt, oApp : variant;
  i : integer;
begin
  //Export the report to a file
  cry := TCrystalActiveXReportViewer.Create(Self);
  oApp := CreateOleObject('CrystalRuntime.Application');
  oRpt := oApp.OpenReport(c_DBRpt,1);
  for i := 1 to oRpt.Database.Tables.Count do begin
    oRpt.Database.Tables[i].ConnectionProperties.Item['User ID'] := 'username';
    oRpt.Database.Tables[i].ConnectionProperties.Item['Password'] := 'password';
  end;

  oRpt.ExportOptions.FormatType := 29;  //excel 8
  oRpt.ExportOptions.DiskFileName := 'c:\output.xls';
  oRpt.ExportOptions.DestinationType := 1;  //file destination
  //Export(False) => do NOT prompt.
  //Export(True) will give runtime prompts for export options.
  oRpt.Export(False);
end;

如果您使用此方法,那么this (rather dense) reference将会有所帮助,尤其是因为Intellisense不能对这些Ole对象起作用。

编辑:引用的原始链接断开,因此我将其更改为指向新的(从2009年12月15日起生效)。如果新的那个破了,那么Google should be able to find it

答案 1 :(得分:3)

我知道这不是你的问题,在你的情况下可能根本不是一个可接受的答案,但我发现FastReports明显优于Crystal。它重量更轻,包括一个真正的脚本语言,包含事件处理,可以调用您的本机代码以获取信息和更新,并且不需要ActiveX连接。我可以将报告导出为外观精美的PDF文件或Excel电子表格以及其他几种格式。输出的质量增加了用户从我的应用程序中获得的整体体验。我可以继续,但如果它不适合你,它将没有帮助。

答案 2 :(得分:3)

为了能够使用它的任何人,这里有一个完整的类,它为这些卑鄙的Crystal交互提供了一个愉快的包装。大约80%的时间它对我有用,但我怀疑这些东西很多都依赖于它运行的特定平台。我会在制作它们时发布改进。

Business Objects的某些人应该认真看看这个API。它非常糟糕。

{
Class to facilitate the display of Crystal 11 Reports.

The Crystal 11 VCL component does not seem to work with Delphi 2007.
As a result, we have to use ActiveX objects, which make deployment messy.

This class is similar to CrystalReporter, but it works for Crystal 11.
However, it lacks some of the features of the old CrystalReporter.

Refer to the crystal reports activex technical reference to duplicate the
missing functionality.

Example usage is at the bottom of this unit.
//}
unit CrystalReporter11;

interface

uses
  CrystalActiveXReportViewerLib11_5_TLB, OleAuto, Classes, Controls;

type
  TCryExportFormat = (
                      XLS
                     ,PDF
                     );

type
  TCrystalReporter11 = class
  private
    FCryRpt : TCrystalActiveXReportViewer;
    FRpt, FApp : variant;
    FReportFile, FUsername, FPassword, FServer, FFilters : string;
    FOwner : TComponent;
    procedure SetLoginInfo(const username, password, server : string);
    function GetFilterConds: string;
    procedure SetFilterConds(const Value: string);
  public
    property FilterConditions : string read GetFilterConds write SetFilterConds;

    procedure ExportToFile(ExportFileName : string;
      FileExportFmt : TCryExportFormat; PromptForOptions : boolean);
    procedure Display;

    constructor Create(AOwner : TComponent; ReportFile : string); overload;
    constructor Create(AOwner : TComponent; ReportFile,
      Username, Password, Server : string); overload;
  end;

implementation

uses
  SysUtils, Forms;

const
  //these are taken from pgs 246 and 247 of the technical reference
  c_FmtCode_Excel = 29;
  c_FmtCode_PDF = 31;

constructor TCrystalReporter11.Create(AOwner: TComponent; ReportFile: string);
begin
  inherited Create;
  try
    FReportFile := ReportFile;
    if FileExists(FReportFile) then begin
      FOwner := AOwner;
      FCryRpt := TCrystalActiveXReportViewer.Create(AOwner);
      FApp := CreateOleObject('CrystalRuntime.Application');
      FRpt := FApp.OpenReport(FReportFile,1);
      FFilters := FRpt.RecordSelectionFormula;
    end
    else begin
      raise Exception.Create('Report file ' + ReportFile + ' not found!');
    end;
  except on e : exception do
    raise;
  end;  //try-except
end;

constructor TCrystalReporter11.Create(AOwner: TComponent; ReportFile, Username,
  Password, Server: string);
begin
  Create(AOwner,ReportFile);
  FUsername := Username;
  FPassword := Password;
  FServer := Server;
  SetLoginInfo(FUsername,FPassword,FServer);
end;

procedure TCrystalReporter11.Display;
var
  rptForm : TForm;
begin
  SetLoginInfo(FUsername,FPassword,FServer);
  FCryRpt.ReportSource := FRpt;
  rptForm := TForm.Create(FOwner);
  try
    FCryRpt.Parent := rptForm;
    FCryRpt.Align := alClient;
    FCryRpt.ViewReport;
    rptForm.Position := poOwnerFormCenter;
    rptForm.WindowState := wsMaximized;
    rptForm.Caption := ExtractFileName(FReportFile);
    rptForm.ShowModal;
  finally
    FreeAndNil(rptForm);
  end;  //try-finally
end;

procedure TCrystalReporter11.ExportToFile(ExportFileName : string;
  FileExportFmt : TCryExportFormat; PromptForOptions : boolean);
begin
  case FileExportFmt of
    XLS : FRpt.ExportOptions.FormatType := c_FmtCode_Excel;
    PDF : FRpt.ExportOptions.FormatType := c_FmtCode_PDF;
  end;  //case

  FRpt.ExportOptions.DiskFileName := ExportFileName;
  FRpt.ExportOptions.DestinationType := 1;  //file destination
  FCryRpt.ReportSource := FRpt;  
  FRpt.Export(PromptForOptions);
end;

function TCrystalReporter11.GetFilterConds: string;
begin
  Result := FFilters;
end;

procedure TCrystalReporter11.SetFilterConds(const Value: string);
begin
  FFilters := Value;
  if 0 < Length(Trim(FFilters)) then begin
    FRpt.RecordSelectionFormula := Value;
  end;
end;

procedure TCrystalReporter11.SetLoginInfo(const username, password,
  server : string);
var
  i : integer;
begin
  //set user name and password
  //crystal only accepts these values if they are CONST params
  for i := 1 to FRpt.Database.Tables.Count do begin
    FRpt.Database.Tables[i].ConnectionProperties.Item['User ID'] := username;
    FRpt.Database.Tables[i].ConnectionProperties.Item['Password'] := password;
    try
      {
      Some reports use direct connections, and others use an ODBC Data Source.
      Crystal XI uses a different label to refer to the database name in each
      method.
      I don't know how to determine in advance which method is being used, so:
          First, we try the direct connection.
          If that fails, we try the "data source" method.

      Reference: "Crystal Reports XI Technical Reference", pages 41 thru 46;
                 "Common ConnectionProperties"
      }
      FRpt.Database.Tables[i].ConnectionProperties.Item['Server'] := server;
    except on E: Exception do
      FRpt.Database.Tables[i].ConnectionProperties.Item['Data Source'] := server;
    end;
  end;
end;
{
Example usage:

procedure TForm1.btnShowRptDBClick(Sender: TObject);
var
  cry : TCrystalReporter11;
begin
  cry := TCrystalReporter11.Create(Self,'c:\my_report.rpt','username',
    'password','server.domain.com');
  try
    cry.Display;
  finally
    FreeAndNil(cry);
  end;
end;
}
end.

答案 3 :(得分:1)

我也对Crystal Reports在应用程序集成方面缺乏努力感到失望。我使用的是RDC,根据我的理解,这是被弃用的,重点放在.Net上。

我的应用程序在uses子句中包含这些文件:    CRRDC,CRAXDRT_TLB,

一切正常。因为缺点是参数传递。在我的选项中,查看器附带的参数对话框很糟糕。所以我使用自己的Delphi应用程序来提示参数并将它们传递给报告。

答案 4 :(得分:0)

这是一个更简单,更干净的类,可以很好地解决问题:

单位CrystalReports; 使用Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,     Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls,Vcl.OleCtrls,ActiveX,ComObj,Data.DB,Data.Win.ADODB,     CrystalActiveXReportViewerLib11_TLB,Vcl.OleServer,CrystalReportsControllersLib_TLB;

type
TCrystalReportForm = class(TForm)
    CRV: TCrystalActiveXReportViewer;
    procedure DisplayReport;
private
    { Private declarations }
public
    {Public declarations }
    ReportName : WideString;
    ReportCaption : String;
    ReportSelectionFormula : WideString;
end;

var
CRXIRuntime : Variant;

implementation

{$R *.dfm}

procedure TCrystalReportForm.DisplayReport;
var
CrystalReport : variant;
i : integer;

begin
CrystalReport := CRXIRuntime.OpenReport(ReportName);
for i := 1 to CrystalReport.Database.Tables.Count do begin
    CrystalReport.Database.Tables[1].ConnectionProperties.Item['User ID'] := 'user';
    CrystalReport.Database.Tables[1].ConnectionProperties.Item['Password'] := 'password';
end;
CrystalReport.FormulaSyntax := 0;
Caption := ReportCaption;
CrystalReport.RecordSelectionFormula := ReportSelectionFormula;
CRV.Align := alClient;
CRV.ReportSource := CrystalReport;
WindowState := wsMaximized;
CRV.ViewReport;
ShowModal;
end;

begin
CRXIRuntime := CreateOleObject('CrystalRuntime.Application');
end.