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
This commit is contained in:
parent
82f6d9f991
commit
03c8608066
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
@ -1919,12 +1921,19 @@ 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)
|
||||
@ -1934,8 +1943,20 @@ public class Workbook implements Model
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
BIN
src/testcases/org/apache/poi/hssf/data/43623.xls
Normal file
BIN
src/testcases/org/apache/poi/hssf/data/43623.xls
Normal file
Binary file not shown.
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user