aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Burch <nick@apache.org>2008-07-10 22:27:38 +0000
committerNick Burch <nick@apache.org>2008-07-10 22:27:38 +0000
commit0f2b7db942b713315eee796221d3b68776efec0d (patch)
treec98a10680969d059ac2b49e4ae508ee84e01477a
parent99b7fbfaea7af348bd13c61cd16cb5a3c8dc509a (diff)
downloadpoi-0f2b7db942b713315eee796221d3b68776efec0d.tar.gz
poi-0f2b7db942b713315eee796221d3b68776efec0d.zip
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647711,647714-647737,647739-647823,647825-648155,648157-648202,648204-648273,648275,648277-648302,648304-648333,648335-648588,648590-648622,648625-648673,648675-649141,649144,649146-649556,649558-649795,649799,649801-649910,649912-649913,649915-650128,650131-650132,650134-650137,650140-650914,650916-651991,651993-652284,652286-652287,652289,652291,652293-652297,652299-652328,652330-652425,652427-652445,652447-652560,652562-652933,652935,652937-652993,652995-653116,653118-653124,653126-653483,653487-653519,653522-653550,653552-653607,653609-653667,653669-653674,653676-653814,653817-653830,653832-653891,653893-653944,653946-654055,654057-654355,654357-654365,654367-654648,654651-655215,655217-655277,655279-655281,655283-655911,655913-656212,656214,656216-656251,656253-656698,656700-656756,656758-656892,656894-657135,657137-657165,657168-657179,657181-657354,657356-657357,657359-657701,657703-657874,657876-658032,658034-658284,658286,658288-658301,658303-658307,658309-658321,658323-658335,658337-658348,658351,658353-658832,658834-658983,658985,658987-659066,659068-659402,659404-659428,659430-659451,659453-659454,659456-659461,659463-659477,659479-659524,659526-659571,659574,659576-660255,660257-660262,660264-660279,660281-660343,660345-660473,660475-660827,660829-660833,660835-660888,660890-663321,663323-663435,663437-663764,663766-663854,663856-664219,664221-664489,664494-664514,664516-668013,668015-668142,668144-668152,668154,668156-668256,668258,668260-669139,669141-669455,669457-669657,669659-669808,669810-670189,670191-671321,671323-672229,672231-672549,672551-672552,672554-672561,672563-672566,672568,672571-673049,673051-673852,673854-673862,673864-673986,673988-673996,673998-674347,674349-674890,674892-674910,674912-674936,674938-674952,674954-675078,675080-675085,675087-675217,675219-675660,675662-675670,675672-675716,675718-675776 via svnmerge from
https://svn.apache.org:443/repos/asf/poi/trunk ........ r675727 | nick | 2008-07-10 21:54:42 +0100 (Thu, 10 Jul 2008) | 1 line Fix cell.getRichStringCellValue() for formula cells with string results ........ r675734 | nick | 2008-07-10 22:03:52 +0100 (Thu, 10 Jul 2008) | 1 line Add test for bug #43623, currently disabled as it makes FormulaParser unhappy ........ r675776 | nick | 2008-07-10 22:49:37 +0100 (Thu, 10 Jul 2008) | 1 line Fix bug #45126 - Avoid generating multiple NamedRanges with the same name, which Excel dislikes ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@675787 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/documentation/content/xdocs/changes.xml2
-rw-r--r--src/documentation/content/xdocs/status.xml2
-rwxr-xr-xsrc/java/org/apache/poi/hssf/model/LinkTable.java30
-rw-r--r--src/java/org/apache/poi/hssf/model/Workbook.java33
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFCell.java23
-rw-r--r--src/testcases/org/apache/poi/hssf/data/43623.xlsbin0 -> 13824 bytes
-rw-r--r--src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java75
-rw-r--r--src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java59
8 files changed, 204 insertions, 20 deletions
diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml
index f0c5d67ac2..d0c00a646e 100644
--- a/src/documentation/content/xdocs/changes.xml
+++ b/src/documentation/content/xdocs/changes.xml
@@ -50,6 +50,8 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45126 - Avoid generating multiple NamedRanges with the same name, which Excel dislikes</action>
+ <action dev="POI-DEVELOPERS" type="fix">Fix cell.getRichStringCellValue() for formula cells with string results</action>
<action dev="POI-DEVELOPERS" type="fix">45365 - Handle more excel number formatting rules in FormatTrackingHSSFListener / XLS2CSVmra</action>
<action dev="POI-DEVELOPERS" type="fix">45373 - Improve the performance of HSSFSheet.shiftRows</action>
<action dev="POI-DEVELOPERS" type="fix">45367 - Fixed bug when last row removed from sheet is row zero</action>
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index 693fc42e2e..78937b3257 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -47,6 +47,8 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45126 - Avoid generating multiple NamedRanges with the same name, which Excel dislikes</action>
+ <action dev="POI-DEVELOPERS" type="fix">Fix cell.getRichStringCellValue() for formula cells with string results</action>
<action dev="POI-DEVELOPERS" type="fix">45365 - Handle more excel number formatting rules in FormatTrackingHSSFListener / XLS2CSVmra</action>
<action dev="POI-DEVELOPERS" type="fix">45373 - Improve the performance of HSSFSheet.shiftRows</action>
<action dev="POI-DEVELOPERS" type="fix">45367 - Fixed bug when last row removed from sheet is row zero</action>
diff --git a/src/java/org/apache/poi/hssf/model/LinkTable.java b/src/java/org/apache/poi/hssf/model/LinkTable.java
index a19971b7d5..1d8781d971 100755
--- a/src/java/org/apache/poi/hssf/model/LinkTable.java
+++ b/src/java/org/apache/poi/hssf/model/LinkTable.java
@@ -63,6 +63,8 @@ import org.apache.poi.hssf.record.SupBookRecord;
* @author Josh Micich
*/
final class LinkTable {
+
+
// TODO make this class into a record aggregate
private static final class CRNBlock {
@@ -233,13 +235,39 @@ final class LinkTable {
if (idx == -1) idx = findFirstRecordLocBySid(CountryRecord.sid);
int countNames = _definedNames.size();
_workbookRecordList.add(idx+countNames, name);
-
}
public void removeName(int namenum) {
_definedNames.remove(namenum);
}
+ /**
+ * checks if the given name is already included in the linkTable
+ */
+ public boolean nameAlreadyExists(NameRecord name)
+ {
+ // Check to ensure no other names have the same case-insensitive name
+ for ( int i = getNumNames()-1; i >=0; i-- ) {
+ NameRecord rec = getNameRecord(i);
+ if (rec != name) {
+ if (isDuplicatedNames(name, rec))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isDuplicatedNames(NameRecord firstName, NameRecord lastName)
+ {
+ return lastName.getNameText().equalsIgnoreCase(firstName.getNameText())
+ && isSameSheetNames(firstName, lastName);
+ }
+ private boolean isSameSheetNames(NameRecord firstName, NameRecord lastName)
+ {
+ return lastName.getEqualsToIndexToSheet() == firstName.getEqualsToIndexToSheet();
+ }
+
+
public short getIndexToSheet(short num) {
return _externSheetRecord.getREFRecordAt(num).getIndexToFirstSupBook();
}
diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java
index fa22cfb688..329e217a81 100644
--- a/src/java/org/apache/poi/hssf/model/Workbook.java
+++ b/src/java/org/apache/poi/hssf/model/Workbook.java
@@ -105,6 +105,8 @@ public class Workbook implements Model
private static POILogger log = POILogFactory.getLogger(Workbook.class);
+ protected static final String EXCEL_REPEATING_NAME_PREFIX_ = "Excel_Name_Record_Titles_";
+
/**
* Creates new Workbook with no intitialization --useless right now
* @see #createWorkbook(List)
@@ -1918,13 +1920,20 @@ public class Workbook implements Model
*/
public NameRecord addName(NameRecord name)
{
-
- getOrCreateLinkTable().addName(name);
+
+ LinkTable linkTable = getOrCreateLinkTable();
+ if(linkTable.nameAlreadyExists(name)) {
+ throw new IllegalArgumentException(
+ "You are trying to assign a duplicated name record: "
+ + name.getNameText());
+ }
+ linkTable.addName(name);
return name;
}
-
- /**Generates a NameRecord to represent a built-in region
+
+ /**
+ * Generates a NameRecord to represent a built-in region
* @return a new NameRecord unless the index is invalid
*/
public NameRecord createBuiltInName(byte builtInName, int index)
@@ -1933,9 +1942,21 @@ public class Workbook implements Model
throw new IllegalArgumentException("Index is not valid ["+index+"]");
NameRecord name = new NameRecord(builtInName, (short)(index));
-
- addName(name);
+ String prefix = EXCEL_REPEATING_NAME_PREFIX_ + index + "_";
+ int cont = 0;
+ while(linkTable.nameAlreadyExists(name)) {
+ cont++;
+ String altNameName = prefix + cont;
+
+ // It would be better to set a different builtInName here.
+ // It does not seem possible, so we create it as a
+ // non built-in name from this point on
+ name = new NameRecord();
+ name.setNameText(altNameName);
+ name.setNameTextLength((byte)altNameName.length());
+ }
+ addName(name);
return name;
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
index 2c82348949..a5279993e9 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
@@ -610,13 +610,28 @@ public class HSSFCell implements Cell
// Set the 'pre-evaluated result' for the formula
// note - formulas do not preserve text formatting.
FormulaRecordAggregate fr = (FormulaRecordAggregate) record;
- // must make new sr because fr.getStringRecord() may be null
- StringRecord sr = new StringRecord();
- sr.setString(hvalue.getString()); // looses format
- fr.setStringRecord(sr);
+
+ // Save the string into a String Record, creating
+ // one if required
+ StringRecord sr = fr.getStringRecord();
+ if(sr == null) {
+ // Wasn't a string before, need a new one
+ sr = new StringRecord();
+ fr.setStringRecord(sr);
+ }
+
+ // Save, loosing the formatting
+ sr.setString(hvalue.getString());
+ // Update our local cache to the un-formatted version
+ stringValue = new HSSFRichTextString(sr.getString());
+
+ // All done
return;
}
+ // If we get here, we're not dealing with a formula,
+ // so handle things as a normal rich text cell
+
if (cellType != CELL_TYPE_STRING) {
setCellType(CELL_TYPE_STRING, false, row, col, styleIndex);
}
diff --git a/src/testcases/org/apache/poi/hssf/data/43623.xls b/src/testcases/org/apache/poi/hssf/data/43623.xls
new file mode 100644
index 0000000000..401cb2a887
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/43623.xls
Binary files differ
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
index 523d42ec9e..bfd3593180 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
@@ -33,9 +33,7 @@ import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
-import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.NameRecord;
-import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
import org.apache.poi.util.TempFile;
@@ -1152,10 +1150,12 @@ public final class TestBugs extends TestCase {
s.createRow(0);
HSSFCell c1 = s.getRow(0).createCell((short)0);
HSSFCell c2 = s.getRow(0).createCell((short)1);
+ HSSFCell c3 = s.getRow(0).createCell((short)2);
// As number and string
c1.setCellFormula("70164");
c2.setCellFormula("\"70164\"");
+ c3.setCellFormula("\"90210\"");
// Check the formulas
assertEquals("70164.0", c1.getCellFormula());
@@ -1166,20 +1166,31 @@ public final class TestBugs extends TestCase {
assertEquals("", c1.getRichStringCellValue().getString());
assertEquals(0.0, c2.getNumericCellValue(), 0.00001);
assertEquals("", c2.getRichStringCellValue().getString());
+ assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
+ assertEquals("", c3.getRichStringCellValue().getString());
- // Now evaluate
+ // Try changing the cached value on one of the string
+ // formula cells, so we can see it updates properly
+ c3.setCellValue(new HSSFRichTextString("test"));
+ assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
+ assertEquals("test", c3.getRichStringCellValue().getString());
+
+
+ // Now evaluate, they should all be changed
HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb);
eval.setCurrentRow(s.getRow(0));
eval.evaluateFormulaCell(c1);
eval.evaluateFormulaCell(c2);
+ eval.evaluateFormulaCell(c3);
- // Check
+ // Check that the cells now contain
+ // the correct values
assertEquals(70164.0, c1.getNumericCellValue(), 0.00001);
assertEquals("", c1.getRichStringCellValue().getString());
assertEquals(0.0, c2.getNumericCellValue(), 0.00001);
-
- // TODO - why isn't this working?
-// assertEquals("70164", c2.getRichStringCellValue().getString());
+ assertEquals("70164", c2.getRichStringCellValue().getString());
+ assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
+ assertEquals("90210", c3.getRichStringCellValue().getString());
// Write and read
@@ -1187,12 +1198,15 @@ public final class TestBugs extends TestCase {
HSSFSheet ns = nwb.getSheetAt(0);
HSSFCell nc1 = ns.getRow(0).getCell((short)0);
HSSFCell nc2 = ns.getRow(0).getCell((short)1);
+ HSSFCell nc3 = ns.getRow(0).getCell((short)2);
// Re-check
assertEquals(70164.0, nc1.getNumericCellValue(), 0.00001);
assertEquals("", nc1.getRichStringCellValue().getString());
assertEquals(0.0, nc2.getNumericCellValue(), 0.00001);
assertEquals("70164", nc2.getRichStringCellValue().getString());
+ assertEquals(0.0, nc3.getNumericCellValue(), 0.00001);
+ assertEquals("90210", nc3.getRichStringCellValue().getString());
// Now check record level stuff too
ns.getSheet().setLoc(0);
@@ -1205,15 +1219,58 @@ public final class TestBugs extends TestCase {
if(fn == 0) {
assertEquals(70164.0, fr.getFormulaRecord().getValue(), 0.0001);
assertNull(fr.getStringRecord());
- } else {
+ } else if (fn == 1) {
assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001);
assertNotNull(fr.getStringRecord());
assertEquals("70164", fr.getStringRecord().getString());
+ } else {
+ assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001);
+ assertNotNull(fr.getStringRecord());
+ assertEquals("90210", fr.getStringRecord().getString());
}
fn++;
}
}
- assertEquals(2, fn);
+ assertEquals(3, fn);
+ }
+
+ /**
+ * Problem with "Vector Rows", eg a whole
+ * column which is set to the result of
+ * {=sin(B1:B9)}(9,1), so that each cell is
+ * shown to have the contents
+ * {=sin(B1:B9){9,1)[rownum][0]
+ * In this sample file, the vector column
+ * is C, and the data column is B.
+ *
+ * For now, blows up with an exception from ExtPtg
+ * Expected ExpPtg to be converted from Shared to Non-Shared...
+ */
+ public void DISABLEDtest43623() throws Exception {
+ HSSFWorkbook wb = openSample("43623.xls");
+ assertEquals(1, wb.getNumberOfSheets());
+
+ HSSFSheet s1 = wb.getSheetAt(0);
+
+ HSSFCell c1 = s1.getRow(0).getCell(2);
+ HSSFCell c2 = s1.getRow(1).getCell(2);
+ HSSFCell c3 = s1.getRow(2).getCell(2);
+
+ // These formula contents are a guess...
+ assertEquals("{=sin(B1:B9){9,1)[0][0]", c1.getCellFormula());
+ assertEquals("{=sin(B1:B9){9,1)[1][0]", c2.getCellFormula());
+ assertEquals("{=sin(B1:B9){9,1)[2][0]", c3.getCellFormula());
+
+ // Save and re-open, ensure it still works
+ HSSFWorkbook nwb = writeOutAndReadBack(wb);
+ HSSFSheet ns1 = nwb.getSheetAt(0);
+ HSSFCell nc1 = ns1.getRow(0).getCell(2);
+ HSSFCell nc2 = ns1.getRow(1).getCell(2);
+ HSSFCell nc3 = ns1.getRow(2).getCell(2);
+
+ assertEquals("{=sin(B1:B9){9,1)[0][0]", nc1.getCellFormula());
+ assertEquals("{=sin(B1:B9){9,1)[1][0]", nc2.getCellFormula());
+ assertEquals("{=sin(B1:B9){9,1)[2][0]", nc3.getCellFormula());
}
}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java b/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java
index 591a7ba24f..0a508805db 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java
@@ -17,11 +17,17 @@
package org.apache.poi.hssf.usermodel;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+
import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.util.AreaReference;
import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
/**
*
@@ -485,4 +491,57 @@ public final class TestNamedRange extends TestCase {
// expected during successful test
}
}
+
+ public void testRepeatingRowsAndColumsNames() throws Exception {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet = wb.createSheet();
+
+ for (int rowItem = 0; rowItem < 10; rowItem++) {
+ HSSFRow r = sheet.createRow(rowItem);
+ for (int column = 0; column < 2; column++) {
+ HSSFCell cellItem = r.createCell((short) column);
+ cellItem.setCellType(HSSFCell.CELL_TYPE_STRING);
+ cellItem.setCellValue(new HSSFRichTextString("Some value here"));
+ if (rowItem == 2) {
+ wb.setRepeatingRowsAndColumns(0, 0, 0, 0, 3 - 1);
+ sheet.createFreezePane(0, 3);
+ }
+ }
+ }
+
+ assertEquals(2, wb.getNumberOfNames());
+ HSSFName nr1 = wb.getNameAt(0);
+ HSSFName nr2 = wb.getNameAt(1);
+
+ assertEquals("Print_Titles", nr1.getNameName());
+ assertEquals("Sheet0!$A$1:$A$0,Sheet0!$A$1:$IV$3", nr1.getReference());
+
+ assertEquals("Excel_Name_Record_Titles_1_1", nr2.getNameName());
+ assertEquals("Sheet0!$A$1:$A$0,Sheet0!$A$1:$IV$3", nr2.getReference());
+
+ // Save and re-open
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ wb.write(baos);
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ HSSFWorkbook nwb = new HSSFWorkbook(new POIFSFileSystem(bais));
+
+ assertEquals(2, nwb.getNumberOfNames());
+ nr1 = nwb.getNameAt(0);
+ nr2 = nwb.getNameAt(1);
+
+ // TODO -
+ // should these references really have been corrected?
+ // and if so, why not also above?
+ assertEquals("Print_Titles", nr1.getNameName());
+ assertEquals("Sheet0!A:A,Sheet0!$A$1:$IV$3", nr1.getReference());
+
+ assertEquals("Excel_Name_Record_Titles_1_1", nr2.getNameName());
+ assertEquals("Sheet0!A:A,Sheet0!$A$1:$IV$3", nr2.getReference());
+
+ // In case you fancy checking in excel, to ensure it
+ // won't complain about the file now
+ FileOutputStream fout = new FileOutputStream(File.createTempFile("POI-45126-", ".xls"));
+ wb.write(fout);
+ fout.close();
+ }
}