XFRX
Developer’s guide
© 2005 Martin Haluza
EQEUS.COM
XFRX version: 10.2
Document version: 1.2
Last update: 12:05, April 20, 2005
The latest version of this document is available at: http://www.eqeus.com.
Trademarks: Microsoft, Visual FoxPro, .NET, Visual C#, ASP.NET, Word, Excel and ActiveX are either trademarks or registered trademarks of Microsoft Corporation.
4.1 How XFRX handles different version of Visual FoxPro
4.2 Differences between XFRX for VFP 8.0 and XFRX for VFP 9.0
4.3 Distributing XFRX with other applications
5.1 Running XFRX in VFP 5.0, 6.0, 7.0 and 8.0
5.3 Using THISFORM and THIS references
5.4 Displaying progress bar in VFP 8
5.5 Displaying progress bar in VFP 9
5.6 Canceling report generation in progress
5.9 Zipping the generated files
7.4 Appending generated output to existing PDF Documents
9 Flow layout Word document option
10.1 HTML page size adjustment
11.3.1 Generating sheet per page
11.3.2 Generating sheet per start-each-group-on-a-new-page groups.
11.5 Hiding the Excel sheet grid
11.6 Leaving the fields content in Excel cells
11.7 How to invoke the XLS output
11.9 How to achieve the best results
11.10 Numeric field picture format in Excel
12 Converting reports to plain text
12.4 Characters per inch setting
13.2 Initializing the XFFWriter class instance
13.3 Creating temporary XFF files
13.4 Converting XFF files to other output formats
14.1 Adding the previewer container to a form
14.3 Printing from the previewer
15 Converting reports to pictures
16 Chaining listeners in VFP 9
17 Running XFRX in a web-based environment
18.2 Methods common in XFRXListener and XFRXSession classes
|
Date |
XFRX version |
Document modifications |
|
March 28, 2005 |
10.2 |
New chapters: Defining sheet names in XLS documents (page 26) Hiding the Excel sheet grid (page 26) Leaving the fields content in Excel cells (page 26) Printing XFF files, chapter Printing XFF files (page 36)
Updated chapters: Handling page breaks in XLS output (page 25) Using XFF files (page 34) XFRX previewer (page 37) XFFWriter class reference (page 54)
|
|
December 29, 2004 |
10.1 |
New chapters: Appending generated output to existing PDF Documents on page 19. |
XFRX is a tool for transforming Visual Foxpro reports to electronic formats. It can be incorporated into Visual Foxpro applications and used to provide end users with an option to:
XFRX is a royalty-free product, so it can be added to Visual Foxpro applications without any additional costs. Please read the License for more details.
XFRX is available for Visual FoxPro 5.0, 6.0, 7.0, 8.0 and 9.0. XFRX contains its own report engine which is used in VFP 8.0 and earlier. In VFP 9.0, XFRX plugs into the new reporting architecture of the native report engine.
The differences between XFRX for VFP 5.0, 6.0, 7.0 and 8.0 and XFRX for VFP 9.0 are described in detail in this document.
Please note: To make the text easier to read, these differences are described as differences between VFP 8.0 and VFP 9.0. If VFP 8.0 is mentioned further in the text, it applies for VFP 5.0, 6.0 and 7.0 as well.
Evaluation version quick tip: For a quick preview of the capabilities of XFRX, unpack the whole zip archive to an empty directory and run DEMO.SCX.
XFRX consist of the following parts:
The installation is very easy: simply unpack the zip archive and make sure the files are accessible from VFP (they can either be placed in a local directory or the path can be set via the SET PATH command).
XFRX for VFP 8 contains its own report engine that mimics the behavior of the native Visual FoxPro report engine.
XFRX for VFP 9 is implemented as an XFRXListener class, a descendant of UtilityReportListener class (please see _REPORTLISTENER.VCX in FFC for more information about the basic report listener classes provided by FFC). The XFRXListener class complies with the object-assisted reporting standards introduced in VFP 9 and perfectly fits into the new open architecture. You can use it alone or in combination with other report listeners provided with the product or by third parties.
About 95% of XFRX is written in Visual FoxPro and, to make the deployment as easy as possible, all its source code (without the visual classes for the report previewer container) is in one PRG file, both for VFP 8.0 and VFP 9.0: XFRX.PRG. This PRG file is the same for all VFP versions.
If you purchase XFRX without source codes, you will be able to download XFRX.FXP compiled in the VFP version you are using.
If you purchase the source code, before you add XFRX.PRG into your project and compile it, you need to enable (uncomment) one of the #DEFINE commands at the beginning of XFRX.H, which determines the VFP version you are using.
Example: If XFRX is used in VFP 8.0, the beginning of XFRX.H would look
like this:
*#DEFINE VFP5
*#DEFINE VFP6
#DEFINE VFP8
*#DEFINE VFP9
(Please note there is not a constant for VFP 7.0. If you are using VFP 7.0, uncomment VFP6).
As written in the previous paragraph, XFRX for VFP 9.0 uses the native report engine, which results in the following advantages:
The best way to distribute XFRX is to include XFRX.FXP (or XFRX.PRG, if you purchased the source code option) into the target application’s exe (add it to your project, to the section where your PRGs are). This way, you won’t have to distribute this file and, more importantly, XFRX will be able to access the reports and other resource files (pictures, tables, etc.) built into the exe as well.
If you are using the XFRX previewer, add the appropriate files from the XFRXLIB directory to your project as well.
The support libraries (XFRXLIB.FLL, HNDLIB.DLL and ZLIB.DLL) cannot be included in the exe and need to be distributed along with the application. They need to be located either in the same directory where the main EXE is or in a directory defined in SET PATH command.
When XFRX is run, it returns an instance of one of three classes, depending on a parameter passed. The available parameters are:
Important note: The evaluation version of XFRX cannot be included into VFP projects, it makes VFP crash. The avoid this please invoke XFRX via macro substitution:
loSession = EVALUATE("xfrx('XFRX#INIT')")
This way XFRX.APP does not get into the project and you will be able to compile your application without problems.
Please note: To make the text easier to read, the
differences between XFRX for VFP 5.0, 6.0, 7.0, 8.0 and XFRX for VFP 9.0 are
further in the text described as differences between VFP 8.0 and VFP 9.0. If
VFP 8.0 is mentioned, the described feature applies for VFP 5.0, 6.0 and 7.0 as
well.
Example 1:
This code merges two reports – report1 and report2 – into a single PDF document, output.pdf
use demoreps\invoices order customer
local loSession, lnRetval
loSession= xfrx("XFRX#INIT")
lnRetVal = loSession.SetParams("output.pdf",,,,,,"PDF")
If lnRetVal = 0
loSession.ProcessReport("report1")
loSession.ProcessReport("report2")
loSession.finalize()
Else
? lnRetVal
Endif
In VFP 9.0, the standard object-assisted mode is used to run XFRX:
Note: Even in VFP 9.0, you can initialize the XFRXSession class via “XFRX#INIT” parameter and use the XFRX’s own engine, rather than the native one.
The following examples all do exactly the same (and they also do exactly the same as the example 1 above), showing various ways of calling XFRX in VFP 9.0:
Example 2:
use demoreps\invoices order customer
local loSession, lnRetval
loxfrx = XFRX("XFRX#LISTENER")
lnRetval = loxfrx.SetParams("output.pdf",,,,,,"PDF")
IF lnRetval = 0
REPORT FORM report1 OBJECT loxfrx NOPAGEEJECT
REPORT FORM report2 OBJECT loxfrx
ELSE
? lnRetval
endif
Example 3:
use demoreps\invoices order customer
local loSession, lnRetval
loxfrx = XFRX("XFRX#LISTENER")
lnRetval = loxfrx.SetParams("output.pdf",,,,,,"PDF")
IF lnRetval = 0
REPORT FORM report1 OBJECT loxfrx NOPAGEEJECT
REPORT FORM report2 OBJECT loxfrx NOPAGEEJECT
Loxfrx.finalize()
ELSE
? lnRetval
endif
Example 4:
use demoreps\invoices order customer
local loSession, lnRetval
loxfrx = XFRX("XFRX#LISTENER")
loxfrx.targetType = "PDF"
loxfrx.targetFileName = "output.pdf"
lnRetval = loxfrx.SetParams()
IF lnRetval = 0
REPORT FORM report1 OBJECT loxfrx NOPAGEEJECT
REPORT FORM report2 OBJECT loxfrx
ELSE
? lnRetval
endif
Note: This paragraph applies to VFP 8 only. THISFORM and THIS references are handled properly by the native report engine in VFP 9.
XFRX supports using THISFORM and THIS in the expressions of the report fields. However, being normal VFP application, XFRX cannot access THISFORM and THIS objects directly. Instead, THISFORM object has to be explicitly sent to XFRX via setThisform() method, THIS needs to be sent via setThis() method. The use is very simple.
If you have THISFORM in your report, call xfrxSession.setThisform(THISFORM) before calling ProcessReport(). If you are using THIS, call xfrxSession.setThis(THIS).
XFRX provides a simple hook so that any progress bar tool could be used for displaying the progress during the document generation process. All you have to do is to create an object which contains updateProgress() method and pass it to XFRX. During the generation process, XFRX calls updateProgress() method either after each page or after each record is processed.
This is a simple example of displaying the generation progress in a wait window:
loSession=xfrx("XFRX#Init")
loProgress = createobject("progress")
lnRetVal = loSession.SetParams("document",,,,,,"PDF")
if lnRetVal = 0
loSession.setProgressObj(loProgress,2)
loSession.ProcessReport("myReport")
loSession.finalize()
endif
define class progress as custom
procedure updateProgress
lpara ta,tb, tc
wait window nowait "Page #:
"+allt(str(tb))+" Report #: "+allt(str(ta))+"
("+allt(str(tc))+"%)"
enddef
The progress
object is attached to XFRX with setProgressObj() method. This method takes two
parameteres - the first one is the progress object, the second defines the
information the updateProgress() will be getting. It can contain two values: 1
- only page number and report number will be provided in updateProgress()
method, or 2 - page number, report number and percentage progress within the current
report will be provided. Using the percentage progress information is more
accurate and more suitable for progress bar visualization, but to provide this,
XFRX has to calculate the number of records in the processed table, which,
sometimes, can be very time demanding. In this cases, 1 can be used not to
calculate the number of records.
The updateProgress method takes three parameteres: current report number,
current page number and actual percentage progress within the current report.
In VFP 9.0, the XFRXListener object can be chained together with another listener which would take care of the progress bar displaying. One of the possible ways to do this is to use the UpdateListener class, which is shipped with VFP 9.0, in FFC.
Example:
This sample code creates an instance of the UpdateListener class and chains it with XFRXListener:
loxfrx = XFRX("XFRX#LISTENER")
SET CLASSLIB TO (HOME()+"FFC\_reportlistener.vcx")
loUpdate = CREATEOBJECT("updatelistener")
loUpdate.thermFormCaption = "Report in progress ..."
loxfrx.successor = loUpdate
lnRetval = loxfrx.setparams("output.pdf",,,,,,"PDF")
IF lnRetval == 0
REPORT FORM (lcReportName) OBJECT loxfrx NOPAGEEJECT
loxfrx.finalize()
ELSE
? lnRetval
endif
Note: This paragraph applies both to VFP 9 and VFP 8.
The report generation process in progress can be canceled by setting the global variable gnStopXFRX to 1. For example, you can, for example, use it this way:
ON KEY LABEL Ctrl+C gnStopXFRX = 1
Note: This paragraph applies to VFP 8 only. In VFP 9, please use the RANGE clause of the REPORT FORM command to achieve the same.
To define the page range, call setPageRange() method before calling calling ProcessReport(). There are two possible ways how to call the setPageRange() method:
loSession.setPageRange(5,10)
loSession.setPageRange("1,4,10-20,25")
Note: This paragraph applies both to VFP 8 and VFP 9.
You can define the page size of the generated document. The user-defined page size will override the page size stored in the report. To define the user-defined page size, call setPaperSize() method with paper width and paper height as parameters:
setPaperSize(nUDPaperWidth, nUDPaperHeight)
The unit is Inch * 10000.
See also: HTML page size adjustment on page 24.
Note: This paragraph applies both to VFP 8 and VFP 9.
The generated file can be automatically zipped. This feature is controlled by the last three parameters of SetParams() method of XFRXSession and XFRXListener classes (see the reference on page 45) or, with an equivalent behavior, by the three parameters of ZipDocument() method of XFRXListener class (reference on page 52).
Example:
With the following SetParams parameters, XFRX first creates "invoices.pdf", then creates "archive.zip" (if it doesn't exist) and adds "invoices.pdf" into the archive. Then the original "invoices.pdf" will be deleted:
loSession.SetParams("invoices.pdf",,.T.,,,,"PDF","archive.zip", .t., .t.)
The generated documents can include hyperlinks for faster navigation, PDF documents can also include bookmarks. The hyperlinks and bookmarks are controlled via Comment field of labels and fields.
Please note: In the beta version of VFP 9 there is a bug that makes it impossible to store anything into fields’ comment. Because XFRX uses the comment field to define hyperlinks and bookmarks, the “User data” field is now used for this purpose. In the final version, XFRX for VFP 9 will work both with comment and user data field.
Note: This paragraph applies both to VFP 9 and VFP 8.
The hyperlinks are controlled via Comment
field of report labels or fields.
To create a link, you need a source field (the underlined text you will
navigate from) and a target field (the place where you get when you click on a
hyperlink).
o
Creating source fields
Enter the following text into the comment of the source field:
#UR A HREF=<destination name>
The destination name is an expression, which is evaluated at the time of report generation. You can navigate to other fields in the same document, or to any URL. The destination names of other fields in the same document has to be preceeded with #.
Examples:
#UR A HREF="#top"
Navigates to the beginning of the document. "top" is a reserved word. Do not name target fields are "top".
#UR A HREF="#custlist"
Navigates to the field whose destination name is "custlist".
#UR A HREF="#"+customer.id
Navigates to the field whose destination name is eval(customer.id)
#UR A HREF="http://www.eqeus.com"
Navigates to Eqeus.com homepage
o Creating target fields
To add a destination name to a (target) field, add the following text into the
comment:
#UR A NAME=<destination name>
Example:
#UR A NAME=customer.id
This field will be a target field for source fields with HREF="#"+customer.id
Note: This paragraph applies both to VFP 9 and VFP 8.
Note 2: Bookmarks are currently supported in PDF and HTML documents
Bookmarks (document outline) serves as a "visual table of contents"
to display the document structure. Users use this to interactively navigate in
the document. To add a report field into the document outline simply put the
following into the field's comment:
#UR OUTLINE=<outline_name>
The outline_name is an expression, which is evaluated at the time of report generation and the result is used as the bookmark item. If users click the bookmark, they will navigate to the corresponding report field.
Example:
In a report with a list of invoices grouped by customers, bookmarks containing the list of customer can be created by adding
#UR OUTLINE=invoices.customerName
into the comment of a customer name field (or any other field you want to navigate to, e.g. the first field on a page with the customer).
To enable bookmarks in the HTML output, call
loSession.SetOtherParams("PRINT_BOOKMARKS",.t.)
before calling loSession.ProcessReport()
With bookmarks enabled, XFRX will generate three HTML pages (three files): the main page defining the page frames, the bookmark page and the page with the report output.
Note: This paragraph applies both to VFP 9 and VFP 8. The set… methods are implemented both in XFRXListener and XFRXSession classes.
The following methods can be called to set various document properties. When generating a Word document, all document properties have to be set before the first report is processed. When exporting to PDF, the properties have to be set before Finalize() method is called.
loSession.setAuthor(<author>)
loSession.setTitle(<title>)
loSession.setSubject(<subject>)
loSession.setKeywords(<keywords>)
loSession.setCreator(<creator>)
loSession.setProducer(<producer>)
loSession.setComments(<comments>)
loSession.setCategory(<category>)
loSession.setManager(<manager>)
loSession.setCompany(<company>)
Note: This paragraph applies both to VFP 9 and VFP 8. The setPasswords method is implemented both in XFRXListener and XFRXSession classes.
PDF documents can be encrypted. To set the encryption on, call setPasswords method:
loSession.setPasswords(tcOwnerPassword, tcUserPassword)
The user password can be empty. If the
owner password is empty, a random string will be generated as the password.
The owner can do anything with the document. The user permissions can be set
using the setPermission method:
loSession.setPermissions(tlPrintDocument, ;
tlModifyDocument, ;
tlCopyTextAndGraphics, ;
tlAddOrModifyAnnotations)
The default values of the permissions is .F. (false).
Note: This paragraph applies both to VFP 9 and VFP 8. The method is implemented both in XFRXListener and XFRXSession classes.
XFRX supports both whole font and font subset embedding.
To embed all characters of all used fonts, call:
loSession.setEmbeddingType(2)
before running the report.
To embed only the characters used, call:
loSession.setEmbeddingType(3)
Embedding only subset of fonts (characters used in the document) significantly reduces the size of the generated file.
To select which font to embed (e.g. when you need just to embed the barcode font, or font that is not installed on the pc the document will be sent to), add “#UR INCLUDEFONT” (without the quotation marks) to the comments of a field that uses the font (in the report). Add “#UR INCLUDEFONT SUBSET” comment to include the font subset.
Note: This paragraph applies both to VFP 9 and VFP 8.
To rotate a text or a picture in PDF output, add “#UR ROTATE” (without the quotation marks) to the comment of the report field. The text or the picture will rotate anticlockwise by the entered angle, e.g. to print vertically, add: “#UR ROTATE 90”.
Note: This paragraph applies both to VFP 9 and VFP 8.
From version 10.1, XFRX is able to append the generated report to an existing PDF document. It is possible to append the report at the end of the document or at an arbitrary position within the document: with either inserting the new pages or replacing the pages in the existing PDF document.
In XFRX for VFP 8 this feature is controlled by a new parameter of SetParams(…) method: tuAppend. Please see the SetParams method reference on page 45 for more information about setting this parameter.
In XFRX for VFP 9 you can interchangeably use the new parameter of SetParams(…) method or AppendToFile property of the XFRXListener class.
Notes:
Note: This paragraph applies both to VFP 9 and VFP 8. The setPasswords method is implemented both in XFRXListener and XFRXSession classes.
To add passwords to Word documents, call SetPasswords() method before calling ProcessReport():
loSession.setPasswords(tcReadPassword, tcWritePassword, tlRequirePassword)
You can omit either tcReadPassword or tcWritePassword. tlRequirePassword is optional (default value is .F.). If set to .T., Word will ask for the password even when the document is being opened first time after the generation (if tlNotOpenViewer parameter of SetParams method is set to .F.).
Note: This paragraph applies to VFP 8 only.
When the generated documents are very long, Word application has problem with the conversion - it takes very long to convert it. To avoid this problem, XFRX can split the generated document into more smaller documents. To set this up, call SplitDocument() method before calling ProcessReport():
loSession.SplitDocument(tnPages)
tnPagesp is the number of pages each of the resulting documents would have.
Note: This chapter links to several sample documents at our web site. If you are reading an electronic version of this document, simply click the hyperlinks to download them. If you are reading a printed version, here are the addresses:
http://www.eqeus.com/xfrxmanual/example1.doc
http://www.eqeus.com/xfrxmanual/example2.doc
http://www.eqeus.com/xfrxmanual/example3.doc
http://www.eqeus.com/xfrxmanual/example4.doc
There are two output options that produce Word documents – Absolute positioned layout (DOC) and Flow layout (FDOC). The generated documents often look the same, but the algorithms behind these options are completely different. The absolute positioned layout always looks like the original report, but is hard to edit and bigger in size. The flow layout may not always look exactly the same, but it is a 'real' Word document - easily editable, with styles, page headers and footers, paragraphs and tab stops, which is also shorter in size and faster to open.
This chapter describes the Flow layout (FDOC) output option – how it works and how it differs from the Absolute positioned layout (DOC).
Flow layout Word option is implemented as a new target type, so simply send “FDOC” as the tcTarget parameter of the SetParams() method.
The logic is similar to the way how plain text option works. During the generation process, XFRX takes each section – one by one – and tries to split it to individual lines. Then each line is added to the output, respecting the vertical position of the line on the paper and horizontal positions of individual objects. Vertically misaligned objects are moved down to the closest baseline.
Example 1:
This report definition:

will be split to three lines and the resulting document will look like this:

(download example1.doc)
As you can see all objects are aligned to the same baseline and the horizontal
position is set by a tab stop (left, right or center, depending on the field’s
alignment). If you add any graphics or pictures, these are added to the
document and linked to the paragraph it starts at, so if you add contents above
the graphics, it will move down along with the corresponding paragraph.
If XFRX cannot create distinct lines or if the text objects overlap one another, the overlapping text object is placed at the exact position as a textbox.
Example 2:
|
|
>> converts to >> |
(download example2.doc) |
Page headers and footers defined in the report are converted to page headers and footers in the Word document, so for example, if you add a line in the middle of a page, the page footer will not move to the next page header, but stay in place.
Even though most reports are converted without problems, there are certain scenarios when the output wouldn’t look as expected. As stated above, all fields in one line are aligned to the same baseline. In some reports, this can cause a problem, for example:
|
|
>> converts as >> |
(download example3.doc) |
Not only is the “two” text too below, it is also printed over the “three” one (“three” is placed too high to be on a separate line, so it is converted as a textbox). In this case, you may want to tell the engine that “two” and “three” objects should always be treated as absolute positioned textboxes.
To do this, add “#UR POSITIONABSOLUTE” as a comment of these fields:

And the resulted Word document would be generated as:
|
(download example4.doc) |
Note: This paragraph applies both to VFP 9 and VFP 8. The ShrinkHeight method is implemented both in XFRXListener and XFRXSession class.
When generating HTML documents, XFRX makes the page a bit shorter by default (by 1.65 inches). This is to suppress the bottom of a page to wrap to a new page when printing from the Internet Explorer. Two lines are added to the printed page - at the top and bottom of the page - as header and footer. By calling ShrinkHeight() method, you can either suppress this behaviour by calling:
ShrinkHeight(0)
or set your own value by which the page will be shrinked. The unit is Inch * 10000, so to make the page shorter by 2 inches, call:
ShrinkHeight(20000)
The value sent by ShrinkHeight() method is applied to all output types, not just HTML.
See also: User-defined page size on page 13.
The output to the Excel format is similar to the flow layout formats. The other formats use absolutely positioned textboxes for each report label or textbox, containing the generated text output. The XLS output, on the other hand, puts the generated text directly into the cells on the Excel sheet and sets the height of the rows and width of the columns to achieve the desired layout. Lines and rectangles, too, are added as cells' borders, rather than graphics over the sheet.
There are many advantages in this approach: the generated documents are smaller and much easier to be modified - all numeric fields can be used in calculations, it's no problem to add rows or columns, change cell attributes, etc.
There are, however, downsides, too: The fields cannot overlap, so something like this:
![]()
in the report won't convert correctly, and, as each Excel cell has a margin inside that cannot be suppressed, some fields might have to be made a little wider to accommodate the whole content.
With XFRX, the reports will probably need some tweaking, especially the complicated ones, but the result will be a normal Excel document, as if someone created it manually.
XFRX makes use of the possibility to merge more Excel cells together. Wherever a label or textbox should start or finish, XFRX creates a row and a column. To achieve the best looking results, it is a good thing to align the labels and textboxes both vertically and horizontally - result of which is a clearer document with fewer rows and columns. (Please see more about this below, in How to achieve the best results? paragraph.)
By default, XFRX does not break pages in the XLS output the same way as in other output formats – it is run in the plain mode instead, which means the output is one sheet - as long as it needs to be, with a page header on the top and a page footer at the bottom.
If more reports are processed, each report creates one sheet in the output document.
There are two options you can use to modify the way the page breaks are handled:
To enable this option, call SetOtherParams method to set the “SHEET_PER_PAGE” parameter to .T.:
loSession.SetOtherParams("SHEET_PER_PAGE",.t.)
This will switch off the “plain” mode and the page breaks will correspond to other output options. Each page will be generated as a new sheet in the Excel document.
Please see more information about the SetOtherParams method in Methods common in XFRXListener and XFRXSession classes reference on page 45.
To enable this option, call SetOtherParams method to set the “SHEET_PER_NP_GROUP” parameter to .T.:
loSession.SetOtherParams("SHEET_PER_NP_GROUP",.t.)
This option combines the plain mode and the sheet-per-page mode. The report runs in the plain mode but a new sheet is generated for each report group with “Start each group on a new page” flag set to .T.
There are two ways how to define sheet names. You can define a static text via NEXT_SHEET_NAME parameter, or you can use the NEXT_SHEET_NAME_EXPR parameter to define an expression, which will be evaluated at the bottom of each sheet and the result will be used as the new sheet name. The latter option is useful if more sheets are generated during one report run.
Please see more information about SetOtherParams method in Methods common in XFRXListener and XFRXSession classes reference on page 45.
The background grid is visible by default. To hide it, please set DISPLAY_GRID_LINES parameter to false:
loSession.SetOtherParams("DISPLAY_GRID_LINES",.F.)
By default, the content of non-stretchable fields is cut according to the size of the field, but you can optionally leave the full content of the field in the Excel cell. To enable this option, set the LEAVE_FULL_FIELD_CONTENT parameter to .T.:
loSession.SetOtherParams("LEAVE_FULL_FIELD_CONTENT",.T.)
It is pretty much the same as with the other targets:
local loSession, lnRetval
loSession= xfrx("XFRX#INIT")
loSession.initLog()
lnRetVal = loSession.SetParams("output.xls",,,,,,"XLS")
If lnRetVal = 0
loSession.SetOtherParams("NEXT_SHEET_NAME","first") && the name of the sheet, optional
loSession.ProcessReport("report1")
loSession.SetOtherParams("NEXT_SHEET_NAME","second")
loSession.ProcessReport("report2")
loSession.finalize()
ENDIF
This example creates a two sheet document. As you can see, SetOtherParams() method can be used to define the sheet names. If it is not called, the default names are "sheet1", "sheet2", etc.
When XLS document is generated, the vertical and horizontal coordinates of objects are adjusted - if the difference between two coordinates is smaller than a certain value, the coordinates are 'aligned'. This approach significantly reduces the number of rows and columns in the generated document.
It is possible to define this minimal difference. The greater the number is, the lesser number of rows/columns is generated, but if the number is too big, fields might get overlapped and could be left out.
Call SetOtherParams method with "HORIZONAL_ADJUSTMENT" or "VERTICAL_ADJUSTMENT" to define the minimal horizontal and/or vertical difference.
Example:
loSession.SetOtherParams("HORIZONTAL_ADJUSTMENT",1000) && default value = 76
loSession.SetOtherParams("VERTICAL_ADJUSTMENT",1000) && default value = 180




USE report.frxREPLACE objtype WITH 8 ALL FOR objtype = 5USE
The format
definition of numeric cells in Excel is different from the format syntax used
in Foxpro. XFRX is now able to convert the simple format definitions and allows
for user-defined implicit and/or explicit Excel-type format definitions.
In Visual Foxpro, the numeric field is converted to its text representation
based on an explicit format definition (format field in the report expression
definition) or field's decimal places and SET DECIMAL setting.
When a numeric
field is transformed to an Excel cell, the following algorithm is used:
To define an explicit XLS format for a numeric field, add:
#UR XLSF= (expression)
to the field's comment.
Example 1:
#UR XLSF="General"
The "General" formatting - no special formatting, the number of decimal places is determined by the field's value
Example 2:
#UR XLSF="Standard"
The "Standard" formatting - two decimal places, thousand and decimal separators will be used according to the Excel defaults
Example 3:
#UR XLSF="#0.00"
Two decimal places, no leading zeros
Example 4:
#UR XLSF="#0.00;[red]#0.00"
Two decimal places, display negative
numbers in red
A conversion table can be populated programmatically when XFRX is executed so that the formats that are often used and cannot by converted automatically by XFRX would not require an explicit definition in each field in the report.
To add an entry to the conversion table, use addXLSFormatConversion method of XFRXSession class.
Example 5:
loSession.addXLSFormatConversion("@L
999999.99","000000.00")