Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Using fastreport


This question is answered.


Permlink Replies: 11 - Last Post: Oct 15, 2015 7:50 PM Last Post By: Daniel Fields
Ertan Kucukoglu

Posts: 49
Registered: 7/4/09
Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 10, 2015 10:38 PM
Hi,

As I have been testing intraweb now I am interested in reporting with it. Embarcadero ships with fastreport, and I plan to use it, too.

Already tried some samples on the internet. Got stuck again.

Found this link nearly identical to my problem: http://codeverge.com/embarcadero.delphi.intraweb/intraweb-14.0.22-and-fastreport-4/1060347

Couldn't understand how that particular person solved his problem though. So, I'm still here with my problem.

Some details as to project:
UserSessionUnit has all data components.
Unit1 has fast report components including fast report and pdf export components. There is fast report data source, that is not linked to any component at the moment.
Unit1 uses UserSessionUnit, ServerController

Started with a data aware report first. After a while, I deleted the component to start from scratch, and now I have a no-database connected report file. There are just two labels in it. No datasource is bound to the component. When I try to run report on a button click event below, I get a download sized around 747 bytes.

Button click code in Unit1 is as follows:
procedure TIWForm1.IWButton1Click(Sender: TObject);
var pdfname, pdfurl:string;
begin
  // Get temp filename
  pdfname := IWServerController.CacheDir + WebApplication.AppID + 'rapor1.pdf';
  pdfurl  := WebApplication.AppURLBase + '/Files/' + WebApplication.AppID + 'rapor1.pdf';
  ForceDirectories(ExtractFileDir(pdfname));
 
  // DestroyForms can be switched off, if every time a report is renewed from a file or from the current report
  FrxReport1.EngineOptions.DestroyForms := False;
  FrxReport1.EngineOptions.SilentMode := True;
  FrxReport1.EngineOptions.EnableThreadSafe:=true;
  frxReport1.ShowProgress := false;
  frxReport1.EngineOptions.UseFileCache:=false;
  frxReport1.ReportOptions.Compressed := True;
  FrxReport1.EngineOptions.UseGlobalDataSetList := False; // This property switches off the search of the global list
  // EnabledDataSets plays the role of a local list, it should be installed
  // before the template is loaded
//  frxReport1.EnabledDataSets.Clear;
//  FrxReport1.EnabledDataSets.Add(FrxDBDataSet1);
  frxReport1.LoadFromFile(GetCurrentDir + '\rapor1.fr3');
  if FrxReport1.PrepareReport(true) then
  begin
    frxPDFExport1.FileName := pdfname;
    frxPDFExport1.ShowDialog := false;
    frxPDFExport1.ShowProgress := false;
    frxReport1.Export(frxPDFExport1);
//    WebApplication.NewWindow(pdfurl);
    WebApplication.SendFile(pdfname, True, 'pdf', 'rapor1.pdf');
    frxReport1.Clear;
  end else begin
    raise Exception.Create('Reporting error');
  end;
end;


I appreciate any support.

Thanks & regards,
Ertan Küçükoğlu
Daniel Fields

Posts: 622
Registered: 11/29/04
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 11, 2015 12:39 AM   in response to: Ertan Kucukoglu in response to: Ertan Kucukoglu
You are getting the download because of this line "WebApplication.SendFile(pdfname, True, 'pdf', 'rapor1.pdf')" that sends the specified file to the client browser, as a download. You have to do something else if you want to see that report inside you application.

1. Put a region on the form.
2. Size it to dimensions that will be suitable to view your report.
3. Set IWRegion1.HorzScrollBar.Visible to false.
4. Put a label inside IWRegion1.
5. Set IWLabel1.Top =1 and IWLabel1.Left=1.
6. Set IWLabel1.RawText to true;

//replace the download code below
//WebApplication.SendFile(pdfname, True, 'pdf', 'rapor1.pdf');" with this:
 
//new code to show report
IWLabel1.Caption := '<object data="'
                                +'Files/' + WebApplication.AppID + 'rapor1.pdf'
                                +'" type="application/pdf" width="100%" height="100%">';
 


That is off the top of my head, so try it and let me know if you have a problem.
Ertan Kucukoglu

Posts: 49
Registered: 7/4/09
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 11, 2015 2:39 AM   in response to: Daniel Fields in response to: Daniel Fields
It's all on me. My problem was that source report file "rapor1.fr3" is mis-located in the filesystem. It was not where my executable is running. once I fixed its location in my computer, downloading and everything is fine. It's just I still cannot display it in IWRegion.

My variable pdfname already has 'rapor1.pdf' location. So, I changed your code sample as blow:

    IWLabel1.Caption := '<object data="' + pdfname
                                +'" type="application/pdf" width="100%" height="100%">';


What I get is that all my visual controls like navigation bar, buttons, fileupload control etc are moved in IWRegion1 and displayed in it. Original locations are empty after I click reporting button. Though, they are still working and button click, etc running. It is just nothing displayed as a report.
Daniel Fields

Posts: 622
Registered: 11/29/04
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 11, 2015 2:54 AM   in response to: Ertan Kucukoglu in response to: Ertan Kucukoglu
pdfname := IWServerController.CacheDir + WebApplication.AppID + 'rapor1.pdf';
pdfurl := WebApplication.AppURLBase + '/Files/' + WebApplication.AppID + 'rapor1.pdf';

pdfname is going to be in Windows format (UNC)
pdfurl is URL encoded

The <object> tag is expecting a URL, not a filename.

Try changing this line
pdfurl := WebApplication.AppURLBase + '/Files/' + WebApplication.AppID + 'rapor1.pdf';

To
pdfurl := 'files/' + WebApplication.AppID + 'rapor1.pdf';
Ertan Kucukoglu

Posts: 49
Registered: 7/4/09
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 11, 2015 5:37 AM   in response to: Daniel Fields in response to: Daniel Fields
Hi again,

I am working on my code base and trying to solve that displaying report on the screen issue at the same time. Below is my updated code in a new procedure. I will continue to add several export types and then I will be mostly finished.

Code to call procedure:
  // expPDF and expXLSX are both constants to identify export type
  // I choose to pass all objects as parameters, I need to add at least CSV export in my procedure
  ReportExport(expPDF, 'rapor1', frxReport1, frxPDFExport1, nil);  // PDF export
  ReportExport(expXLSX, 'rapor1', frxReport1, nil, frxXLSXExport1);  // XLSX export
 
  // procedure definition
  procedure ReportExport(WhatToExport: Word; ReportFile: string; rptObj: TfrxReport; pdfObj: TfrxPDFExport; xlsxObj: TfrxXLSXExport);


Report Exporting procedure code:
procedure TIWForm1.ReportExport(WhatToExport: Word; ReportFile: string; rptObj: TfrxReport; pdfObj: TfrxPDFExport; xlsxObj: TfrxXLSXExport);
var fname, furl, ftype, fextension:string;
begin
  // Get temp filename
  fname := WebApplication.UserCacheDir + '\files\' + WebApplication.AppID + ReportFile;
  furl  := WebApplication.UserCacheUrlBase + 'files/';
 
  // set some application parameters
  case WhatToExport of
    expPDF: begin
      fextension := '.pdf';
      fname      := fname + fextension;
      furl       := furl + ExtractFileName(fname);
      ftype      := 'pdf';
    end;
    expXLSX: begin
      fextension := '.xlsx';
      fname      := fname + fextension;
      furl       := furl + ExtractFileName(fname);
      ftype      := 'xlsx';
    end;
  end;
 
  ForceDirectories(ExtractFileDir(fname));
 
  // DestroyForms can be switched off, if every time a report is renewed from a file or from the current report
  rptObj.EngineOptions.DestroyForms := False;
  rptObj.EngineOptions.SilentMode := True;
  rptObj.EngineOptions.EnableThreadSafe:=true;
  rptObj.ShowProgress := false;
  rptObj.EngineOptions.UseFileCache:=false;
  rptObj.ReportOptions.Compressed := True;
  rptObj.EngineOptions.UseGlobalDataSetList := False; // This property switches off the search of the global list
  // EnabledDataSets plays the role of a local list, it should be installed
  // before the template is loaded
 
  if not TFile.Exists(GetCurrentDir + '\' + ReportFile + '.fr3') then begin
    raise Exception.Create('ERROR: report file cannot be loaded' + #13 + GetCurrentDir + '\' + ReportFile + '.fr3');
  end;
 
  rptObj.LoadFromFile(GetCurrentDir + '\' + ReportFile + '.fr3');
  if rptObj.PrepareReport(true) then
  begin
    case WhatToExport of
      expPDF: begin // PDF EXPORT
        pdfObj.FileName := fname;
        pdfObj.ShowDialog := false;
        pdfObj.ShowProgress := false;
        pdfObj.OverwritePrompt := false;
        rptObj.Export(pdfObj);
      end;
      expXLSX: begin
        xlsxObj.FileName := fname;
        xlsxObj.ExportPageBreaks := false;
        xlsxObj.OverwritePrompt := false;
        xlsxObj.DataOnly := true;
        xlsxObj.EmptyLines := false;
        xlsxObj.ShowDialog := false;
        xlsxObj.ShowProgress := false;
        rptObj.Export(xlsxObj);
      end;
    end;
 
    WebApplication.NewWindow(furl);
    WebApplication.SendFile(fname, True, ftype, ReportFile + fextension);
 
    IWLabel1.Caption := '<object data="' + furl
                                +'" type="application/pdf" width="100%" height="100%">';
    Self.Refresh;
  end else begin
    raise Exception.Create('Reporting error');
  end;
end;


I have also uploaded some pictures for easier understanding of the problem. They can be downloaded from: http://1drv.ms/1ZrcOOA

I have below problems remaining at the moment:
1) when I click any button to export a report, I see wait circle in the middle of my browser. It stays there even if I finish my download. Only way to clear it is a click on browser refresh button.
2) I still cannot see my report on the screen. You can see how screen become after above code run.
3) WebApplication.NewWindow(furl); code has no effect. No new window is opened. I don't get any pop-up page blocked message in my browser. Be it IE or Comodo Chromodo.

Thanks & regards,
Ertan Küçükoğlu
Daniel Fields

Posts: 622
Registered: 11/29/04
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 11, 2015 6:22 PM   in response to: Ertan Kucukoglu in response to: Ertan Kucukoglu
1) when I click any button to export a report, I see wait circle in the middle of my browser. It stays there even if I finish my download. Only way to clear it is a click on browser refresh button.

Set IWForm.LockOnSubmit to false;

2) I still cannot see my report on the screen. You can see how screen become after above code run.
That may be related to #1

3) WebApplication.NewWindow(furl); code has no effect. No new window is opened. I don't get any pop-up page blocked message in my browser. Be it IE or Comodo Chromodo.

That call should be avoided because it does not have good cross browser support. You should use a TIWModalWindow control instead. You would then do this:

with IWModalWindow1 do 
begin
    Reset;
    Autosize := False;
    Title := 'My Report';
    Draggable := False;
    WindowWidth := 300;
    WindowHeight := 500;
    Src := ReportFile + fextension;
    OnAsyncClick := nil;
    Show;
  end;
Ertan Kucukoglu

Posts: 49
Registered: 7/4/09
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 12, 2015 1:50 PM   in response to: Daniel Fields in response to: Daniel Fields
Daniel Fields wrote:
1) when I click any button to export a report, I see wait circle in the middle of my browser. It stays there even if I finish my download. Only way to clear it is a click on browser refresh button.

Set IWForm.LockOnSubmit to false;

I set that to False.

2) I still cannot see my report on the screen. You can see how screen become after above code run.
That may be related to #1

I believe that problem is something else. I still cannot see anything in my IWLabel1.

3) WebApplication.NewWindow(furl); code has no effect. No new window is opened. I don't get any pop-up page blocked message in my browser. Be it IE or Comodo Chromodo.

That call should be avoided because it does not have good cross browser support. You should use a TIWModalWindow control instead. You would then do this:

with IWModalWindow1 do 
begin
    Reset;
    Autosize := False;
    Title := 'My Report';
    Draggable := False;
    WindowWidth := 300;
    WindowHeight := 500;
    Src := ReportFile + fextension;
    OnAsyncClick := nil;
    Show;
  end;

Above code didn't display me any window. No popup warning either. Just nothing. I can only download my report file. I also played with "Src", passing temprorary PDF file location or URL didn't help, too.

It should be some minor thing I am missing. Just still cannot see it.
Ertan Kucukoglu

Posts: 49
Registered: 7/4/09
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2015 2:20 AM   in response to: Ertan Kucukoglu in response to: Ertan Kucukoglu
I could overcome my problems IWLabel1 and IWModalWindow not showing. What I did was simply to comment my WebApplication.SendFile line. I have no idea why that line blocks every other thing in the procedure. Is there any way that SendFile call locks file for read while uploading to user?

I am using below string variables (fname, furl) to thread safe reach created PDF report. One of them is a filesystem link, other one is a URL link. At least that's what I'm thinking.

Would someone confirm that they are both accessible with my WebApplication, please?

  // Get temp filename. 
  // Both UserCacheDir and UserCacheUrlBase consecutively returns '\' or '/' at the end.
  fname := WebApplication.UserCacheDir + 'files\' + WebApplication.AppID + 'rapor2.pdf;
  furl  := WebApplication.UserCacheUrlBase + 'files/' + WebApplication.AppID + 'rapor2.pdf';


I know that I can reach fname because WebApplication.SendFile works as expected. However, IWModalWindow1 code above is saying me

Src := fname and I see nothing in popup window. It is empty. No scroll bars or anything.
Src := furl and I read "404 - Not Found" in popup window.

I get below values in variables at run time.

fname: C:\Users\Ertan\AppData\Local\Temp\01amktjexv\user\3qL6~rv9tu2Kz1QNzwjxIq\files\3qL6~rv9tu2Kz1QNzwjxIqrapor2.pdf
furl: /$/MyApp/3qL6~rv9tu2Kz1QNzwjxIq/files/3qL6~rv9tu2Kz1QNzwjxIqrapor2.pdf

Thanks.
Daniel Fields

Posts: 622
Registered: 11/29/04
Re: Using fastreport
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 15, 2015 12:48 AM   in response to: Ertan Kucukoglu in response to: Ertan Kucukoglu
I gave you incomplete instructions for the label. They <Object> tag was left unclosed. You have to add '</object>' to the end of the IWLabel1.Caption. I created a demo that shows a PDF embedded into the form, and also shows how to display a PDF in a modal window. I used a region inside the modal window to gain better control over the appearance.

https://onedrive.live.com/redir?resid=D26292E04DF972AD!1499&authkey=!ACOBPJCtnQwEZVc&ithint=file%2czip

The filenames and locations can get confusing. The UserCacheDir is a temporary folder for the current session. It is in standard Windows file name format. You should use it with system controls and functions, such as LoadFromFile for an image. The UserCachUrlBase points to the same location, but it is in URL format, and seems to be only a partial path. I have never used it in an application.

You also seem to be confusing the "files" subfolder. That should be part of your application's folder structure, which should look like this:

-MyApplicationFolder
---wwwroot
---files

wwwroot is a public folder for your application. You can store static content there and anyone can get to it through your application's server functions. If you place a picture in wwwroot, it would be accessible like this mydomain.com:8888/mypicture.com. Your application would function like a standard web content server and deliver that file from wwwroot. You can put sub folders there to contain anything you want. I have even loaded small websites into the a subfolder and redirected users to it.

The files subfolder is private to your application. It is accessible to each session of your application, but cannot be called from an outside URL. You can put anything you want there, but you should also place images there that you plan to use as resources inside the application. This is where you should set MyImage.ImageFile.Filename. That will ensure that the application will resolve those links at runtime. Even when you move the application to another machine. If you point images to files outside the wwwroot or wwwroot/files folder, the images will be broken at runtime when the application is moved.

So your file name assignment should look like this: fname := WebApplication.UserCacheDir + WebApplication.AppID + 'rapor2.pdf. You should not use UserCacheUrlBase because it has been deprecated according to the documentation. (see http://docs.atozed.com/docs.dll/classes/TIWApplication.html). A new method of handling cache files was introduced that uses a class, TIWAppCache. See http://docs.atozed.com/docs.dll/classes/TIWAppCache.html.

There is a demo on how to use it here http://iwdemos.codeplex.com/SourceControl/latest. Select Atozed Demos, then your version, then Delphi and then CacheFiles. For your current test I would use System.DeletFilee() to remove the file in an event. That way you can control the file instead of waiting on the application to clean up the cache. I say that because you could end up with brief period of cache clutter for multiple sessions depending upon your ServerController.SessionTimeout.

Edited by: Daniel Fields on Oct 15, 2015 1:36 AM
Ertan Kucukoglu

Posts: 49
Registered: 7/4/09
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 15, 2015 12:49 PM   in response to: Daniel Fields in response to: Daniel Fields
Daniel Fields wrote:
I gave you incomplete instructions for the label. They <Object> tag was left unclosed. You have to add '</object>' to the end of the IWLabel1.Caption. I created a demo that shows a PDF embedded into the form, and also shows how to display a PDF in a modal window. I used a region inside the modal window to gain better control over the appearance.

Thank you. I learned how to use TIWRegion better with your sample project. Why did you choose to use OnAsynClick event and not OnClick?

You also seem to be confusing the "files" subfolder. That should be part of your application's folder structure, which should look like this:

Structure you gave, is it a must to use for my application deployment? For example, I can put my "rapor2.fr3" file in files subfolder of my application, and I can load it from there. What if I don't have any thing to put there? Should I create it as an empty subfolder? Is this same way with wwwroot?

So your file name assignment should look like this: fname := WebApplication.UserCacheDir + WebApplication.AppID + 'rapor2.pdf. You should not use UserCacheUrlBase because it has been deprecated according to the documentation. (see http://docs.atozed.com/docs.dll/classes/TIWApplication.html). A new method of handling cache files was introduced that uses a class, TIWAppCache. See http://docs.atozed.com/docs.dll/classes/TIWAppCache.html.

I read TIWAppCache details. Saw example there. I also checked and understood demo. I will post here my final code in a separate reply which is working finally. PDF is displayed in TIWLabel object and, I didn't use TIWModalWindow for the time being.

For your current test I would use System.DeletFilee() to remove the file in an event. That way you can control the file instead of waiting on the application to clean up the cache. I say that because you could end up with brief period of cache clutter for multiple sessions depending upon your ServerController.SessionTimeout.

I am not sure that I understand your explanation for why I should manually delete that report file by code like in a close form event than letting UserSession to do the job.
Daniel Fields

Posts: 622
Registered: 11/29/04
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 15, 2015 7:50 PM   in response to: Ertan Kucukoglu in response to: Ertan Kucukoglu
The subfolder structure (wwwroot\files) is only required for content. If you do not have any, it will not hurt anything to have the empty folders. I do it in all cases out of habit. I also use CGDev Tools, which uses jquery. That library requires folders under wwwroot to support styles and library files. The files subfolder is optional. I use it because it makes the content inaccessible unless they go through a session in the application. This adds extra protection to assets that may require restricted access.

My comment about deleting the file were just a suggestion. If you rely on the cache to clean up files, it may not happen as fast as you like. Many times users will abandon sessions without logging out, which means they remain active until they timeout according to ServerController.SessionTimeout. If you delete the files by code after the user has finished, you will be certain that they have been removed. Either way works fine.

Your code looks great! I'm glad you got it working the way you wanted.
Ertan Kucukoglu

Posts: 49
Registered: 7/4/09
Re: Using fastreport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 15, 2015 1:15 PM   in response to: Daniel Fields in response to: Daniel Fields
Here is my working code for displaying my PDF report on the screen.

1) I included some units in my uses clause, and set some my personal constants

implementation
 
uses ServerController, UserSessionUnit, IWAppCache, IW.CacheStream;
 
{$R *.dfm}
 
const expPDF  = 0;
const expXLSX = 1;
const expCSV  = 2;

2) Then I used MemoryStream and TIWAppCache to get thread safe URL

procedure TIWForm1.ReportExport(WhatToExport: Word; ReportFile: string; rptObj: TfrxReport; pdfObj: TfrxPDFExport; xlsxObj: TfrxXLSXExport; csvObj: TfrxCSVExport);
var
  fname, furl, ftype, fextension:string;
  fstream: TMemoryStream;
begin
  if not TFile.Exists(GetCurrentDir + '\' + ReportFile + '.fr3') then begin  // this code may change to use "files" sub folder in the future
    raise Exception.Create('ERROR: report file does not exists' + #10#13 + GetCurrentDir + '\' + ReportFile + '.fr3');
  end;
 
  // Get temp filename
  fname := WebApplication.UserCacheDir + WebApplication.AppID + ReportFile;
 
  // set some application parameters
  case WhatToExport of
    expPDF: begin
      fextension := '.pdf';
      fname      := fname + fextension;
      ftype      := 'pdf';
    end;
    expXLSX: begin
      fextension := '.xlsx';
      fname      := fname + fextension;
      ftype      := 'xlsx';
    end;
    expCSV: begin
      fextension := '.csv';
      fname      := fname + fextension;
      ftype      := 'csv';
    end;
  end;
 
 
  ForceDirectories(ExtractFileDir(fname));
 
  // DestroyForms can be switched off, if every time a report is renewed from a file
  // or from the current report
  rptObj.EngineOptions.DestroyForms := False;
  rptObj.EngineOptions.SilentMode := True;
  rptObj.EngineOptions.EnableThreadSafe:=true;
  rptObj.ShowProgress := false;
  rptObj.EngineOptions.UseFileCache:=false;
  rptObj.ReportOptions.Compressed := True;
  rptObj.EngineOptions.UseGlobalDataSetList := False; // This property switches off the search of the global list
 
  rptObj.LoadFromFile(GetCurrentDir + '\' + ReportFile + '.fr3');
  // Try to load report file
  if rptObj.PrepareReport(true) then
  begin
    case WhatToExport of
      expPDF: begin // PDF EXPORT
        pdfObj.FileName := fname;
        pdfObj.ShowDialog := false;
        pdfObj.ShowProgress := false;
        pdfObj.OverwritePrompt := false;
        rptObj.Export(pdfObj);
      end;
      expXLSX: begin // XLSX EXPORT
        xlsxObj.FileName := fname;
        xlsxObj.ExportPageBreaks := false;
        xlsxObj.OverwritePrompt := false;
        xlsxObj.DataOnly := true;
        xlsxObj.EmptyLines := false;
        xlsxObj.ShowDialog := false;
        xlsxObj.ShowProgress := false;
        rptObj.Export(xlsxObj);
      end;
      expCSV: begin // CSV EXPORT
        csvObj.FileName := fname;
        csvObj.OverwritePrompt := false;
        csvObj.DataOnly := true;
        csvObj.UTF8 := false; // making this true broke localized characters in my case
        csvObj.ForcedQuotes := true;
        csvObj.ShowDialog := false;
        csvObj.ShowProgress := false;
        rptObj.Export(csvObj);
      end;
    end;
 
    fstream := nil;  // My way of suppressing warning about "variable might not be initialized"
    try
      fstream := TMemoryStream.Create; // Get file stream ready
      fstream.LoadFromFile(fname);     // Load temporary PDF file in the stream
      // Here we upload our file stream into cache and function returns us an URL link accessible by outside world.
      furl := TIWAppCache.StreamToCacheFile(Self, fstream, 'application/pdf', ctSession);
      // Our final code to display PDF in a IWLabel
      // Don't forget. IWLabel is placed in a IWRegion for easier handling.
      IWLabel1.RawText := True; // Necessary
      IWLabel1.Align   := alClient;  // Set to maximum size of IWRegion
      IWLabel1.Caption := '<object data="' + furl + '" type="application/pdf" '
                       +'width="100%" '  // Use maximum width of IWLabel1
                       +'height="100%"></object>';  // Use maximum height of IWLabel1
    finally
      fstream.Free;  // Don't forget that!
    end;
 
  end else begin
    raise Exception.Create('Reporting error');
  end;
end;
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02