delphi 将FastReport报表存入access数据库

转载自:http://t.zoukankan.com/hnxxcxg-p-2940801.html

以下代碼在D7+ACCESS+FastReport 3.15版中測試通過.

1.將FastReport存入數據庫中:

在窗體的"Insert"按鈕的OnClick事件中插入下面代碼:
(Insert_rep: TADOQuery.設置SQL語句:select * from reportdata.
注:ReportData為放置數據庫的表,其中有字段ID(標志),REPORT(報表內容))
procedure TForm1.Button4Click(Sender: TObject);
var
template : TStream;
begin
template := TMemoryStream.Create;
template.Position := 0;
frxReport1.SaveToStream(template);
Insert_rep.Insert;
try
    Insert_rep.Active := true;
    Insert_rep.Edit;
    Insert_rep.DisableControls;
    Insert_rep.FieldByName('rptname').AsString := ExtractFileName(OpenDialog1.FileName);//報表名稱,作為報表數據的標志
    (Insert_rep.FieldByName('rptdata') as TBlobField).LoadFromStream(template);
    Insert_rep.FieldByName('uptime').AsDateTime := now;
    Insert_rep.Append;
    ShowMessage('Insert OK!');
finally
    Insert_rep.EnableControls;
    template.Free;
end;
end;

2.將報表從數據庫中讀取出來:
在Button的OnClick事件中添加下面代碼:
(qr_report: ADOQuery)
procedure TForm1.Button4Click(Sender: TObject);
var
template : TStream;
begin
try
    g_filename := ...;//報表名稱
    qr_report.Close;
    qr_report.SQL.Clear;
    qr_report.SQL.Add('select * from reportdata where id =:id');
    qr_report.Parameters.ParamByName('id').Value := g_filename;
    qr_report.Open;
    try
      template := qr_report.CreateBlobStream(qr_report.FieldByName('report'), bmRead);
      template.Position := 0;
      frxReport1.LoadFromStream(template);
    finally
      template.Free;
    end;
end;
end;

3修改報表,并寫入數據庫.
在frxDesigner1控件的OnSaveReport事件中,加入下面代碼:
(設計報表后,單擊報表中的 "save" 圖標,觸發該事件)
function TForm1.frxDesigner1SaveReport(Report: TfrxReport;
SaveAs: Boolean): Boolean;
var template : TStream;
begin
template := TMemoryStream.Create;
template.Position := 0;
frxReport1.SaveToStream(template);
qr_report.Edit;
try
    qr_report.DisableControls;
    (qr_report.FieldByName('Report') as TBlobField).LoadFromStream(template);
    qr_report.Post;
finally
    qr_report.EnableControls;
    template.Free;
end;
end

 

2023-01-27 16:48追加

上面的代码收藏了许久,现在才有机会实践,上面用的是ADO的方法,而我实际中用的是FireDAC,以下代码经过实测可用,仅供参考

数据库设计:

 

 功能设计:

 

 

添加一个窗体(类)方法:

public
procedure StartReport(flg: Boolean);  //准备报表  ,true为打印,false为预览

以下是它的具体内容:

//准备报表
procedure T报废记录.StartReport(flg: Boolean);
var
  IDList: string;
  n, i: integer;
  template: TStream;
begin
  inherited;
  //检查权限
  if UserInfo.frm报废记录 < 3 then
  begin
    Application.MessageBox('您当前的权限不足,无法进行打印操作!', '权限不足', MB_OK + MB_ICONSTOP);
    exit;
  end;

  with TV报废记录 do
  begin
    n := Controller.SelectedRowCount;
    //检查是否选中记录
    if n = 0 then
    begin
      Application.MessageBox('请先选择目标记录,然后再进行打印操作!', '无效的操作', MB_OK + MB_ICONSTOP);
      exit;
    end;
     //获取用户选择的数据列表 => 1,2,3, 注意后面会多出一个逗号,后面要处理掉
    for i := 0 to n - 1 do
    begin
      Controller.SelectedRows[i].Focused := true;
      IDList := IDList + DM.FDQ报废记录.FieldByName('ID').AsString + ',';
    end;
  end;
  SetLength(IDList, IDList.Length - 1);    //删除最后的逗号

  //下载数据库中的报表模板
  with DM.FD公共查询 do
  begin
    try
      Close;
      SQL.text := 'select * from 报表存储 where UserID =' + userinfo.UserID.ToString +
        ' and ModuleName=' + 'Frm报废记录'.QuotedString;
      Open();
      if recordcount > 0 then  //如果用户有自定义报表,则下载,否则调用内置报表格式
      begin
        try
          template := CreateBlobStream(FieldByName('ReportData'), bmRead);//下载模板
          template.Position := 0;
          frxReport1.LoadFromStream(template);//套用模板
        finally
          template.Free;
        end;
      end;
    finally
          //empty
    end;
  end;

  with dm.FDQReport报废记录 do     //初始化查询,为报表提供数据,这里大家自由发挥吧
  begin
    close;
    sql.Text :=
      ' SELECT 报废记录.recordID, 报废记录.报废单号, 报废记录.日期, 报废记录.物料代码, 报废记录.名称规格,' +
      ' round(报废记录.数量,2)*1 as 数量, 报废记录.用途, 报废记录.报废原因, 报废记录.审核, 供应商列表.供应商名称 AS 供应商,' +
      ' 仓库列表.仓库名称 AS 仓库, 单位列表.单位, 用户名.UserName AS 申请人 ' +
      ' FROM 供应商列表 INNER JOIN (用户名 INNER JOIN (单位列表 INNER JOIN (仓库列表 INNER JOIN 报废记录 ON ' +
      ' 仓库列表.仓库ID = 报废记录.仓库ID) ON 单位列表.单位ID = 报废记录.单位) ON 用户名.UserID = 报废记录.申请人) ON' +
      ' 供应商列表.供应商ID = 报废记录.供应商 WHERE 审核=0 and 报废记录.recordID In (' + IDList + ')';
    Open();
    DisableControls; //断开与数据集的联系,否则会出现逐行扫描的现象 ,这是FDQUERY的方法

    if flg then
    begin
      frxReport1.PrepareReport();   //准备报表
      frxReport1.Print;     //调出打印机界面
    end
    else
      frxReport1.ShowReport();

    EnableControls; //恢复与数据集的联系 ,这是FDQUERY的方法
    first; //  使数据集跳到第一行  ,这是FDQUERY的方法
  end;

end;

然后打印报表和预览报表,都是调用上面的公共方法,只是参数有区别 true为打印,false为预览

procedure T报废记录.dxBarLargeButton3Click(Sender: TObject);    //打印报表
begin
  Self.StartReport(True);
end;

procedure T报废记录.dxBarLargeButton4Click(Sender: TObject);   //预览报表
begin
  Self.StartReport(false);
end;

然后是设置报表,这没什么好讲的,就一句代码

procedure T报废记录.dxBarLargeButton5Click(Sender: TObject);  //报表设计
begin
  frxReport1.DesignReport();
end;

重点是要用到它的保存事件OnSaveReport

//修改报表
function T报废记录.frxDesigner1SaveReport(Report: TfrxReport;SaveAs: Boolean): Boolean;
var
  template: TStream;
begin
  template := TMemoryStream.Create;
  template.Position := 0;
  frxReport1.SaveToStream(template);
  with DM.FD公共查询 do
  begin
    close;
    SQL.Text := 'select * from 报表存储 where userID=' + UserInfo.UserID.ToString + ' and ModuleName=' +
      'frm报废记录'.QuotedString;
    open();
    if recordcount = 0 then     //如果不存在则新增
    begin
      close;
      SQL.Text := 'insert into 报表存储 (UserID,ModuleName) values(' + Userinfo.UserID.ToString + ',' +
        'Frm报废记录'.QuotedString + ')';
      ExecSQL;

      //重新选定用户数据
      close;
      SQL.Text := 'select * from 报表存储 where userID=' + UserInfo.UserID.ToString + ' and ModuleName='
        + 'frm报废记录'.QuotedString;
      open();
    end;

    Edit;
    try
      DisableControls; //断开联系
      (FieldByName('ReportData') as TBlobField).LoadFromStream(template);
      Post;//上传报表
    finally
      EnableControls;  //恢复联系
      template.Free;
    end;
  end;
end;

 以下是chatGPT的回复

---
Q: 请用delphi写出把fastreport报表提交到数据库的方法,要带注释
A:


方法一:
//使用FastReport的DataSet属性
DataSet := MyDataSet;
DataSet.Open;
DataSet.Append;
DataSet.FieldByName('FieldName').AsString := 'Value';
DataSet.Post;
---

 

posted @ 2022-10-28 08:20  一曲轻扬  阅读(369)  评论(0)    收藏  举报