FastReport 打印模版頁(TFrxReportpage)複製

遇到一個奇葩的需求。通常狀況下咱們打印單據,用FastReport設置打印格式,也就是就設一個模版頁而己,就是一種單據格式。若是打印的單據數據多了就自動打印多頁了,他們的格式是同樣的。也就是讀同一個模版頁。spa

現的需求是,若是打印N頁內容。每一頁的格式除了表體外是同樣的(也可能部份不一樣)。而表體取自不一樣的數據集(也就是讀取不一樣的FDQuery),須要設置不一樣的表體格式(表體列的數量,列的名稱)。code

在各大論壇中找不到現成解決方案。經網友提示,FastReport的打印模版設置好了其實就是一個XML文件。因此咱們只須要讀取這個XML,而後取出Page部份,複製成N份,根據需求修改不一樣部份的內容,而後再寫入這個打印模版就能夠了。開發中發現Delphi裏讀取XML文件的控件是很多,可是都有或多或少的問題,導制不適用於這個方案,最終我選擇了FastReport裏自帶的FrxXML。功能雖少,可是夠用了。orm

如下分享的是Page頁的複製的實現代碼,修改內容部份根據實際需求自行編寫。至於如何修改,能夠參照如下代碼。blog

與網友的交流中,有網友不明白個人需求,最終說我語文小學沒畢業,表達不清楚。其實我雖然語文小學有畢業,但也是離畢業的不遠。開發

  1 unit frxHelp;
  2 
  3 interface
  4 
  5  uses frxClass,frxXML,System.SysUtils,Vcl.Dialogs;
  6  type
  7   TChangeProp=reference to  procedure (aXML:TfrxXMLItem);
  8 
  9 ///*******************根據FastReport設置好的打印模版(ReportPage)生成多頁
 10 ///
 11 //procedure TForm1.FormCreate(Sender: TObject);
 12 //
 13 //const
 14 // frxFile='G:\delphi\delphi\企業通ERP\DOERP\BIN\fr3\銷售明細打印.fr3';
 15 //var
 16 // cStream:TStream;
 17 // I:integer;
 18 // frXML:TfrxXMLDocument;
 19 // frXItem:TfrxXMLItem;
 20 // fdoprop:TChangeProp;
 21 //begin
 22 //   I:=0;
 23 //   fdoprop:= procedure (aXML:TfrxXMLItem)
 24 //  begin
 25 //    if aXML.PropExists('DataSet') then
 26 //      ShowMessage(aXML.Prop['DataSet']);
 27 //  end;
 28 //  IF  GetFrxpageTemple(frxFile,frXML,frXItem) then
 29 //     IF CopyfrxPage(frXML,frXItem,I,'Page3',fdoProp) then
 30 //       begin
 31 //          cStream:=TMemoryStream.Create;
 32 //          frXML.SaveToStream(cStream);
 33 //          cStream.Position:=0;
 34 //          frxReport1.LoadFromStream(cStream);
 35 //          frxReport1.DesignReport();
 36 //       end;
 37 //end;
 38   procedure changeProp(aXML:TfrxXMLItem;iXML:Integer;Prop:TChangeProp=nil);
 39   procedure CopyXML(S,D:TfrxXMLItem);
 40   function CopyfrxPage(fXMLDoc:TfrxXMLDocument;sPageItem:TfrxXMLItem;ID:integer;cPname:String;Prop:TChangeProp=nil):Boolean;
 41   function GetFrxpageTemple(cFile:String;out fXMLDoc:TfrxXMLDocument;out PageItem:TfrxXMLItem):Boolean;
 42 implementation
 43  procedure CopyXML(S,D:TfrxXMLItem);
 44  var
 45    I:Integer;
 46    a,b:TfrxXMLItem;
 47   begin
 48     for I := 0 to S.Count-1 do
 49       begin
 50         a:=s.Items[i];
 51         b:=d.Add;
 52         b.Name:=a.Name;
 53         b.Text:=a.Text;
 54         if a.Count>0 then
 55          CopyXML(a,b);
 56 
 57       end;
 58   end;
 59  procedure changeProp(aXML:TfrxXMLItem;iXML:Integer;Prop:TChangeProp);
 60  var
 61    I:Integer;
 62    fXML:TfrxXMLItem;
 63   begin
 64     for I := 0 to aXML.Count-1 do
 65       begin
 66         fXML:=aXML.Items[I];
 67       //Name屬性是必須改的,爲避免沒有傳入屬性修改 方法(Prop:TChange)默認強制修改Name
 68         if fXML.PropExists('Name') then
 69           fXML.Prop['Name']:=fXML.Prop['Name']+'N'+iXML.toString;
 70           if Assigned(Prop) then
 71             Prop(aXML);
 72         if fXML.Count>0 then
 73           changeProp(fxML,iXML,Prop);
 74           Inc(iXml);
 75       end;
 76   end;
 77 function GetFrxpageTemple(cFile:String;out fXMLDoc:TfrxXMLDocument;out PageItem:TfrxXMLItem):Boolean;
 78 begin
 79  if Not FileExists(cFile) then
 80    begin
 81      ShowMessagefmt('打印模版[%s]不存在!!',[cFile]);
 82      Exit(False);
 83    end;
 84   try
 85      fXMLDoc:=TfrxXMLDocument.Create;
 86      fXMLDoc.LoadFromFile(cFile);
 87      PageItem:=TfrxXMLItem.Create;
 88      PageItem:=fXMLDoc.Root.FindItem('TfrxReportPage');
 89   except
 90     on E:Exception do
 91       begin
 92         ShowMessage(E.Message);
 93         Exit(false);
 94       end;
 95   end;
 96   Result:=True;
 97 end;
 98 function CopyfrxPage(fXMLDoc:TfrxXMLDocument;sPageItem:TfrxXMLItem;ID:integer;cPname:String;Prop:TChangeProp):Boolean;
 99 var
100  fFrxItem:TfrxXMLItem;
101 begin
102   try
103    fFrXItem:=fXMLDoc.Root.Add;
104    fFrxItem.Name:='TfrxReportPage';
105    fFrxItem.Text:=sPageItem.Text;
106    fFrxItem.Prop['Name']:=cPname;
107    CopyXML(spageItem,fFrxItem);
108    ChangeProp(fFrxItem,ID,Prop);
109   except
110     on E:Exception do
111       begin
112         ShowMessage(E.Message);
113         Exit(false);
114       end;
115   end;
116    result:=True;
117  end;
118 
119 end.
相關文章
相關標籤/搜索