Index: src/documentation/content/xdocs/spreadsheet/book.xml =================================================================== --- src/documentation/content/xdocs/spreadsheet/book.xml (revision 1058689) +++ src/documentation/content/xdocs/spreadsheet/book.xml (working copy) @@ -39,6 +39,8 @@ + + Index: src/documentation/content/xdocs/spreadsheet/excelant.xml =================================================================== --- src/documentation/content/xdocs/spreadsheet/excelant.xml (revision 0) +++ src/documentation/content/xdocs/spreadsheet/excelant.xml (revision 0) @@ -0,0 +1,301 @@ + + + + + +
+ ExcelAnt - Ant Tasks for Validating Excel Spreadsheets + + + + +
+ +
ExcelAnt - Ant Tasks for Validating Excel Spreadsheets + +
Introduction +

ExcelAnt is a set of Ant tasks that make it possible to verify or test + a workbook without having to write Java code. Of course, the tasks themselves + are written in Java, but to use this frame work you only need to know a little + bit about Ant.

+

This document covers the basic usage and set up of ExcelAnt.

+

This document will assume basic familiarity with Ant and Ant build files.

+
+
Setup +

To start with, you'll need to have the POI 3.8 or higher jar files. You will + need to have the following files in your path from Ant's perspective:

+
    +
  • excelant-x.x.x.jar
  • +
  • poi-3.8-YYYYDDMM.jar
  • +
  • poi-ooxml-3.8-YYYYMMDD.jar
  • +
  • poi-ooxml-schemas-3.8-YYYYMMDD.jar
  • +
+

For example, if you have these jars in a lib/ dir in your project, your build.xml + might look like this:

+ + + + + + + + + +]]> +

Next, you'll need to define the Ant tasks. (TODO-JDS: I think there is a way to make + it so that users don't have to add the taskdefs to their build files). This is done + using the taskdef tagset:

+ + + + +]]> +

There are actually more tags than this but to start with we will consider these.

+
+ +
A Simple Example +

The simplest example of using Excel is the ability to validate that POI is giving you back + the value you expect it to. Does this mean that POI is inaccurate? Hardly. There are cases + where POI is unable to evaluate cells for a variety of reasons. If you need to write code + to integrate a worksheet into an app, you may want to know that it's going to work before + you actually try to write that code. ExcelAnt helps with that.

+ +

Consider the mortgage-calculation.xls file found in the Examples + (/examples/src/org/apache/poi/ss/examples/excelant/simple-mortgage-calculation.xls). This sheet + is shown below:

+ + + +

This sheet calculates the principal and interest payment for a mortgage based + on the amount of the loan, term and rate. To write a simple ExcelAnt test you + need to tell ExcelAnt about the file like this:

+ + + + + + + + + +]]> + + +

This code sets up ExcelAnt to access the file defined in the ant property + xls.file. Then it creates a 'test' named 'checkValue'. Finally it tries + to evaluate the B4 on the sheet named 'MortgageCalculator'. There are some assumptions + here that are worth explaining. For starters, ExcelAnt is focused on the testing + numerically oriented sheets. The <evaluate> task is actually evaluating the + cell as a formula using a FormulaEvaluator instance from POI. Therefore it will fail + if you point it to a cell that doesn't contain a formula or a test a plain old number.

+ +

Having said all that, here is what the output looks like:

+ + + +
+ +
Setting Values into a Cell +

So now we know that at a minimum POI can use our sheet to calculate the existing value. + This is an important point: in many cases sheets have dependencies, i.e., cells they reference. + As is often the case, these cells may have dependencies, which may have dependencies, etc. + The point is that sometimes a dependent cell may get adjusted by a macro or a function + and it may be that POI doesn't have the capabilities to do the same thing. This test + verifies that we can rely on POI to retrieve the default value, based on the stored values + of the sheet. Now we want to know if we can manipulate those dependencies and verify + the output.

+ +

To verify that we can manipulate cell values, we need a way in ExcelAnt to set a value. + This is provided by the following task types:

+
    +
  • setDouble() - sets the specified cell as a double.
  • +
  • setFormula() - sets the specified cell as a formula.
  • +
  • setString() = sets the specified cell as a String.
  • +
+ +

For the purposes of this example we'll use the <setDouble> task. Let's + start with a $240,000, 30 year loan at 11% (let's pretend it's like 1984). Here + is how we will set that up:

+ + + + + +]]> + +

Don't forget that we're verifying the behavior so you need to put all this + into the sheet. That is how I got the result of $2,285 and change. So save your + changes and run it; you should get the following:

+ + + +
+ +
Getting More Details + +

This is great, it's working! However, suppose you want to see a little more detail. The + ExcelAnt tasks leverage the Ant logging so you can add the -verbose and -debug flags to + the Ant command line to get more detail. Try adding -verbose. Here is what + you should see:

+ + + + +

We see a little more detail. Notice that we see that there is a setting for global precision. + Up until now we've been setting the precision on each evaluate that we call. This + is obviously useful but it gets cumbersome. It would be better if there were a way + that we could specify a global precision - and there is. There is a <precision> + tag that you can specify as a child of the <excelant> tag. Let's go back to + our original task we set up earlier and modify it:

+ + + + + + + + + + + +]]> + +

In this example we have set the global precision to 1.0e-3. This means that + in the absence of something more stringent, all tests in the task will use + the global precision. We can still override this by specifying the + precision attribute of all of our <evaluate> task. Let's first run + this task with the global precision and the -verbose flag:

+ + + + +

As the output clearly shows, the test itself has no precision but there is + the global precision. Additionally, it tells us we're going to use that + more stringent global value. Now suppose that for this test we want + to use a more stringent precision, say 1.0e-4. We can do that by adding + the precision attribute back to the <evaluate> task:

+ + + + + + + + + + +]]> + + +

Now when you re-run this test with the verbose flag you will see that + your test ran and passed with the higher precision:

+ +
+ +
Leveraging User Defined Functions +

POI has an excellent feature (besides ExcelAnt) called User Defined Functions, + that allows you to write Java code that will be used in place of custom VB + code or macros is a spreadsheet. If you have read the documentation and written + your own FreeRefFunction implmentations, ExcelAnt can make use of this code. + For each <excelant> task you define you can nest a <udf> tag + which allows you to specify the function alias and the class name.

+ +

Consider the previous example of the mortgage calculator. What if, instead + of being a formula in a cell, it was a function defined in a VB macro? As luck + would have it, we already have an example of this in the examples from the + User Defined Functions example, so let's use that. In the example spreadsheet + there is a tab for MortgageCalculatorFunction, which will use. If you look in + cell B4, you see that rather than a messy cell based formula, there is only the function + call. Let's not get bogged down in the function/Java implementation, as these + are covered in the User Defined Function documentation. Let's just add + a new target and test to our existing build file:

+ + + + + + + + + + + + +]]> + +

So if you look at this carefully it looks the same as the previous examples. We + still use the global precision, we're still setting values, and we still want + to evaluate a cell. The only real differences are the sheet name and the + addition of the function.

+
+
+ +
\ No newline at end of file Index: src/examples/src/org/apache/poi/ss/examples/excelant/excelant-example.xml =================================================================== --- src/examples/src/org/apache/poi/ss/examples/excelant/excelant-example.xml (revision 0) +++ src/examples/src/org/apache/poi/ss/examples/excelant/excelant-example.xml (revision 0) @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Index: src/examples/src/org/apache/poi/ss/examples/excelant/mortgage-calculation.xls =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: src\examples\src\org\apache\poi\ss\examples\excelant\mortgage-calculation.xls ___________________________________________________________________ Added: svn:mime-type + application/octet-stream