mirror of https://github.com/apache/poi.git
How-to code examples fix.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352298 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e91f14258e
commit
bb124077b5
|
@ -11,13 +11,6 @@
|
||||||
<body>
|
<body>
|
||||||
<s1 title="How to use the HSSF prototype API">
|
<s1 title="How to use the HSSF prototype API">
|
||||||
|
|
||||||
<s2 title="Recent revision history">
|
|
||||||
<ul>
|
|
||||||
<li>12.30.2001 - revised for poi 1.0-final - minor revisions</li>
|
|
||||||
<li>01.03.2001 - revised for poi 1.1-devel</li>
|
|
||||||
</ul>
|
|
||||||
</s2>
|
|
||||||
|
|
||||||
<s2 title="Capabilities">
|
<s2 title="Capabilities">
|
||||||
<p>This release of the how-to outlines functionality for 1.5.
|
<p>This release of the how-to outlines functionality for 1.5.
|
||||||
Those looking for information on the release edition should
|
Those looking for information on the release edition should
|
||||||
|
@ -94,94 +87,99 @@ does not close it for you.
|
||||||
</p>
|
</p>
|
||||||
<p>Here is some example code (excerpted and adapted from
|
<p>Here is some example code (excerpted and adapted from
|
||||||
org.apache.poi.hssf.dev.HSSF test class):</p>
|
org.apache.poi.hssf.dev.HSSF test class):</p>
|
||||||
<source> // create a new file
|
<source><![CDATA[ short rownum;
|
||||||
FileOutputStream out = new FileOutputStream("/home/me/myfile.xls");
|
|
||||||
|
// create a new file
|
||||||
|
FileOutputStream out = new FileOutputStream("workbook.xls");
|
||||||
// create a new workbook
|
// create a new workbook
|
||||||
HSSFWorkbook wb = new HSSFWorkbook();
|
HSSFWorkbook wb = new HSSFWorkbook();
|
||||||
// create a new sheet
|
// create a new sheet
|
||||||
HSSFSheet s = wb.createSheet();
|
HSSFSheet s = wb.createSheet();
|
||||||
// declare a row object reference
|
// declare a row object reference
|
||||||
HSSFRow r = null;
|
HSSFRow r = null;
|
||||||
// declare a cell object reference
|
// declare a cell object reference
|
||||||
HSSFCell c = null;
|
HSSFCell c = null;
|
||||||
// create 3 cell styles
|
// create 3 cell styles
|
||||||
HSSFCellStyle cs = wb.createCellStyle();
|
HSSFCellStyle cs = wb.createCellStyle();
|
||||||
HSSFCellStyle cs2 = wb.createCellStyle();
|
HSSFCellStyle cs2 = wb.createCellStyle();
|
||||||
HSSFCellStyle cs3 = wb.createCellStyle();
|
HSSFCellStyle cs3 = wb.createCellStyle();
|
||||||
// create 2 fonts objects
|
// create 2 fonts objects
|
||||||
HSSFFont f = wb.createFont();
|
HSSFFont f = wb.createFont();
|
||||||
HSSFFont f2 = wb.createFont();
|
HSSFFont f2 = wb.createFont();
|
||||||
|
|
||||||
//set font 1 to 12 point type
|
//set font 1 to 12 point type
|
||||||
f.setFontHeightInPoints((short)12);
|
f.setFontHeightInPoints((short) 12);
|
||||||
//make it red
|
//make it red
|
||||||
f.setColor((short)0xA);
|
f.setColor((short) HSSFCellStyle.RED);
|
||||||
// make it bold
|
// make it bold
|
||||||
//arial is the default font
|
//arial is the default font
|
||||||
f.setBoldweight(f.BOLDWEIGHT_BOLD);
|
f.setBoldweight(f.BOLDWEIGHT_BOLD);
|
||||||
|
|
||||||
//set font 2 to 10 point type
|
//set font 2 to 10 point type
|
||||||
f2.setFontHeightInPoints((short)10);
|
f2.setFontHeightInPoints((short) 10);
|
||||||
//make it the color at palette index 0xf (white)
|
//make it the color at palette index 0xf (white)
|
||||||
f2.setColor((short)0xf);
|
f2.setColor((short) HSSFCellStyle.WHITE);
|
||||||
//make it bold
|
//make it bold
|
||||||
f2.setBoldweight(f2.BOLDWEIGHT_BOLD);
|
f2.setBoldweight(f2.BOLDWEIGHT_BOLD);
|
||||||
|
|
||||||
//set cell stlye
|
//set cell stlye
|
||||||
cs.setFont(f);
|
cs.setFont(f);
|
||||||
//set the cell format see HSSFDataFromat for a full list
|
//set the cell format see HSSFDataFromat for a full list
|
||||||
cs.setDataFormat(HSSFDataFormat.getFormat("($#,##0_);[Red]($#,##0)"));
|
cs.setDataFormat(HSSFDataFormat.getFormat("($#,##0_);[Red]($#,##0)"));
|
||||||
|
|
||||||
//set a thin border
|
//set a thin border
|
||||||
cs2.setBorderBottom(cs2.BORDER_THIN);
|
cs2.setBorderBottom(cs2.BORDER_THIN);
|
||||||
//fill w fg fill color
|
//fill w fg fill color
|
||||||
cs2.setFillPattern((short)1);
|
cs2.setFillPattern((short) HSSFCellStyle.SOLID_FOREGROUND);
|
||||||
// set foreground fill to red
|
// set foreground fill to red
|
||||||
cs2.setFillForegroundColor((short)0xA);
|
cs2.setFillForegroundColor((short) HSSFCellStyle.RED);
|
||||||
|
|
||||||
// set the font
|
// set the font
|
||||||
cs2.setFont(f2);
|
cs2.setFont(f2);
|
||||||
|
|
||||||
// set the sheet name to HSSF Test
|
// set the sheet name to HSSF Test
|
||||||
wb.setSheetName(0,"HSSF Test");
|
wb.setSheetName(0, "HSSF Test");
|
||||||
// create a sheet with 300 rows (0-299)
|
// create a sheet with 300 rows (0-299)
|
||||||
for (rownum = (short)0; rownum < 300; rownum++)
|
for (rownum = (short) 0; rownum < 300; rownum++)
|
||||||
{
|
{
|
||||||
// create a row
|
// create a row
|
||||||
r = s.createRow(rownum);
|
r = s.createRow(rownum);
|
||||||
// on every other row
|
// on every other row
|
||||||
if ( (rownum % 2) == 0) {
|
if ((rownum % 2) == 0)
|
||||||
|
{
|
||||||
// make the row height bigger (in twips - 1/20 of a point)
|
// make the row height bigger (in twips - 1/20 of a point)
|
||||||
r.setHeight((short)0x249);
|
r.setHeight((short) 0x249);
|
||||||
}
|
}
|
||||||
|
|
||||||
//r.setRowNum(( short ) rownum);
|
//r.setRowNum(( short ) rownum);
|
||||||
// create 50 cells (0-49) (the += 2 becomes apparent later
|
// create 50 cells (0-49) (the += 2 becomes apparent later
|
||||||
for (short cellnum = (short)0; cellnum < 50; cellnum += 2)
|
for (short cellnum = (short) 0; cellnum < 50; cellnum += 2)
|
||||||
{
|
{
|
||||||
// create a numeric cell
|
// create a numeric cell
|
||||||
c = r.createCell(cellnum,HSSFCell.CELL_TYPE_NUMERIC);
|
c = r.createCell(cellnum);
|
||||||
// do some goofy math to demonstrate decimals
|
// do some goofy math to demonstrate decimals
|
||||||
c.setCellValue(rownum * 10000 + cellnum
|
c.setCellValue(rownum * 10000 + cellnum
|
||||||
+ ((( double ) rownum / 1000)
|
+ (((double) rownum / 1000)
|
||||||
+ (( double ) cellnum / 10000)));
|
+ ((double) cellnum / 10000)));
|
||||||
|
|
||||||
// on every other row
|
// on every other row
|
||||||
if ( (rownum % 2) == 0) {
|
if ((rownum % 2) == 0)
|
||||||
|
{
|
||||||
// set this cell to the first cell style we defined
|
// set this cell to the first cell style we defined
|
||||||
c.setCellStyle(cs);
|
c.setCellStyle(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a string cell (see why += 2 in the
|
// create a string cell (see why += 2 in the
|
||||||
c = r.createCell((short)(cellnum+1),HSSFCell.CELL_TYPE_STRING);
|
c = r.createCell((short) (cellnum + 1));
|
||||||
|
|
||||||
// set the cell's string value to "TEST"
|
// set the cell's string value to "TEST"
|
||||||
c.setCellValue("TEST");
|
c.setCellValue("TEST");
|
||||||
// make this column a bit wider
|
// make this column a bit wider
|
||||||
s.setColumnWidth((short)(cellnum+1), (short)((50*8) / ((double)1/20)) );
|
s.setColumnWidth((short) (cellnum + 1), (short) ((50 * 8) / ((double) 1 / 20)));
|
||||||
|
|
||||||
// on every other row
|
// on every other row
|
||||||
if ( (rownum % 2) == 0) {
|
if ((rownum % 2) == 0)
|
||||||
|
{
|
||||||
// set this to the white on red cell style
|
// set this to the white on red cell style
|
||||||
// we defined above
|
// we defined above
|
||||||
c.setCellStyle(cs2);
|
c.setCellStyle(cs2);
|
||||||
|
@ -202,9 +200,10 @@ org.apache.poi.hssf.dev.HSSF test class):</p>
|
||||||
cs3.setBorderBottom(cs3.BORDER_THICK);
|
cs3.setBorderBottom(cs3.BORDER_THICK);
|
||||||
|
|
||||||
//create 50 cells
|
//create 50 cells
|
||||||
for (short cellnum = (short)0; cellnum < 50; cellnum++) {
|
for (short cellnum = (short) 0; cellnum < 50; cellnum++)
|
||||||
|
{
|
||||||
//create a blank type cell (no value)
|
//create a blank type cell (no value)
|
||||||
c = r.createCell(cellnum,HSSFCell.CELL_TYPE_BLANK);
|
c = r.createCell(cellnum);
|
||||||
// set it to the thick black border style
|
// set it to the thick black border style
|
||||||
c.setCellStyle(cs3);
|
c.setCellStyle(cs3);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +214,7 @@ org.apache.poi.hssf.dev.HSSF test class):</p>
|
||||||
// demonstrate adding/naming and deleting a sheet
|
// demonstrate adding/naming and deleting a sheet
|
||||||
// create a sheet, set its title then delete it
|
// create a sheet, set its title then delete it
|
||||||
s = wb.createSheet();
|
s = wb.createSheet();
|
||||||
wb.setSheetName(1,"DeletedSheet");
|
wb.setSheetName(1, "DeletedSheet");
|
||||||
wb.removeSheetAt(1);
|
wb.removeSheetAt(1);
|
||||||
//end deleted sheet
|
//end deleted sheet
|
||||||
|
|
||||||
|
@ -223,7 +222,7 @@ org.apache.poi.hssf.dev.HSSF test class):</p>
|
||||||
// close our file (don't blow out our file handles
|
// close our file (don't blow out our file handles
|
||||||
wb.write(out);
|
wb.write(out);
|
||||||
out.close();
|
out.close();
|
||||||
</source>
|
]]></source>
|
||||||
</s4>
|
</s4>
|
||||||
<s4 title="Reading or modifying an existing file">
|
<s4 title="Reading or modifying an existing file">
|
||||||
|
|
||||||
|
@ -281,119 +280,96 @@ registered to listen for until the file has been completely read.
|
||||||
<p>A code excerpt from org.apache.poi.hssf.dev.EFHSSF (which is
|
<p>A code excerpt from org.apache.poi.hssf.dev.EFHSSF (which is
|
||||||
in CVS or the source distribution) is reprinted below with excessive
|
in CVS or the source distribution) is reprinted below with excessive
|
||||||
comments:</p>
|
comments:</p>
|
||||||
<source>
|
<source><![CDATA[
|
||||||
//this non-public class implements the required interface
|
/**
|
||||||
// we construct it with a copy of its container class...this is cheap but effective
|
* This example shows how to use the event API for reading a file.
|
||||||
class EFHSSFListener implements HSSFListener {
|
*/
|
||||||
EFHSSF efhssf;
|
public class EventExample
|
||||||
public EFHSSFListener(EFHSSF efhssf) {
|
implements HSSFListener
|
||||||
this.efhssf = efhssf;
|
{
|
||||||
|
private SSTRecord sstrec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method listens for incoming records and handles them as required.
|
||||||
|
* @param record The record that was found while reading.
|
||||||
|
*/
|
||||||
|
public void processRecord(Record record)
|
||||||
|
{
|
||||||
|
switch (record.getSid())
|
||||||
|
{
|
||||||
|
// the BOFRecord can represent either the beginning of a sheet or the workbook
|
||||||
|
case BOFRecord.sid:
|
||||||
|
BOFRecord bof = (BOFRecord) record;
|
||||||
|
if (bof.getType() == bof.TYPE_WORKBOOK)
|
||||||
|
{
|
||||||
|
System.out.println("Encountered workbook");
|
||||||
|
// assigned to the class level member
|
||||||
|
} else if (bof.getType() == bof.TYPE_WORKSHEET)
|
||||||
|
{
|
||||||
|
System.out.println("Encountered sheet reference");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BoundSheetRecord.sid:
|
||||||
|
BoundSheetRecord bsr = (BoundSheetRecord) record;
|
||||||
|
System.out.println("New sheet named: " + bsr.getSheetname());
|
||||||
|
break;
|
||||||
|
case RowRecord.sid:
|
||||||
|
RowRecord rowrec = (RowRecord) record;
|
||||||
|
System.out.println("Row found, first column at "
|
||||||
|
+ rowrec.getFirstCol() + " last column at " + rowrec.getLastCol());
|
||||||
|
break;
|
||||||
|
case NumberRecord.sid:
|
||||||
|
NumberRecord numrec = (NumberRecord) record;
|
||||||
|
System.out.println("Cell found with value " + numrec.getValue()
|
||||||
|
+ " at row " + numrec.getRow() + " and column " + numrec.getColumn());
|
||||||
|
break;
|
||||||
|
// SSTRecords store a array of unique strings used in Excel.
|
||||||
|
case SSTRecord.sid:
|
||||||
|
sstrec = (SSTRecord) record;
|
||||||
|
for (int k = 0; k < sstrec.getNumUniqueStrings(); k++)
|
||||||
|
{
|
||||||
|
System.out.println("String table value " + k + " = " + sstrec.getString(k));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LabelSSTRecord.sid:
|
||||||
|
LabelSSTRecord lrec = (LabelSSTRecord) record;
|
||||||
|
System.out.println("String cell found with value "
|
||||||
|
+ sstrec.getString(lrec.getSSTIndex()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we just use this as an adapter so we pass the record to the method in the container class
|
/**
|
||||||
public void processRecord(Record record) {
|
* Read an excel file and spit out what we find.
|
||||||
efhssf.recordHandler(record);
|
*
|
||||||
}
|
* @param args Expect one argument that is the file to read.
|
||||||
}
|
* @throws IOException When there is an error processing the file.
|
||||||
|
*/
|
||||||
//here is an excerpt of the main line execution code from EFHSSF
|
public static void main(String[] args) throws IOException
|
||||||
public void run() throws IOException {
|
{
|
||||||
// create a new file input stream with the input file specified
|
// create a new file input stream with the input file specified
|
||||||
// at the command line
|
// at the command line
|
||||||
FileInputStream fin = new FileInputStream(infile);
|
FileInputStream fin = new FileInputStream(args[0]);
|
||||||
// create a new org.apache.poi.poifs.filesystem.Filesystem
|
// create a new org.apache.poi.poifs.filesystem.Filesystem
|
||||||
Filesystem poifs = new Filesystem(fin);
|
POIFSFileSystem poifs = new POIFSFileSystem(fin);
|
||||||
// get the Workbook (excel part) stream in a InputStream
|
// get the Workbook (excel part) stream in a InputStream
|
||||||
InputStream din = poifs.createDocumentInputStream("Workbook");
|
InputStream din = poifs.createDocumentInputStream("Workbook");
|
||||||
// construct out HSSFRequest object
|
// construct out HSSFRequest object
|
||||||
HSSFRequest req = new HSSFRequest();
|
HSSFRequest req = new HSSFRequest();
|
||||||
// lazy listen for ALL records with the listener shown above
|
// lazy listen for ALL records with the listener shown above
|
||||||
req.addListenerForAllRecords(new EFHSSFListener(this));
|
req.addListenerForAllRecords(new EventExample());
|
||||||
// create our event factory
|
// create our event factory
|
||||||
HSSFEventFactory factory = new HSSFEventFactory();
|
HSSFEventFactory factory = new HSSFEventFactory();
|
||||||
// process our events based on the document input stream
|
// process our events based on the document input stream
|
||||||
factory.processEvents(req,din);
|
factory.processEvents(req, din);
|
||||||
// once all the events are processed close our file input stream
|
// once all the events are processed close our file input stream
|
||||||
fin.close();
|
fin.close();
|
||||||
// and our document input stream (don't want to leak these!)
|
// and our document input stream (don't want to leak these!)
|
||||||
din.close();
|
din.close();
|
||||||
// create a new output stream from filename specified at the command line
|
System.out.println("done.");
|
||||||
FileOutputStream fout = new FileOutputStream(outfile);
|
|
||||||
// write the HSSFWorkbook (class member) we created out to the file.
|
|
||||||
workbook.write(fout);
|
|
||||||
// close our file output stream
|
|
||||||
fout.close();
|
|
||||||
// print done. Go enjoy your copy of the file.
|
|
||||||
System.out.println("done.");
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
]]></source>
|
||||||
//here is an excerpt of the recordHander called from our listener.
|
|
||||||
// the record handler in the container class is intent on just rewriting the file
|
|
||||||
public void recordHandler(Record record) {
|
|
||||||
HSSFRow row = null;
|
|
||||||
HSSFCell cell = null;
|
|
||||||
int sheetnum = -1;
|
|
||||||
switch (record.getSid()) {
|
|
||||||
// the BOFRecord can represent either the beginning of a sheet or the workbook
|
|
||||||
case BOFRecord.sid:
|
|
||||||
BOFRecord bof = (BOFRecord) record;
|
|
||||||
if (bof.getType() == bof.TYPE_WORKBOOK) {
|
|
||||||
//if its the workbook then create a new HSSFWorkbook
|
|
||||||
workbook = new HSSFWorkbook();
|
|
||||||
// assigned to the class level member
|
|
||||||
} else if (bof.getType() == bof.TYPE_WORKSHEET) {
|
|
||||||
sheetnum++;
|
|
||||||
// otherwise if its a sheet increment the sheetnum index
|
|
||||||
cursheet = workbook.getSheetAt(sheetnum);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// get the sheet at that index and assign it to method variable
|
|
||||||
// cursheet (the sheet was created when the BoundSheetRecord record occurred
|
|
||||||
case BoundSheetRecord.sid:
|
|
||||||
// when we find a boundsheet record create a new sheet in the workbook and
|
|
||||||
BoundSheetRecord bsr = (BoundSheetRecord) record;
|
|
||||||
// assign it the name specified in this record.
|
|
||||||
workbook.createSheet(bsr.getSheetname());
|
|
||||||
break;
|
|
||||||
// if this is a row record add the row to the current sheet
|
|
||||||
case RowRecord.sid:
|
|
||||||
RowRecord rowrec = (RowRecord) record;
|
|
||||||
// assign our row the rownumber specified in the Row Record
|
|
||||||
cursheet.createRow(rowrec.getRowNumber());
|
|
||||||
break;
|
|
||||||
// if this is a NumberRecord (RKRecord, MulRKRecord get converted to Number
|
|
||||||
// records) then get the row specified in the number record from the current
|
|
||||||
// sheet. With this instance of HSSFRow create a new HSSFCell with the column
|
|
||||||
// number specified in the record and assign it type NUMERIC
|
|
||||||
case NumberRecord.sid:
|
|
||||||
NumberRecord numrec = (NumberRecord) record;
|
|
||||||
row = cursheet.getRow(numrec.getRow());
|
|
||||||
cell = row.createCell(numrec.getColumn(),HSSFCell.CELL_TYPE_NUMERIC);
|
|
||||||
// set the HSSFCell's value to the value stored in the NumberRecord
|
|
||||||
cell.setCellValue(numrec.getValue());
|
|
||||||
break;
|
|
||||||
// if this is the SSTRecord (occurs once in the workbook) then add all of its
|
|
||||||
// strings to our workbook. We'll look them up later when we add LABELSST records.
|
|
||||||
case SSTRecord.sid:
|
|
||||||
SSTRecord sstrec = (SSTRecord) record;
|
|
||||||
for (int k = 0; k < sstrec.getNumUniqueStrings(); k++) {
|
|
||||||
workbook.addSSTString(sstrec.getString(k));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// if this is a LabelSSTRecord then get the row specified in the LabelSSTRecord from
|
|
||||||
// the current sheet. With this instance of HSSFRow create a new HSSFCell with the
|
|
||||||
// column nubmer specified in the record and set the type to type STRING.
|
|
||||||
case LabelSSTRecord.sid:
|
|
||||||
LabelSSTRecord lrec = (LabelSSTRecord) record;
|
|
||||||
row = cursheet.getRow(lrec.getRow());
|
|
||||||
cell = row.createCell(lrec.getColumn(),HSSFCell.CELL_TYPE_STRING);
|
|
||||||
//set the cells value to the string in our workbook object (added in the case
|
|
||||||
//above) at the index specified by the LabelSSTRecord.
|
|
||||||
cell.setCellValue(workbook.getSSTString(lrec.getSSTIndex()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}</source>
|
|
||||||
</s3>
|
</s3>
|
||||||
<s3 title="Low Level APIs">
|
<s3 title="Low Level APIs">
|
||||||
|
|
||||||
|
@ -427,13 +403,15 @@ export CLASSPATH=$CLASSPATH:$HSSFDIR/hssf.jar:$HSSFDIR/poi-poifs.jar:$HSSFDIR/po
|
||||||
</li><li>type:
|
</li><li>type:
|
||||||
<code>java org.apache.poi.hssf.dev.HSSF ~/myxls.xls write</code></li>
|
<code>java org.apache.poi.hssf.dev.HSSF ~/myxls.xls write</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<p></p>
|
||||||
<p>This should generate a test sheet in your home directory called <code>"myxls.xls"</code>. </p>
|
<p>This should generate a test sheet in your home directory called <code>"myxls.xls"</code>. </p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Type:
|
<li>Type:
|
||||||
<code>java org.apache.poi.hssf.dev.HSSF ~/input.xls output.xls
|
<code>java org.apache.poi.hssf.dev.HSSF ~/input.xls output.xls</code>
|
||||||
|
<p>
|
||||||
This is the read/write/modify test. It reads in the spreadsheet, modifies a cell, and writes it back out.
|
This is the read/write/modify test. It reads in the spreadsheet, modifies a cell, and writes it back out.
|
||||||
Failing this test is not necessarily a bad thing. If HSSF tries to modify a non-existant sheet then this will
|
Failing this test is not necessarily a bad thing. If HSSF tries to modify a non-existant sheet then this will
|
||||||
most likely fail. No big deal. </code></li>
|
most likely fail. No big deal. </p></li>
|
||||||
</ul>
|
</ul>
|
||||||
</s3>
|
</s3>
|
||||||
<s3 title="HSSF Logging facility">
|
<s3 title="HSSF Logging facility">
|
||||||
|
@ -510,7 +488,7 @@ intertwined. To use that just pass a file with a second argument
|
||||||
matching "on" exactly.</p>
|
matching "on" exactly.</p>
|
||||||
<p>In the next release cycle we'll also have something called a
|
<p>In the next release cycle we'll also have something called a
|
||||||
FormulaViewer. The class is already there, but its not very useful
|
FormulaViewer. The class is already there, but its not very useful
|
||||||
yet. When it does something, I'll document it.</p>
|
yet. When it does something, we'll document it.</p>
|
||||||
|
|
||||||
</s3>
|
</s3>
|
||||||
<s3 title="What's Next?">
|
<s3 title="What's Next?">
|
||||||
|
|
Loading…
Reference in New Issue