Browse Source

custom data formats patch: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=11068

PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352825 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_1_10
Andrew C. Oliver 22 years ago
parent
commit
b25e15e3d7

+ 33
- 0
src/documentation/xdocs/hssf/quick-guide.xml View File

@@ -29,6 +29,7 @@
<li><link href="#WorkingWithFonts">Working with fonts</link></li>
<li><link href="#ReadWriteWorkbook">Reading and writing</link></li>
<li><link href="#NewLinesInCells">Use newlines in cells.</link></li>
<li><link href="#DataFormats">Create user defined data formats.</link></li>
</ul>
</section>
<section title="Features">
@@ -324,6 +325,38 @@
wb.write( fileOut );
fileOut.close();</source>
</section>
<anchor id="DataFormats"/>
<section title="Data Formats">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFCellStyle style;
HSSFDataFormat format = wb.createDataFormat();
HSSFRow row;
HSSFCell cell;
short rowNum = 0;
short colNum = 0;

row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(11111.25);
style = wb.createCellStyle();
style.setDataFormat(format.getFormat("0.0"));
cell.setCellStyle(style);

row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(11111.25);
style = wb.createCellStyle();
style.setDataFormat(format.getFormat("#,##0.0000"));
cell.setCellStyle(style);

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>

</section>
</section>
</body>

+ 3
- 1
src/documentation/xdocs/who.xml View File

@@ -50,7 +50,9 @@
</ul>
</section>
<section title="Developers">
<ul>
<li>Shawn Laubach (shawnlaubach at cox dot net)</li>
</ul>
</section>
</section>


+ 1
- 1
src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java View File

@@ -109,7 +109,7 @@ public class BigExample
//set cell stlye
cs.setFont(f);
//set the cell format see HSSFDataFromat for a full list
cs.setDataFormat(HSSFDataFormat.getFormat("($#,##0_);[Red]($#,##0)"));
cs.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)"));

//set a thin border
cs2.setBorderBottom(cs2.BORDER_THIN);

+ 1
- 1
src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateDateCells.java View File

@@ -85,7 +85,7 @@ public class CreateDateCells
// we style the second cell as a date (and time). It is important to create a new cell style from the workbook
// otherwise you can end up modifying the built in style and effecting not only this cell but other cells.
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(HSSFDataFormat.getFormat("m/d/yy h:mm"));
cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
cell = row.createCell((short)1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);

+ 1
- 1
src/java/org/apache/poi/hssf/dev/HSSF.java View File

@@ -145,7 +145,7 @@ public class HSSF
f2.setColor(( short ) 0xf);
f2.setBoldweight(f2.BOLDWEIGHT_BOLD);
cs.setFont(f);
cs.setDataFormat(HSSFDataFormat.getFormat("($#,##0_);[Red]($#,##0)"));
cs.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)"));
cs2.setBorderBottom(cs2.BORDER_THIN);
cs2.setFillPattern(( short ) 1); // fill w fg
cs2.setFillForegroundColor(( short ) 0xA);

+ 83
- 8
src/java/org/apache/poi/hssf/model/Workbook.java View File

@@ -84,6 +84,7 @@ import org.apache.poi.hssf.util.HSSFColor;
* Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf
* before even attempting to use this.
*
* @author Shawn Laubach (shawnlaubach at cox.net) (Data Formats)
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
* @author Sergei Kozello (sergeikozello at mail.ru)
@@ -130,6 +131,8 @@ public class Workbook {

protected ArrayList boundsheets = new ArrayList();

protected ArrayList formats = new ArrayList();

protected ArrayList names = new ArrayList();

protected int bspos =
@@ -150,6 +153,8 @@ public class Workbook {
0; // holds the position of last name record
private int supbookpos =
0; // holds the position of sup book
private short maxformatid =
-1; // holds the max format id

private static POILogger log =
POILogFactory.getLogger(Workbook.class);
@@ -238,6 +243,11 @@ public class Workbook {
log.log(DEBUG, "found SupBook record at " + k);
retval.supbookpos = k;
break;
case FormatRecord.sid :
log.log(DEBUG, "found format record at " + k);
retval.formats.add(rec);
retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode();
break;

default :
}
@@ -263,6 +273,7 @@ public class Workbook {
log.log(DEBUG, "creating new workbook from scratch");
Workbook retval = new Workbook();
ArrayList records = new ArrayList(30);
ArrayList formats = new ArrayList(8);

records.add(retval.createBOF());
records.add(retval.createInterfaceHdr());
@@ -293,14 +304,17 @@ public class Workbook {
records.add(retval.createFont());
retval.fontpos = records.size() - 1; // last font record postion
retval.numfonts = 4;
records.add(retval.createFormat(0));
records.add(retval.createFormat(1));
records.add(retval.createFormat(2));
records.add(retval.createFormat(3));
records.add(retval.createFormat(4));
records.add(retval.createFormat(5));
records.add(retval.createFormat(6));
records.add(retval.createFormat(7));

// set up format records
for (int i = 0; i <= 7; i++) {
Record rec;
rec = retval.createFormat(i);
retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode();
formats.add(rec);
records.add(rec);
}
retval.formats = formats;

for (int k = 0; k < 21; k++) {
records.add(retval.createExtendedFormat(k));
retval.numxfs++;
@@ -1796,6 +1810,51 @@ public class Workbook {
return rec;
}

/**
* Returns a format index that matches the passed in format. It does not tie into HSSFDataFormat.
* @param format the format string
* @param createIfNotFound creates a new format if format not found
* @return the format id of a format that matches or -1 if none found and createIfNotFound
*/
public short getFormat(String format, boolean createIfNotFound) {
Iterator iterator;
for (iterator = formats.iterator(); iterator.hasNext();) {
FormatRecord r = (FormatRecord)iterator.next();
if (r.getFormatString().equals(format)) {
return r.getIndexCode();
}
}

if (createIfNotFound) {
return createFormat(format);
}

return -1;
}

/**
* Creates a FormatRecord, inserts it, and returns the index code.
* @param format the format string
* @return the index code of the format record.
* @see org.apache.poi.hssf.record.FormatRecord
* @see org.apache.poi.hssf.record.Record
*/
public short createFormat(String format) {
FormatRecord rec = new FormatRecord();
maxformatid = maxformatid >= (short)0xa4 ? (short)(maxformatid + 1) : (short)0xa4; //Starting value from M$ empiracle study.
rec.setIndexCode(maxformatid);
rec.setFormatStringLength((byte)format.length());
rec.setFormatString(format);

int pos = 0;
while (pos < records.size() && ((Record)records.get(pos)).getSid() != FormatRecord.sid)
pos++;
pos += formats.size();
formats.add(rec);
records.add(pos, rec);
return maxformatid;
}


/**
* Returns the first occurance of a record matching a particular sid.
@@ -1804,6 +1863,22 @@ public class Workbook {
public Record findFirstRecordBySid(short sid) {
for (Iterator iterator = records.iterator(); iterator.hasNext(); ) {
Record record = ( Record ) iterator.next();
if (record.getSid() == sid) {
return record;
}
}
return null;
}

/**
* Returns the next occurance of a record matching a particular sid.
*/
public Record findNextRecordBySid(short sid, int pos) {
Iterator iterator = records.iterator();
for (;pos > 0 && iterator.hasNext(); iterator.next(),pos--);
while (iterator.hasNext()) {
Record record = ( Record ) iterator.next();

if (record.getSid() == sid) {
return record;

+ 143
- 74
src/java/org/apache/poi/hssf/usermodel/HSSFDataFormat.java View File

@@ -1,4 +1,3 @@

/* ====================================================================
* The Apache Software License, Version 1.1
*
@@ -60,11 +59,16 @@
*/
package org.apache.poi.hssf.usermodel;

import java.util.ArrayList;
import java.util.Vector;
import java.util.List;
import java.util.ListIterator;

import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.FormatRecord;

/**
* Utility to identify builin formats. The following is a list of the formats as
* Utility to identify builin formats. Now can handle user defined data formats also. The following is a list of the formats as
* returned by this class.<P>
*<P>
* 0, "General"<P>
@@ -112,75 +116,92 @@ import java.util.List;

public class HSSFDataFormat
{
private static ArrayList formats;
private static Vector builtinFormats;

private Vector formats = new Vector();
private Workbook workbook;
private boolean movedBuiltins = false; // Flag to see if need to
// check the built in list
// or if the regular list
// has all entries.

/**
* Construncts a new data formatter. It takes a workbook to have
* access to the workbooks format records.
* @param workbook the workbook the formats are tied to.
*/
public HSSFDataFormat(Workbook workbook) {
this.workbook = workbook;
if (builtinFormats == null) populateBuiltinFormats();
}

private static synchronized void populateFormats()
private static synchronized void populateBuiltinFormats()
{
formats = new ArrayList();
formats.add(0, "General");
formats.add(1, "0");
formats.add(2, "0.00");
formats.add(3, "#,##0");
formats.add(4, "#,##0.00");
formats.add(5, "($#,##0_);($#,##0)");
formats.add(6, "($#,##0_);[Red]($#,##0)");
formats.add(7, "($#,##0.00);($#,##0.00)");
formats.add(8, "($#,##0.00_);[Red]($#,##0.00)");
formats.add(9, "0%");
formats.add(0xa, "0.00%");
formats.add(0xb, "0.00E+00");
formats.add(0xc, "# ?/?");
formats.add(0xd, "# ??/??");
formats.add(0xe, "m/d/yy");
formats.add(0xf, "d-mmm-yy");
formats.add(0x10, "d-mmm");
formats.add(0x11, "mmm-yy");
formats.add(0x12, "h:mm AM/PM");
formats.add(0x13, "h:mm:ss AM/PM");
formats.add(0x14, "h:mm");
formats.add(0x15, "h:mm:ss");
formats.add(0x16, "m/d/yy h:mm");
builtinFormats = new Vector();
builtinFormats.add(0, "General");
builtinFormats.add(1, "0");
builtinFormats.add(2, "0.00");
builtinFormats.add(3, "#,##0");
builtinFormats.add(4, "#,##0.00");
builtinFormats.add(5, "($#,##0_);($#,##0)");
builtinFormats.add(6, "($#,##0_);[Red]($#,##0)");
builtinFormats.add(7, "($#,##0.00);($#,##0.00)");
builtinFormats.add(8, "($#,##0.00_);[Red]($#,##0.00)");
builtinFormats.add(9, "0%");
builtinFormats.add(0xa, "0.00%");
builtinFormats.add(0xb, "0.00E+00");
builtinFormats.add(0xc, "# ?/?");
builtinFormats.add(0xd, "# ??/??");
builtinFormats.add(0xe, "m/d/yy");
builtinFormats.add(0xf, "d-mmm-yy");
builtinFormats.add(0x10, "d-mmm");
builtinFormats.add(0x11, "mmm-yy");
builtinFormats.add(0x12, "h:mm AM/PM");
builtinFormats.add(0x13, "h:mm:ss AM/PM");
builtinFormats.add(0x14, "h:mm");
builtinFormats.add(0x15, "h:mm:ss");
builtinFormats.add(0x16, "m/d/yy h:mm");

// 0x17 - 0x24 reserved for international and undocumented
formats.add(0x17, "0x17");
formats.add(0x18, "0x18");
formats.add(0x19, "0x19");
formats.add(0x1a, "0x1a");
formats.add(0x1b, "0x1b");
formats.add(0x1c, "0x1c");
formats.add(0x1d, "0x1d");
formats.add(0x1e, "0x1e");
formats.add(0x1f, "0x1f");
formats.add(0x20, "0x20");
formats.add(0x21, "0x21");
formats.add(0x22, "0x22");
formats.add(0x23, "0x23");
formats.add(0x24, "0x24");
builtinFormats.add(0x17, "0x17");
builtinFormats.add(0x18, "0x18");
builtinFormats.add(0x19, "0x19");
builtinFormats.add(0x1a, "0x1a");
builtinFormats.add(0x1b, "0x1b");
builtinFormats.add(0x1c, "0x1c");
builtinFormats.add(0x1d, "0x1d");
builtinFormats.add(0x1e, "0x1e");
builtinFormats.add(0x1f, "0x1f");
builtinFormats.add(0x20, "0x20");
builtinFormats.add(0x21, "0x21");
builtinFormats.add(0x22, "0x22");
builtinFormats.add(0x23, "0x23");
builtinFormats.add(0x24, "0x24");

// 0x17 - 0x24 reserved for international and undocumented
formats.add(0x25, "(#,##0_);(#,##0)");
formats.add(0x26, "(#,##0_);[Red](#,##0)");
formats.add(0x27, "(#,##0.00_);(#,##0.00)");
formats.add(0x28, "(#,##0.00_);[Red](#,##0.00)");
formats.add(0x29, "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)");
formats.add(0x2a, "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)");
formats.add(0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)");
formats.add(0x2c,
builtinFormats.add(0x25, "(#,##0_);(#,##0)");
builtinFormats.add(0x26, "(#,##0_);[Red](#,##0)");
builtinFormats.add(0x27, "(#,##0.00_);(#,##0.00)");
builtinFormats.add(0x28, "(#,##0.00_);[Red](#,##0.00)");
builtinFormats.add(0x29, "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)");
builtinFormats.add(0x2a, "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)");
builtinFormats.add(0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)");
builtinFormats.add(0x2c,
"_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)");
formats.add(0x2d, "mm:ss");
formats.add(0x2e, "[h]:mm:ss");
formats.add(0x2f, "mm:ss.0");
formats.add(0x30, "##0.0E+0");
formats.add(0x31, "@");
builtinFormats.add(0x2d, "mm:ss");
builtinFormats.add(0x2e, "[h]:mm:ss");
builtinFormats.add(0x2f, "mm:ss.0");
builtinFormats.add(0x30, "##0.0E+0");
builtinFormats.add(0x31, "@");
}

public static List getFormats()
public static List getBuiltinFormats()
{
if (formats == null)
if (builtinFormats == null)
{
populateFormats();
populateBuiltinFormats();
}
return formats;
return builtinFormats;
}

/**
@@ -189,17 +210,17 @@ public class HSSFDataFormat
* @return index of format or -1 if undefined.
*/

public static short getFormat(String format)
public static short getBuiltinFormat(String format)
{
if (formats == null)
if (builtinFormats == null)
{
populateFormats();
populateBuiltinFormats();
}
short retval = -1;

for (short k = 0; k < 0x31; k++)
{
String nformat = ( String ) formats.get(k);
String nformat = ( String ) builtinFormats.get(k);

if ((nformat != null) && nformat.equals(format))
{
@@ -210,32 +231,80 @@ public class HSSFDataFormat
return retval;
}

/**
* get the format index that matches the given format string.
* Creates a new format if one is not found.
* @param format string matching a built in format
* @return index of format.
*/

public short getFormat(String format)
{
ListIterator i;
int ind;
if (!movedBuiltins) {
i = builtinFormats.listIterator();
while (i.hasNext()) {
ind = i.nextIndex();
formats.add(ind, i.next());
}
movedBuiltins = true;
}
i = formats.listIterator();
while (i.hasNext()) {
ind = i.nextIndex();
if (format.equals(i.next()))
return (short)ind;
}
ind = workbook.getFormat(format, true);
if (formats.size() <= ind)
formats.setSize(ind + 1);
formats.add(ind, format);

return (short)ind;
}

/**
* get the format string that matches the given format index
* @param index of a format
* @return string represented at index of format or null if there is not a format at that index
*/

public String getFormat(short index)
{
if (movedBuiltins)
return ( String ) formats.get(index);
else
return (String) (builtinFormats.get(index) != null ? builtinFormats.get(index) : formats.get(index));
}

/**
* get the format string that matches the given format index
* @param index of a built in format
* @return string represented at index of format or null if there is not a builtin format at that index
*/

public static String getFormat(short index)
public static String getBuiltinFormat(short index)
{
if (formats == null)
if (builtinFormats == null)
{
populateFormats();
populateBuiltinFormats();
}
return ( String ) formats.get(index);
return ( String ) builtinFormats.get(index);
}

/**
* get the number of builtin and reserved formats
* @return number of builtin and reserved formats
* get the number of builtin and reserved builtinFormats
* @return number of builtin and reserved builtinFormats
*/

public static int getNumberOfBuiltinFormats()
public static int getNumberOfBuiltinBuiltinFormats()
{
if (formats == null)
if (builtinFormats == null)
{
populateFormats();
populateBuiltinFormats();
}
return formats.size();
return builtinFormats.size();
}
}

+ 12
- 1
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java View File

@@ -82,6 +82,7 @@ import java.util.List;
* @see org.apache.poi.hssf.usermodel.HSSFSheet
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
* @author Shawn Laubach (shawnlaubach at cox.net)
* @version 2.0-pre
*/

@@ -615,7 +616,17 @@ public class HSSFWorkbook
names.remove(index);
workbook.removeName(index);
}

/**
* Creates an instance of HSSFDataFormat.
* @return the HSSFDataFormat object
* @see org.apache.poi.hssf.record.FormatRecord
* @see org.apache.poi.hssf.record.Record
*/
public HSSFDataFormat createDataFormat() {
return new HSSFDataFormat(workbook);
}
/** remove the named range by his name
* @param name named range name
*/

+ 2
- 2
src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java View File

@@ -152,13 +152,13 @@ public class TestCellStyle

// with Date:
HSSFCell cell = row.createCell((short)1);
cs.setDataFormat(HSSFDataFormat.getFormat("m/d/yy"));
cs.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy"));
cell.setCellStyle(cs);
cell.setCellValue(new Date());

// with Calendar:
cell = row.createCell((short)2);
cs.setDataFormat(HSSFDataFormat.getFormat("m/d/yy"));
cs.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy"));
cell.setCellStyle(cs);
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());

+ 29
- 0
src/testcases/org/apache/poi/hssf/usermodel/TestWorkbook.java View File

@@ -233,6 +233,35 @@ public class TestWorkbook
stream.close();
}

/**
* TEST NAME: Test Read Simple w/ Data Format<P>
* OBJECTIVE: Test that HSSF can read a simple spreadsheet (SimpleWithDataFormat.xls).<P>
* SUCCESS: HSSF reads the sheet. Matches values in their particular positions and format is correct<P>
* FAILURE: HSSF does not read a sheet or excepts. HSSF cannot identify values
* in the sheet in their known positions.<P>
*
*/

public void testReadSimpleWithDataFormat()
throws IOException
{
String filename = System.getProperty("HSSF.testdata.path");

filename = filename + "/SimpleWithDataFormat.xls";
FileInputStream stream = new FileInputStream(filename);
POIFSFileSystem fs = new POIFSFileSystem(stream);
HSSFWorkbook workbook = new HSSFWorkbook(fs);
HSSFSheet sheet = workbook.getSheetAt(0);
HSSFDataFormat format = workbook.createDataFormat();

assertEquals(1.25,
sheet.getRow(( short ) 0).getCell(( short ) 0)
.getNumericCellValue(), 1e-10);

assertEquals(format.getFormat("0.0"), 0xa4);
stream.close();
}

/**
* TEST NAME: Test Read Employee Simple <P>
* OBJECTIVE: Test that HSSF can read a simple spreadsheet (Employee.xls).<P>

Loading…
Cancel
Save