Refinements to fix for bug 45126. Excel does not produce any records like 'Excel_Name_Record_Titles_*'

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@684938 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-08-11 21:24:19 +00:00
parent 71de59ad5c
commit f90a5d380c
7 changed files with 980 additions and 998 deletions

View File

@ -192,14 +192,18 @@ final class LinkTable {
}
public NameRecord getSpecificBuiltinRecord(byte name, int sheetIndex) {
/**
* @param builtInCode a BUILTIN_~ constant from {@link NameRecord}
* @param sheetNumber 1-based sheet number
*/
public NameRecord getSpecificBuiltinRecord(byte builtInCode, int sheetNumber) {
Iterator iterator = _definedNames.iterator();
while (iterator.hasNext()) {
NameRecord record = ( NameRecord ) iterator.next();
//print areas are one based
if (record.getBuiltInName() == name && record.getIndexToSheet() == sheetIndex) {
if (record.getBuiltInName() == builtInCode && record.getSheetNumber() == sheetNumber) {
return record;
}
}
@ -257,14 +261,12 @@ final class LinkTable {
return false;
}
private boolean isDuplicatedNames(NameRecord firstName, NameRecord lastName)
{
private static 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();
private static boolean isSameSheetNames(NameRecord firstName, NameRecord lastName) {
return lastName.getSheetNumber() == firstName.getSheetNumber();
}

View File

@ -54,18 +54,13 @@ import java.util.Locale;
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook
* @version 1.0-pre
*/
public class Workbook implements Model
{
public final class Workbook implements Model {
private static final int DEBUG = POILogger.DEBUG;
// public static Workbook currentBook = null;
/**
* constant used to set the "codepage" wherever "codepage" is set in records
* (which is duplciated in more than one record)
* (which is duplicated in more than one record)
*/
private final static short CODEPAGE = ( short ) 0x4b0;
/**
@ -105,8 +100,6 @@ 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)
@ -361,12 +354,12 @@ public class Workbook implements Model
/**Retrieves the Builtin NameRecord that matches the name and index
* There shouldn't be too many names to make the sequential search too slow
* @param name byte representation of the builtin name to match
* @param sheetIndex Index to match
* @param sheetNumber 1-based sheet number
* @return null if no builtin NameRecord matches
*/
public NameRecord getSpecificBuiltinRecord(byte name, int sheetIndex)
public NameRecord getSpecificBuiltinRecord(byte name, int sheetNumber)
{
return getOrCreateLinkTable().getSpecificBuiltinRecord(name, sheetIndex);
return getOrCreateLinkTable().getSpecificBuiltinRecord(name, sheetNumber);
}
/**
@ -627,11 +620,13 @@ public class Workbook implements Model
}
}
public void removeSheet(int sheetnum) {
if (boundsheets.size() > sheetnum) {
records.remove(records.getBspos() - (boundsheets.size() - 1) + sheetnum);
// records.bspos--;
boundsheets.remove(sheetnum);
/**
* @param sheetIndex zero based sheet index
*/
public void removeSheet(int sheetIndex) {
if (boundsheets.size() > sheetIndex) {
records.remove(records.getBspos() - (boundsheets.size() - 1) + sheetIndex);
boundsheets.remove(sheetIndex);
fixTabIdRecord();
}
@ -642,19 +637,17 @@ public class Workbook implements Model
// However, the sheet index must be adjusted, or
// excel will break. (Sheet index is either 0 for
// global, or 1 based index to sheet)
int sheetNum1Based = sheetnum + 1;
int sheetNum1Based = sheetIndex + 1;
for(int i=0; i<getNumNames(); i++) {
NameRecord nr = getNameRecord(i);
if(nr.getIndexToSheet() == sheetNum1Based) {
if(nr.getSheetNumber() == sheetNum1Based) {
// Excel re-writes these to point to no sheet
nr.setEqualsToIndexToSheet((short)0);
} else if(nr.getIndexToSheet() > sheetNum1Based) {
nr.setSheetNumber(0);
} else if(nr.getSheetNumber() > sheetNum1Based) {
// Bump down by one, so still points
// at the same sheet
nr.setEqualsToIndexToSheet((short)(
nr.getEqualsToIndexToSheet()-1
));
nr.setSheetNumber(nr.getSheetNumber()-1);
}
}
}
@ -1964,27 +1957,18 @@ public class Workbook implements Model
/**
* Generates a NameRecord to represent a built-in region
* @return a new NameRecord unless the index is invalid
* @return a new NameRecord
*/
public NameRecord createBuiltInName(byte builtInName, int index)
{
if (index == -1 || index+1 > Short.MAX_VALUE)
throw new IllegalArgumentException("Index is not valid ["+index+"]");
public NameRecord createBuiltInName(byte builtInName, int sheetNumber) {
if (sheetNumber < 0 || sheetNumber+1 > Short.MAX_VALUE) {
throw new IllegalArgumentException("Sheet number ["+sheetNumber+"]is not valid ");
}
NameRecord name = new NameRecord(builtInName, (short)(index));
NameRecord name = new NameRecord(builtInName, sheetNumber);
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());
throw new RuntimeException("Builtin (" + builtInName
+ ") already exists for sheet (" + sheetNumber + ")");
}
addName(name);
return name;
@ -1992,16 +1976,15 @@ public class Workbook implements Model
/** removes the name
* @param namenum name index
* @param nameIndex name index
*/
public void removeName(int namenum){
public void removeName(int nameIndex){
if (linkTable.getNumNames() > namenum) {
if (linkTable.getNumNames() > nameIndex) {
int idx = findFirstRecordLocBySid(NameRecord.sid);
records.remove(idx + namenum);
linkTable.removeName(namenum);
records.remove(idx + nameIndex);
linkTable.removeName(nameIndex);
}
}
/**

View File

@ -106,7 +106,8 @@ public final class NameRecord extends Record {
private byte field_3_length_name_text;
private short field_4_length_name_definition;
private short field_5_index_to_sheet; // unused: see field_6
private short field_6_equals_to_index_to_sheet;
/** the one based sheet number. Zero if this is a global name */
private int field_6_sheetNumber;
private byte field_7_length_custom_menu;
private byte field_8_length_description_text;
private byte field_9_length_help_topic_text;
@ -144,15 +145,14 @@ public final class NameRecord extends Record {
/**
* Constructor to create a built-in named region
* @param builtin Built-in byte representation for the name record, use the public constants
* @param index
*/
public NameRecord(byte builtin, short index)
public NameRecord(byte builtin, int sheetNumber)
{
this();
this.field_12_builtIn_name = builtin;
this.setOptionFlag((short)(this.getOptionFlag() | OPT_BUILTIN));
this.setNameTextLength((byte)1);
this.setEqualsToIndexToSheet(index); //the extern sheets are set through references
field_6_sheetNumber = sheetNumber; //the extern sheets are set through references
//clearing these because they are not used with builtin records
this.setCustomMenuLength((byte)0);
@ -203,18 +203,13 @@ public final class NameRecord extends Record {
// field_6_equals_to_index_to_sheet = index;
}
public short getEqualsToIndexToSheet()
{
return field_6_equals_to_index_to_sheet;
}
/**
* Convenience method to retrieve the index the name refers to.
* @see #getEqualsToIndexToSheet()
* @return short
* For named ranges, and built-in names
* @return the 1-based sheet number. Zero if this is a global name
*/
public short getIndexToSheet() {
return getEqualsToIndexToSheet();
public int getSheetNumber()
{
return field_6_sheetNumber;
}
/**
@ -226,9 +221,10 @@ public final class NameRecord extends Record {
return (byte) (masked >> 4);
}
public void setEqualsToIndexToSheet(short value)
public void setSheetNumber(int value)
{
field_6_equals_to_index_to_sheet = value;
field_6_sheetNumber = value;
}
@ -277,10 +273,6 @@ public final class NameRecord extends Record {
);
}
// public void setNameDefintion(String definition){
// test = definition;
// }
/** sets the custom menu text
* @param text custom menu text
*/
@ -521,7 +513,7 @@ public final class NameRecord extends Record {
data[7 + offset] = getNameTextLength();
LittleEndian.putShort( data, 8 + offset, getDefinitionLength() );
LittleEndian.putShort( data, 10 + offset, getUnused() );
LittleEndian.putShort( data, 12 + offset, getEqualsToIndexToSheet() );
LittleEndian.putUShort( data, 12 + offset, field_6_sheetNumber);
data[14 + offset] = getCustomMenuLength();
data[15 + offset] = getDescriptionTextLength();
data[16 + offset] = getHelpTopicLength();
@ -718,7 +710,7 @@ public final class NameRecord extends Record {
field_3_length_name_text = in.readByte();
field_4_length_name_definition = in.readShort();
field_5_index_to_sheet = in.readShort();
field_6_equals_to_index_to_sheet= in.readShort();
field_6_sheetNumber = in.readUShort();
field_7_length_custom_menu = in.readByte();
field_8_length_description_text = in.readByte();
field_9_length_help_topic_text = in.readByte();
@ -823,7 +815,7 @@ public final class NameRecord extends Record {
.append("\n");
buffer.append(" .unused = ").append( field_5_index_to_sheet )
.append("\n");
buffer.append(" .index to sheet (1-based, 0=Global) = ").append( field_6_equals_to_index_to_sheet )
buffer.append(" .index to sheet (1-based, 0=Global) = ").append( field_6_sheetNumber )
.append("\n");
buffer.append(" .Length of menu text (character count) = ").append( field_7_length_custom_menu )
.append("\n");

View File

@ -61,6 +61,9 @@ import java.util.Stack;
*/
public class HSSFWorkbook extends POIDocument
{
private static final int MAX_ROW = 0xFFFF;
private static final short MAX_COLUMN = (short)0x00FF;
private static final int DEBUG = POILogger.DEBUG;
/**
@ -835,7 +838,8 @@ public class HSSFWorkbook extends POIDocument
/**
* Sets the repeating rows and columns for a sheet (as found in
* File->PageSetup->Sheet). This is function is included in the workbook
* 2003:File->PageSetup->Sheet, 2007:Page Layout->Print Titles).
* This is function is included in the workbook
* because it creates/modifies name records which are stored at the
* workbook level.
* <p>
@ -865,10 +869,10 @@ public class HSSFWorkbook extends POIDocument
// Check arguments
if (startColumn == -1 && endColumn != -1) throw new IllegalArgumentException("Invalid column range specification");
if (startRow == -1 && endRow != -1) throw new IllegalArgumentException("Invalid row range specification");
if (startColumn < -1 || startColumn >= 0xFF) throw new IllegalArgumentException("Invalid column range specification");
if (endColumn < -1 || endColumn >= 0xFF) throw new IllegalArgumentException("Invalid column range specification");
if (startRow < -1 || startRow > 65535) throw new IllegalArgumentException("Invalid row range specification");
if (endRow < -1 || endRow > 65535) throw new IllegalArgumentException("Invalid row range specification");
if (startColumn < -1 || startColumn >= MAX_COLUMN) throw new IllegalArgumentException("Invalid column range specification");
if (endColumn < -1 || endColumn >= MAX_COLUMN) throw new IllegalArgumentException("Invalid column range specification");
if (startRow < -1 || startRow > MAX_ROW) throw new IllegalArgumentException("Invalid row range specification");
if (endRow < -1 || endRow > MAX_ROW) throw new IllegalArgumentException("Invalid row range specification");
if (startColumn > endColumn) throw new IllegalArgumentException("Invalid column range specification");
if (startRow > endRow) throw new IllegalArgumentException("Invalid row range specification");
@ -880,50 +884,60 @@ public class HSSFWorkbook extends POIDocument
boolean removingRange =
startColumn == -1 && endColumn == -1 && startRow == -1 && endRow == -1;
boolean isNewRecord = false;
NameRecord nameRecord;
nameRecord = findExistingRowColHeaderNameRecord(sheetIndex);
if (removingRange )
{
if (nameRecord != null)
workbook.removeName(findExistingRowColHeaderNameRecordIdx(sheetIndex+1));
int rowColHeaderNameIndex = findExistingRowColHeaderNameRecordIdx(sheetIndex);
if (removingRange) {
if (rowColHeaderNameIndex >= 0) {
workbook.removeName(rowColHeaderNameIndex);
}
return;
}
if ( nameRecord == null )
{
nameRecord = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_TITLE, sheetIndex+1);
boolean isNewRecord;
NameRecord nameRecord;
if (rowColHeaderNameIndex < 0) {
//does a lot of the house keeping for builtin records, like setting lengths to zero etc
nameRecord = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_TITLE, sheetIndex+1);
isNewRecord = true;
} else {
nameRecord = workbook.getNameRecord(rowColHeaderNameIndex);
isNewRecord = false;
}
short definitionTextLength = settingRowAndColumn ? (short)0x001a : (short)0x000b;
nameRecord.setDefinitionTextLength(definitionTextLength);
nameRecord.setDefinitionTextLength(definitionTextLength); // TODO - remove
Stack ptgs = new Stack();
if (settingRowAndColumn)
{
ptgs.add(new MemFuncPtg(23)); // TODO - where did constant '23' come from?
if (settingRowAndColumn) {
final int exprsSize = 2 * 11 + 1; // Area3DPtg.SIZE + UnionPtg.SIZE
ptgs.add(new MemFuncPtg(exprsSize));
}
if (startColumn >= 0)
{
Area3DPtg area3DPtg1 = new Area3DPtg();
area3DPtg1.setExternSheetIndex(externSheetIndex);
area3DPtg1.setFirstColumn((short)startColumn);
area3DPtg1.setLastColumn((short)endColumn);
area3DPtg1.setFirstRow((short)0);
area3DPtg1.setLastRow((short)0xFFFF);
ptgs.add(area3DPtg1);
Area3DPtg colArea = new Area3DPtg();
colArea.setExternSheetIndex(externSheetIndex);
colArea.setFirstColumn((short)startColumn);
colArea.setLastColumn((short)endColumn);
colArea.setFirstRow(0);
colArea.setLastRow(MAX_ROW);
colArea.setFirstColRelative(false);
colArea.setLastColRelative(false);
colArea.setFirstRowRelative(false);
colArea.setLastRowRelative(false);
ptgs.add(colArea);
}
if (startRow >= 0)
{
Area3DPtg area3DPtg2 = new Area3DPtg();
area3DPtg2.setExternSheetIndex(externSheetIndex);
area3DPtg2.setFirstColumn((short)0);
area3DPtg2.setLastColumn((short)0x00FF);
area3DPtg2.setFirstRow((short)startRow);
area3DPtg2.setLastRow((short)endRow);
ptgs.add(area3DPtg2);
Area3DPtg rowArea = new Area3DPtg();
rowArea.setExternSheetIndex(externSheetIndex);
rowArea.setFirstColumn((short)0);
rowArea.setLastColumn(MAX_COLUMN);
rowArea.setFirstRow(startRow);
rowArea.setLastRow(endRow);
rowArea.setFirstColRelative(false);
rowArea.setLastColRelative(false);
rowArea.setFirstRowRelative(false);
rowArea.setLastRowRelative(false);
ptgs.add(rowArea);
}
if (settingRowAndColumn)
{
@ -943,38 +957,31 @@ public class HSSFWorkbook extends POIDocument
sheet.setActive(true);
}
private NameRecord findExistingRowColHeaderNameRecord( int sheetIndex )
{
int index = findExistingRowColHeaderNameRecordIdx(sheetIndex);
if (index == -1)
return null;
else
return (NameRecord)workbook.findNextRecordBySid(NameRecord.sid, index);
}
private int findExistingRowColHeaderNameRecordIdx( int sheetIndex )
{
int index = 0;
NameRecord r = null;
while ((r = (NameRecord) workbook.findNextRecordBySid(NameRecord.sid, index)) != null)
{
int indexToSheet = r.getEqualsToIndexToSheet() -1;
if(indexToSheet > -1) { //ignore "GLOBAL" name records
int nameRecordSheetIndex = workbook.getSheetIndexFromExternSheetIndex(indexToSheet);
if (isRowColHeaderRecord( r ) && nameRecordSheetIndex == sheetIndex)
{
return index;
private int findExistingRowColHeaderNameRecordIdx(int sheetIndex) {
for(int defNameIndex =0; defNameIndex<names.size(); defNameIndex++) {
NameRecord r = workbook.getNameRecord(defNameIndex);
if (r == null) {
throw new RuntimeException("Unable to find all defined names to iterate over");
}
if (!isRowColHeaderRecord( r )) {
continue;
}
if(r.getSheetNumber() == 0) {
//ignore "GLOBAL" name records
continue;
}
int externIndex = r.getSheetNumber() -1;
int nameRecordSheetIndex = workbook.getSheetIndexFromExternSheetIndex(externIndex);
if (nameRecordSheetIndex == sheetIndex) {
return defNameIndex;
}
}
index++;
}
return -1;
}
private boolean isRowColHeaderRecord( NameRecord r )
{
return r.getOptionFlag() == 0x20 && ("" + ((char)7)).equals(r.getNameText());
private static boolean isRowColHeaderRecord(NameRecord r) {
return r.isBuiltInName() && r.getBuiltInName() == NameRecord.BUILTIN_PRINT_TITLE;
}
/**

View File

@ -1013,7 +1013,7 @@ public final class TestBugs extends TestCase {
Workbook w = wb.getWorkbook();
for(int i=0; i<w.getNumNames(); i++) {
NameRecord r = w.getNameRecord(i);
assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets());
List nd = r.getNameDefinition();
assertEquals(1, nd.size());
@ -1031,7 +1031,7 @@ public final class TestBugs extends TestCase {
for(int i=0; i<w.getNumNames(); i++) {
NameRecord r = w.getNameRecord(i);
assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets());
List nd = r.getNameDefinition();
assertEquals(1, nd.size());
@ -1048,7 +1048,7 @@ public final class TestBugs extends TestCase {
for(int i=0; i<w.getNumNames(); i++) {
NameRecord r = w.getNameRecord(i);
assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets());
List nd = r.getNameDefinition();
assertEquals(1, nd.size());

View File

@ -50,7 +50,7 @@ public final class TestHSSFWorkbook extends TestCase {
b.createSheet();
b.setRepeatingRowsAndColumns( 2, 0,1,-1,-1 );
NameRecord nameRecord = b.getWorkbook().getNameRecord( 0 );
assertEquals( 3, nameRecord.getIndexToSheet() );
assertEquals(3, nameRecord.getSheetNumber());
}
public void testCaseInsensitiveNames() {
@ -427,7 +427,7 @@ public final class TestHSSFWorkbook extends TestCase {
// First at low level
nr = b.getWorkbook().getNameRecord(0);
assertEquals("On2", nr.getNameText());
assertEquals(0, nr.getIndexToSheet());
assertEquals(0, nr.getSheetNumber());
assertEquals(1, nr.getExternSheetNumber());
assertEquals(1, nr.getNameDefinition().size());
@ -450,7 +450,7 @@ public final class TestHSSFWorkbook extends TestCase {
// First at low level
nr = b.getWorkbook().getNameRecord(1);
assertEquals("OnOne", nr.getNameText());
assertEquals(0, nr.getIndexToSheet());
assertEquals(0, nr.getSheetNumber());
assertEquals(0, nr.getExternSheetNumber());
assertEquals(1, nr.getNameDefinition().size());
@ -473,7 +473,7 @@ public final class TestHSSFWorkbook extends TestCase {
// First at low level
nr = b.getWorkbook().getNameRecord(2);
assertEquals("OnSheet3", nr.getNameText());
assertEquals(0, nr.getIndexToSheet());
assertEquals(0, nr.getSheetNumber());
assertEquals(2, nr.getExternSheetNumber());
assertEquals(1, nr.getNameDefinition().size());

View File

@ -17,17 +17,15 @@
package org.apache.poi.hssf.usermodel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
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;
/**
*
@ -42,10 +40,6 @@ public final class TestNamedRange extends TestCase {
return HSSFTestDataSamples.openSampleWorkbook(sampleFileName);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(TestNamedRange.class);
}
/** Test of TestCase method, of class test.RangeTest. */
public void testNamedRange() {
HSSFWorkbook wb = openSample("Simple.xls");
@ -411,7 +405,7 @@ public final class TestNamedRange extends TestCase {
String cellValue = "TEST Value";
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(sheetName);
sheet.createRow(0).createCell((short) 0).setCellValue(cellValue);
sheet.createRow(0).createCell(0).setCellValue(new HSSFRichTextString(cellValue));
// create named range for a single cell using areareference
HSSFName namedCell = wb.createName();
@ -447,7 +441,7 @@ public final class TestNamedRange extends TestCase {
String sname = "TestSheet", cname = "TestName", cvalue = "TestVal";
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(sname);
sheet.createRow(0).createCell((short) 0).setCellValue(cvalue);
sheet.createRow(0).createCell(0).setCellValue(new HSSFRichTextString(cvalue));
// create named range for a single cell using cellreference
HSSFName namedCell = wb.createName();
@ -492,56 +486,60 @@ public final class TestNamedRange extends TestCase {
}
}
public void testRepeatingRowsAndColumsNames() throws Exception {
public void testRepeatingRowsAndColumsNames() {
// First test that setting RR&C for same sheet more than once only creates a
// single Print_Titles built-in record
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFSheet sheet = wb.createSheet("FirstSheet");
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);
// set repeating rows and columns twice for the first sheet
for (int i = 0; i < 2; i++) {
wb.setRepeatingRowsAndColumns(0, 0, 0, 0, 3-1);
sheet.createFreezePane(0, 3);
}
}
}
assertEquals(2, wb.getNumberOfNames());
assertEquals(1, 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());
if (false) {
// TODO - full column references not rendering properly, absolute markers not present either
assertEquals("FirstSheet!$A:$A,FirstSheet!$1:$3", nr1.getReference());
} else {
assertEquals("FirstSheet!A:A,FirstSheet!$A$1:$IV$3", nr1.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));
HSSFWorkbook nwb = HSSFTestDataSamples.writeOutAndReadBack(wb);
assertEquals(1, nwb.getNumberOfNames());
nr1 = nwb.getNameAt(0);
assertEquals("Print_Titles", nr1.getNameName());
assertEquals("FirstSheet!A:A,FirstSheet!$A$1:$IV$3", nr1.getReference());
// check that setting RR&C on a second sheet causes a new Print_Titles built-in
// name to be created
sheet = nwb.createSheet("SecondSheet");
nwb.setRepeatingRowsAndColumns(1, 1, 2, 0, 0);
assertEquals(2, nwb.getNumberOfNames());
nr1 = nwb.getNameAt(0);
nr2 = nwb.getNameAt(1);
HSSFName 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());
assertEquals("Print_Titles", nr2.getNameName());
assertEquals("SecondSheet!B:C,SecondSheet!$A$1:$IV$1", nr2.getReference());
if (false) {
// 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);
try {
File tempFile = File.createTempFile("POI-45126-", ".xls");
FileOutputStream fout = new FileOutputStream(tempFile);
nwb.write(fout);
fout.close();
System.out.println("check out " + tempFile.getAbsolutePath());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}