Move CellReference from hssf.util into ss.util, but leave a class in the old package to proxy requests on. Also needed tweaks to several things that used it. Finally, add lots more tests, and fix the high column number num<->letter conversion

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@645143 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2008-04-05 17:42:10 +00:00
parent ec58464f48
commit 6710416a66
15 changed files with 437 additions and 382 deletions

View File

@ -20,6 +20,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
@ -27,6 +28,7 @@ import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/** /**
@ -135,4 +137,20 @@ public class FromQuickGuide {
} }
} }
} }
public void getCellContents(Sheet sheet) {
for (Row row : sheet) {
for (Cell cell : row) {
CellReference cellRef = new CellReference(row.getRowNum(), cell.getCellNum());
System.out.print(cellRef.formatAsString());
switch(cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
System.out.println(cell.getRichStringCellValue().getString());
break;
case Cell.CELL_TYPE_NUMERIC:
}
}
}
}
} }

View File

@ -74,7 +74,7 @@ public class CommentShape extends TextboxShape {
private NoteRecord createNoteRecord( HSSFComment shape, int shapeId ) private NoteRecord createNoteRecord( HSSFComment shape, int shapeId )
{ {
NoteRecord note = new NoteRecord(); NoteRecord note = new NoteRecord();
note.setColumn(shape.getColumn()); note.setColumn((short)shape.getColumn());
note.setRow((short)shape.getRow()); note.setRow((short)shape.getRow());
note.setFlags(shape.isVisible() ? NoteRecord.NOTE_VISIBLE : NoteRecord.NOTE_HIDDEN); note.setFlags(shape.isVisible() ? NoteRecord.NOTE_VISIBLE : NoteRecord.NOTE_HIDDEN);
note.setShapeId((short)shapeId); note.setShapeId((short)shapeId);

View File

@ -260,9 +260,9 @@ public class Area3DPtg extends Ptg implements AreaI
CellReference lastCell = ar.getLastCell(); CellReference lastCell = ar.getLastCell();
setFirstRow( (short) frstCell.getRow() ); setFirstRow( (short) frstCell.getRow() );
setFirstColumn( frstCell.getCol() ); setFirstColumn( (short) frstCell.getCol() );
setLastRow( (short) lastCell.getRow() ); setLastRow( (short) lastCell.getRow() );
setLastColumn( lastCell.getCol() ); setLastColumn( (short) lastCell.getCol() );
setFirstColRelative( !frstCell.isColAbsolute() ); setFirstColRelative( !frstCell.isColAbsolute() );
setLastColRelative( !lastCell.isColAbsolute() ); setLastColRelative( !lastCell.isColAbsolute() );
setFirstRowRelative( !frstCell.isRowAbsolute() ); setFirstRowRelative( !frstCell.isRowAbsolute() );

View File

@ -63,7 +63,7 @@ public class Ref3DPtg extends Ptg {
public Ref3DPtg(String cellref, short externIdx ) { public Ref3DPtg(String cellref, short externIdx ) {
CellReference c= new CellReference(cellref); CellReference c= new CellReference(cellref);
setRow(c.getRow()); setRow(c.getRow());
setColumn(c.getCol()); setColumn((short)c.getCol());
setColRelative(!c.isColAbsolute()); setColRelative(!c.isColAbsolute());
setRowRelative(!c.isRowAbsolute()); setRowRelative(!c.isRowAbsolute());
setExternSheetIndex(externIdx); setExternSheetIndex(externIdx);

View File

@ -105,7 +105,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
* *
* @return the 0-based column of the cell that contains the comment * @return the 0-based column of the cell that contains the comment
*/ */
public short getColumn(){ public int getColumn(){
return col; return col;
} }

View File

@ -17,245 +17,33 @@
package org.apache.poi.hssf.util; package org.apache.poi.hssf.util;
import org.apache.poi.hssf.record.formula.SheetNameFormatter;
/** /**
* * Common convertion functions between Excel style A1, C27 style
* cell references, and POI usermodel style row=0, column=0
* style references.
* @author Avik Sengupta * @author Avik Sengupta
* @author Dennis Doubleday (patch to seperateRowColumns()) * @author Dennis Doubleday (patch to seperateRowColumns())
*/ */
public final class CellReference { public final class CellReference extends org.apache.poi.ss.util.CellReference {
/** The character ($) that signifies a row or column value is absolute instead of relative */
private static final char ABSOLUTE_REFERENCE_MARKER = '$';
/** The character (!) that separates sheet names from cell references */
private static final char SHEET_NAME_DELIMITER = '!';
/** The character (') used to quote sheet names when they contain special characters */
private static final char SPECIAL_NAME_DELIMITER = '\'';
private final int _rowIndex;
private final int _colIndex;
private final String _sheetName;
private final boolean _isRowAbs;
private final boolean _isColAbs;
/** /**
* Create an cell ref from a string representation. Sheet names containing special characters should be * Create an cell ref from a string representation. Sheet names containing special characters should be
* delimited and escaped as per normal syntax rules for formulas. * delimited and escaped as per normal syntax rules for formulas.
*/ */
public CellReference(String cellRef) { public CellReference(String cellRef) {
String[] parts = separateRefParts(cellRef); super(cellRef);
_sheetName = parts[0];
String colRef = parts[1];
if (colRef.length() < 1) {
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
}
_isColAbs = colRef.charAt(0) == '$';
if (_isColAbs) {
colRef=colRef.substring(1);
}
_colIndex = convertColStringToNum(colRef);
String rowRef=parts[2];
if (rowRef.length() < 1) {
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
}
_isRowAbs = rowRef.charAt(0) == '$';
if (_isRowAbs) {
rowRef=rowRef.substring(1);
}
_rowIndex = Integer.parseInt(rowRef)-1; // -1 to convert 1-based to zero-based
} }
public CellReference(int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) { public CellReference(int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
this(null, pRow, pCol, pAbsRow, pAbsCol); this(null, pRow, pCol, pAbsRow, pAbsCol);
} }
public CellReference(String pSheetName, int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) { public CellReference(String pSheetName, int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
// TODO - "-1" is a special value being temporarily used for whole row and whole column area references. super(pSheetName, pRow, pCol, pAbsRow, pAbsCol);
// so these checks are currently N.Q.R.
if(pRow < -1) {
throw new IllegalArgumentException("row index may not be negative");
}
if(pCol < -1) {
throw new IllegalArgumentException("column index may not be negative");
}
_sheetName = pSheetName;
_rowIndex=pRow;
_colIndex=pCol;
_isRowAbs = pAbsRow;
_isColAbs=pAbsCol;
} }
public int getRow(){return _rowIndex;} protected void appendCellReference(StringBuffer sb) {
public short getCol(){return (short) _colIndex;} super.appendCellReference(sb);
public boolean isRowAbsolute(){return _isRowAbs;}
public boolean isColAbsolute(){return _isColAbs;}
/**
* @return possibly <code>null</code> if this is a 2D reference. Special characters are not
* escaped or delimited
*/
public String getSheetName(){
return _sheetName;
} }
/**
* takes in a column reference portion of a CellRef and converts it from
* ALPHA-26 number format to 0-based base 10.
*/
private int convertColStringToNum(String ref) {
int lastIx = ref.length()-1;
int retval=0;
int pos = 0;
for (int k = lastIx; k > -1; k--) {
char thechar = ref.charAt(k);
if ( pos == 0) {
retval += (Character.getNumericValue(thechar)-9);
} else {
retval += (Character.getNumericValue(thechar)-9) * (pos * 26);
}
pos++;
}
return retval-1;
}
/**
* Separates the row from the columns and returns an array of three Strings. The first element
* is the sheet name. Only the first element may be null. The second element in is the column
* name still in ALPHA-26 number format. The third element is the row.
*/
private static String[] separateRefParts(String reference) {
int plingPos = reference.lastIndexOf(SHEET_NAME_DELIMITER);
String sheetName = parseSheetName(reference, plingPos);
int start = plingPos+1;
int length = reference.length();
int loc = start;
// skip initial dollars
if (reference.charAt(loc)==ABSOLUTE_REFERENCE_MARKER) {
loc++;
}
// step over column name chars until first digit (or dollars) for row number.
for (; loc < length; loc++) {
char ch = reference.charAt(loc);
if (Character.isDigit(ch) || ch == ABSOLUTE_REFERENCE_MARKER) {
break;
}
}
return new String[] {
sheetName,
reference.substring(start,loc),
reference.substring(loc),
};
}
private static String parseSheetName(String reference, int indexOfSheetNameDelimiter) {
if(indexOfSheetNameDelimiter < 0) {
return null;
}
boolean isQuoted = reference.charAt(0) == SPECIAL_NAME_DELIMITER;
if(!isQuoted) {
return reference.substring(0, indexOfSheetNameDelimiter);
}
int lastQuotePos = indexOfSheetNameDelimiter-1;
if(reference.charAt(lastQuotePos) != SPECIAL_NAME_DELIMITER) {
throw new RuntimeException("Mismatched quotes: (" + reference + ")");
}
// TODO - refactor cell reference parsing logic to one place.
// Current known incarnations:
// FormulaParser.GetName()
// CellReference.parseSheetName() (here)
// AreaReference.separateAreaRefs()
// SheetNameFormatter.format() (inverse)
StringBuffer sb = new StringBuffer(indexOfSheetNameDelimiter);
for(int i=1; i<lastQuotePos; i++) { // Note boundaries - skip outer quotes
char ch = reference.charAt(i);
if(ch != SPECIAL_NAME_DELIMITER) {
sb.append(ch);
continue;
}
if(i < lastQuotePos) {
if(reference.charAt(i+1) == SPECIAL_NAME_DELIMITER) {
// two consecutive quotes is the escape sequence for a single one
i++; // skip this and keep parsing the special name
sb.append(ch);
continue;
}
}
throw new RuntimeException("Bad sheet name quote escaping: (" + reference + ")");
}
return sb.toString();
}
/**
* Takes in a 0-based base-10 column and returns a ALPHA-26
* representation.
* eg column #3 -> D
*/
protected static String convertNumToColString(int col) { protected static String convertNumToColString(int col) {
String retval = null; return org.apache.poi.ss.util.CellReference.convertNumToColString(col);
int mod = col % 26;
int div = col / 26;
char small=(char)(mod + 65);
char big = (char)(div + 64);
if (div == 0) {
retval = ""+small;
} else {
retval = ""+big+""+small;
}
return retval;
}
/**
* Example return values:
* <table border="0" cellpadding="1" cellspacing="0" summary="Example return values">
* <tr><th align='left'>Result</th><th align='left'>Comment</th></tr>
* <tr><td>A1</td><td>Cell reference without sheet</td></tr>
* <tr><td>Sheet1!A1</td><td>Standard sheet name</td></tr>
* <tr><td>'O''Brien''s Sales'!A1'&nbsp;</td><td>Sheet name with special characters</td></tr>
* </table>
* @return the text representation of this cell reference as it would appear in a formula.
*/
public String formatAsString() {
StringBuffer sb = new StringBuffer(32);
if(_sheetName != null) {
SheetNameFormatter.appendFormat(sb, _sheetName);
sb.append(SHEET_NAME_DELIMITER);
}
appendCellReference(sb);
return sb.toString();
}
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(formatAsString());
sb.append("]");
return sb.toString();
}
/**
* Appends cell reference with '$' markers for absolute values as required.
* Sheet name is not included.
*/
/* package */ void appendCellReference(StringBuffer sb) {
if(_isColAbs) {
sb.append(ABSOLUTE_REFERENCE_MARKER);
}
sb.append( convertNumToColString(_colIndex));
if(_isRowAbs) {
sb.append(ABSOLUTE_REFERENCE_MARKER);
}
sb.append(_rowIndex+1);
} }
} }

View File

@ -0,0 +1,293 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.ss.util;
import org.apache.poi.hssf.record.formula.SheetNameFormatter;
/**
* Common convertion functions between Excel style A1, C27 style
* cell references, and POI usermodel style row=0, column=0
* style references.
* Applys for both HSSF and XSSF.
* @author Avik Sengupta
* @author Dennis Doubleday (patch to seperateRowColumns())
*/
public class CellReference {
/** The character ($) that signifies a row or column value is absolute instead of relative */
private static final char ABSOLUTE_REFERENCE_MARKER = '$';
/** The character (!) that separates sheet names from cell references */
private static final char SHEET_NAME_DELIMITER = '!';
/** The character (') used to quote sheet names when they contain special characters */
private static final char SPECIAL_NAME_DELIMITER = '\'';
private final int _rowIndex;
private final int _colIndex;
private final String _sheetName;
private final boolean _isRowAbs;
private final boolean _isColAbs;
/**
* Create an cell ref from a string representation. Sheet names containing special characters should be
* delimited and escaped as per normal syntax rules for formulas.
*/
public CellReference(String cellRef) {
String[] parts = separateRefParts(cellRef);
_sheetName = parts[0];
String colRef = parts[1];
if (colRef.length() < 1) {
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
}
_isColAbs = colRef.charAt(0) == '$';
if (_isColAbs) {
colRef=colRef.substring(1);
}
_colIndex = convertColStringToNum(colRef);
String rowRef=parts[2];
if (rowRef.length() < 1) {
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
}
_isRowAbs = rowRef.charAt(0) == '$';
if (_isRowAbs) {
rowRef=rowRef.substring(1);
}
_rowIndex = Integer.parseInt(rowRef)-1; // -1 to convert 1-based to zero-based
}
/**
* Creates a cell reference for the given row and cell.
* Assumes these references are relative
*/
public CellReference(int row, int col) {
this(row, col, false, false);
}
public CellReference(int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
this(null, pRow, pCol, pAbsRow, pAbsCol);
}
public CellReference(String pSheetName, int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
// TODO - "-1" is a special value being temporarily used for whole row and whole column area references.
// so these checks are currently N.Q.R.
if(pRow < -1) {
throw new IllegalArgumentException("row index may not be negative");
}
if(pCol < -1) {
throw new IllegalArgumentException("column index may not be negative");
}
_sheetName = pSheetName;
_rowIndex=pRow;
_colIndex=pCol;
_isRowAbs = pAbsRow;
_isColAbs=pAbsCol;
}
public int getRow(){return _rowIndex;}
public int getCol(){return _colIndex;}
public boolean isRowAbsolute(){return _isRowAbs;}
public boolean isColAbsolute(){return _isColAbs;}
/**
* @return possibly <code>null</code> if this is a 2D reference. Special characters are not
* escaped or delimited
*/
public String getSheetName(){
return _sheetName;
}
/**
* takes in a column reference portion of a CellRef and converts it from
* ALPHA-26 number format to 0-based base 10.
* ALPHA-26 goes A to Z, then AA to AZ, BA to BZ, ..., ZA to ZZ,
* AAA to AAZ, ABA to ABZ, ..., AZA to AZZ, BAA to BAZ etc
*/
private int convertColStringToNum(String ref) {
int lastIx = ref.length()-1;
int retval=0;
int pos = 0;
for (int k = lastIx; k > -1; k--) {
char thechar = ref.charAt(k);
// Character.getNumericValue() returns the values
// 10-35 for the letter A-Z
int shift = (int)Math.pow(26, pos);
retval += (Character.getNumericValue(thechar)-9) * shift;
pos++;
}
return retval-1;
}
/**
* Separates the row from the columns and returns an array of three Strings. The first element
* is the sheet name. Only the first element may be null. The second element in is the column
* name still in ALPHA-26 number format. The third element is the row.
*/
private static String[] separateRefParts(String reference) {
int plingPos = reference.lastIndexOf(SHEET_NAME_DELIMITER);
String sheetName = parseSheetName(reference, plingPos);
int start = plingPos+1;
int length = reference.length();
int loc = start;
// skip initial dollars
if (reference.charAt(loc)==ABSOLUTE_REFERENCE_MARKER) {
loc++;
}
// step over column name chars until first digit (or dollars) for row number.
for (; loc < length; loc++) {
char ch = reference.charAt(loc);
if (Character.isDigit(ch) || ch == ABSOLUTE_REFERENCE_MARKER) {
break;
}
}
return new String[] {
sheetName,
reference.substring(start,loc),
reference.substring(loc),
};
}
private static String parseSheetName(String reference, int indexOfSheetNameDelimiter) {
if(indexOfSheetNameDelimiter < 0) {
return null;
}
boolean isQuoted = reference.charAt(0) == SPECIAL_NAME_DELIMITER;
if(!isQuoted) {
return reference.substring(0, indexOfSheetNameDelimiter);
}
int lastQuotePos = indexOfSheetNameDelimiter-1;
if(reference.charAt(lastQuotePos) != SPECIAL_NAME_DELIMITER) {
throw new RuntimeException("Mismatched quotes: (" + reference + ")");
}
// TODO - refactor cell reference parsing logic to one place.
// Current known incarnations:
// FormulaParser.GetName()
// CellReference.parseSheetName() (here)
// AreaReference.separateAreaRefs()
// SheetNameFormatter.format() (inverse)
StringBuffer sb = new StringBuffer(indexOfSheetNameDelimiter);
for(int i=1; i<lastQuotePos; i++) { // Note boundaries - skip outer quotes
char ch = reference.charAt(i);
if(ch != SPECIAL_NAME_DELIMITER) {
sb.append(ch);
continue;
}
if(i < lastQuotePos) {
if(reference.charAt(i+1) == SPECIAL_NAME_DELIMITER) {
// two consecutive quotes is the escape sequence for a single one
i++; // skip this and keep parsing the special name
sb.append(ch);
continue;
}
}
throw new RuntimeException("Bad sheet name quote escaping: (" + reference + ")");
}
return sb.toString();
}
/**
* Takes in a 0-based base-10 column and returns a ALPHA-26
* representation.
* eg column #3 -> D
*/
protected static String convertNumToColString(int col) {
// Excel counts column A as the 1st column, we
// treat it as the 0th one
int excelColNum = col + 1;
String colRef = "";
int colRemain = excelColNum;
while(colRemain > 0) {
int thisPart = colRemain % 26;
if(thisPart == 0) { thisPart = 26; }
colRemain = (colRemain - thisPart) / 26;
// The letter A is at 65
char colChar = (char)(thisPart+64);
colRef = colChar + colRef;
}
return colRef;
}
/**
* Example return values:
* <table border="0" cellpadding="1" cellspacing="0" summary="Example return values">
* <tr><th align='left'>Result</th><th align='left'>Comment</th></tr>
* <tr><td>A1</td><td>Cell reference without sheet</td></tr>
* <tr><td>Sheet1!A1</td><td>Standard sheet name</td></tr>
* <tr><td>'O''Brien''s Sales'!A1'&nbsp;</td><td>Sheet name with special characters</td></tr>
* </table>
* @return the text representation of this cell reference as it would appear in a formula.
*/
public String formatAsString() {
StringBuffer sb = new StringBuffer(32);
if(_sheetName != null) {
SheetNameFormatter.appendFormat(sb, _sheetName);
sb.append(SHEET_NAME_DELIMITER);
}
appendCellReference(sb);
return sb.toString();
}
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(formatAsString());
sb.append("]");
return sb.toString();
}
/**
* Returns the three parts of the cell reference, the
* Sheet name (or null if none supplied), the 1 based
* row number, and the A based column letter.
* This will not include any markers for absolute
* references, so use {@link #formatAsString()}
* to properly turn references into strings.
*/
public String[] getCellRefParts() {
return new String[] {
_sheetName,
Integer.toString(_rowIndex+1),
convertNumToColString(_colIndex)
};
}
/**
* Appends cell reference with '$' markers for absolute values as required.
* Sheet name is not included.
*/
protected void appendCellReference(StringBuffer sb) {
if(_isColAbs) {
sb.append(ABSOLUTE_REFERENCE_MARKER);
}
sb.append( convertNumToColString(_colIndex));
if(_isRowAbs) {
sb.append(ABSOLUTE_REFERENCE_MARKER);
}
sb.append(_rowIndex+1);
}
}

View File

@ -52,7 +52,7 @@ public interface Comment {
* *
* @return the 0-based column of the cell that contains the comment * @return the 0-based column of the cell that contains the comment
*/ */
short getColumn(); int getColumn();
/** /**
* Set the column of the cell that contains the comment * Set the column of the cell that contains the comment

View File

@ -22,8 +22,8 @@ import java.io.OutputStream;
import org.apache.poi.ss.usermodel.Comment; import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CommentsSource; import org.apache.poi.ss.usermodel.CommentsSource;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFComment; import org.apache.poi.xssf.usermodel.XSSFComment;
import org.apache.poi.xssf.util.CellReference;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAuthors; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAuthors;
@ -90,7 +90,8 @@ public class CommentsTable implements CommentsSource, XSSFModel {
} }
public XSSFComment findCellComment(int row, int column) { public XSSFComment findCellComment(int row, int column) {
return findCellComment(new CellReference().convertRowColToString((short)row, (short)column)); return findCellComment(
(new CellReference(row, column)).formatAsString() );
} }
public XSSFComment findCellComment(String cellRef) { public XSSFComment findCellComment(String cellRef) {

View File

@ -29,7 +29,7 @@ import org.apache.poi.ss.usermodel.SharedStringSource;
import org.apache.poi.ss.usermodel.StylesSource; import org.apache.poi.ss.usermodel.StylesSource;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.xssf.util.CellReference; import org.apache.poi.ss.util.CellReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType;
@ -222,7 +222,8 @@ public class XSSFCell implements Cell {
} }
public void setCellComment(Comment comment) { public void setCellComment(Comment comment) {
String cellRef = new CellReference().convertRowColToString((short) row.getRowNum(), getCellNum()); String cellRef =
new CellReference(row.getRowNum(), getCellNum()).formatAsString();
row.getSheet().setCellComment(cellRef, (XSSFComment)comment); row.getSheet().setCellComment(cellRef, (XSSFComment)comment);
} }

View File

@ -20,7 +20,7 @@ import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CommentsSource; import org.apache.poi.ss.usermodel.CommentsSource;
import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.xssf.usermodel.helpers.RichTextStringHelper; import org.apache.poi.xssf.usermodel.helpers.RichTextStringHelper;
import org.apache.poi.xssf.util.CellReference; import org.apache.poi.ss.util.CellReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst;
@ -42,7 +42,7 @@ public class XSSFComment implements Comment {
return comments.getAuthor(comment.getAuthorId()); return comments.getAuthor(comment.getAuthorId());
} }
public short getColumn() { public int getColumn() {
return (new CellReference(comment.getRef())).getCol(); return (new CellReference(comment.getRef())).getCol();
} }
@ -63,7 +63,8 @@ public class XSSFComment implements Comment {
public void setColumn(short col) { public void setColumn(short col) {
initializeRef(); initializeRef();
String newRef = (new CellReference(comment.getRef())).convertRowColToString((short) getRow(), col); String newRef =
(new CellReference(getRow(), col)).formatAsString();
comment.setRef(newRef); comment.setRef(newRef);
} }
@ -75,7 +76,8 @@ public class XSSFComment implements Comment {
public void setRow(int row) { public void setRow(int row) {
initializeRef(); initializeRef();
String newRef = (new CellReference(comment.getRef())).convertRowColToString((short) row, getColumn()); String newRef =
(new CellReference(row, getColumn())).formatAsString();
comment.setRef(newRef); comment.setRef(newRef);
} }

View File

@ -34,9 +34,9 @@ import org.apache.poi.ss.usermodel.Patriarch;
import org.apache.poi.ss.usermodel.PrintSetup; import org.apache.poi.ss.usermodel.PrintSetup;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.model.CommentsTable; import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
import org.apache.poi.xssf.util.CellReference;
import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
@ -377,7 +377,7 @@ public class XSSFSheet implements Sheet {
public short getLeftCol() { public short getLeftCol() {
String cellRef = worksheet.getSheetViews().getSheetViewArray(0).getTopLeftCell(); String cellRef = worksheet.getSheetViews().getSheetViewArray(0).getTopLeftCell();
CellReference cellReference = new CellReference(cellRef); CellReference cellReference = new CellReference(cellRef);
return cellReference.getCol(); return (short)cellReference.getCol();
} }
public double getMargin(short margin) { public double getMargin(short margin) {
@ -832,8 +832,8 @@ public class XSSFSheet implements Sheet {
} }
public void showInPane(short toprow, short leftcol) { public void showInPane(short toprow, short leftcol) {
CellReference cellReference = new CellReference(); CellReference cellReference = new CellReference(toprow, leftcol);
String cellRef = cellReference.convertRowColToString(toprow, leftcol); String cellRef = cellReference.formatAsString();
getSheetTypeSheetView().setTopLeftCell(cellRef); getSheetTypeSheetView().setTopLeftCell(cellRef);
} }

View File

@ -1,102 +0,0 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.xssf.util;
public class CellReference {
private int row;
private short col;
public CellReference() {
}
public CellReference(String cellRef) {
if (cellRef == null || "".equals(cellRef)) {
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
}
String[] parts = getCellRefParts(cellRef);
col = getColNumFromRef(parts[0]);
row = getRowNumFromRef(parts[1]);
}
public CellReference(short col, int row) {
this.col = col;
this.row = row;
}
public int getRow() {
return this.row;
}
public short getCol() {
return this.col;
}
public String[] getCellRefParts(String cellRef) {
StringBuffer sb0 = new StringBuffer("");
StringBuffer sb1 = new StringBuffer("");
String[] parts = new String[2];
for (int i = 0 ; i < cellRef.length() ; i++) {
char item = cellRef.charAt(i);
if ((int)item >= 65 && (int)item <= 90) {
sb0.append(item);
}
else {
sb1.append(item);
}
}
parts[0] = sb0.toString();
parts[1] = sb1.toString();
return parts;
}
public int getRowNumFromRef(String rowRef) {
return (new Integer(rowRef).intValue()) - 1;
}
public short getColNumFromRef(String colRef) {
double columnIndex = -1;
for (int i = (colRef.length() - 1) ; i >= 0 ; i--) {
char numericCharValue = colRef.charAt(colRef.length() - (i + 1));
int convertedNumericCharValue = (numericCharValue - 64);
double indexIncrement = (convertedNumericCharValue * Math.pow(26, i));
columnIndex = columnIndex + indexIncrement;
}
return (short)columnIndex;
}
public String convertNumToColString(short col) {
String colRef = "";
double div = 1;
double mod = 0;
for (int i = 0 ; div >= 1 ; i ++) {
mod = col % 26;
div = col / 26;
int AsciiIncrement = (i != 0 ? 64 : 65);
char modToChar = (char)(mod + AsciiIncrement);
colRef = modToChar + colRef;
col = (short) ((col - mod) / 26);
}
return colRef;
}
public String convertRowColToString(short row, short col) {
return convertNumToColString(col) + ((short) (row + 1));
}
}

View File

@ -19,8 +19,8 @@ package org.apache.poi.xssf.usermodel;
import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.model.CommentsTable; import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.util.CellReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAuthors; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAuthors;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments;

View File

@ -17,101 +17,155 @@
package org.apache.poi.xssf.util; package org.apache.poi.xssf.util;
import org.apache.poi.xssf.util.CellReference; import org.apache.poi.ss.util.CellReference;
import junit.framework.TestCase; import junit.framework.TestCase;
/**
* Tests that the common CellReference works as we need it to
*/
public class TestCellReference extends TestCase { public class TestCellReference extends TestCase {
public void testGetCellRefParts() { public void testGetCellRefParts() {
CellReference cellReference;
String[] parts;
String cellRef = "A1"; String cellRef = "A1";
CellReference cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
String[] parts = cellReference.getCellRefParts(cellRef); assertEquals(0, cellReference.getCol());
parts = cellReference.getCellRefParts();
assertNotNull(parts); assertNotNull(parts);
assertEquals("A", parts[0]); assertEquals(null, parts[0]);
assertEquals("1", parts[1]); assertEquals("1", parts[1]);
assertEquals("A", parts[2]);
cellRef = "AA1"; cellRef = "AA1";
cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
parts = cellReference.getCellRefParts(cellRef); assertEquals(26, cellReference.getCol());
parts = cellReference.getCellRefParts();
assertNotNull(parts); assertNotNull(parts);
assertEquals("AA", parts[0]); assertEquals(null, parts[0]);
assertEquals("1", parts[1]); assertEquals("1", parts[1]);
assertEquals("AA", parts[2]);
cellRef = "AA100"; cellRef = "AA100";
cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
parts = cellReference.getCellRefParts(cellRef); assertEquals(26, cellReference.getCol());
parts = cellReference.getCellRefParts();
assertNotNull(parts); assertNotNull(parts);
assertEquals("AA", parts[0]); assertEquals(null, parts[0]);
assertEquals("100", parts[1]); assertEquals("100", parts[1]);
assertEquals("AA", parts[2]);
cellRef = "AAA300";
cellReference = new CellReference(cellRef);
assertEquals(702, cellReference.getCol());
parts = cellReference.getCellRefParts();
assertNotNull(parts);
assertEquals(null, parts[0]);
assertEquals("300", parts[1]);
assertEquals("AAA", parts[2]);
cellRef = "ZZ100521";
cellReference = new CellReference(cellRef);
assertEquals(26*26+25, cellReference.getCol());
parts = cellReference.getCellRefParts();
assertNotNull(parts);
assertEquals(null, parts[0]);
assertEquals("100521", parts[1]);
assertEquals("ZZ", parts[2]);
cellRef = "ZYX987";
cellReference = new CellReference(cellRef);
assertEquals(26*26*26 + 25*26 + 24 - 1, cellReference.getCol());
parts = cellReference.getCellRefParts();
assertNotNull(parts);
assertEquals(null, parts[0]);
assertEquals("987", parts[1]);
assertEquals("ZYX", parts[2]);
cellRef = "AABC10065"; cellRef = "AABC10065";
cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
parts = cellReference.getCellRefParts(cellRef); parts = cellReference.getCellRefParts();
assertNotNull(parts); assertNotNull(parts);
assertEquals("AABC", parts[0]); assertEquals(null, parts[0]);
assertEquals("10065", parts[1]); assertEquals("10065", parts[1]);
assertEquals("AABC", parts[2]);
} }
public void testGetColNumFromRef() { public void testGetColNumFromRef() {
String cellRef = "A1"; String cellRef = "A1";
CellReference cellReference = new CellReference(cellRef); CellReference cellReference = new CellReference(cellRef);
String[] parts = cellReference.getCellRefParts(cellRef); assertEquals(0, cellReference.getCol());
short col = cellReference.getColNumFromRef(parts[0]);
assertEquals(0, col); cellRef = "AA1";
cellReference = new CellReference(cellRef);
assertEquals(26, cellReference.getCol());
cellRef = "AB1"; cellRef = "AB1";
cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
parts = cellReference.getCellRefParts(cellRef); assertEquals(27, cellReference.getCol());
col = cellReference.getColNumFromRef(parts[0]);
assertEquals(27, col); cellRef = "BA1";
cellReference = new CellReference(cellRef);
assertEquals(26+26, cellReference.getCol());
cellRef = "CA1";
cellReference = new CellReference(cellRef);
assertEquals(26+26+26, cellReference.getCol());
cellRef = "ZA1";
cellReference = new CellReference(cellRef);
assertEquals(26*26, cellReference.getCol());
cellRef = "ZZ1";
cellReference = new CellReference(cellRef);
assertEquals(26*26+25, cellReference.getCol());
cellRef = "AAA1";
cellReference = new CellReference(cellRef);
assertEquals(26*26+26, cellReference.getCol());
cellRef = "A1100"; cellRef = "A1100";
cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
parts = cellReference.getCellRefParts(cellRef); assertEquals(0, cellReference.getCol());
col = cellReference.getColNumFromRef(parts[0]);
assertEquals(0, col);
cellRef = "BC15"; cellRef = "BC15";
cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
parts = cellReference.getCellRefParts(cellRef); assertEquals(54, cellReference.getCol());
col = cellReference.getColNumFromRef(parts[0]);
assertEquals(54, col);
} }
public void testGetRowNumFromRef() { public void testGetRowNumFromRef() {
String cellRef = "A1"; String cellRef = "A1";
CellReference cellReference = new CellReference(cellRef); CellReference cellReference = new CellReference(cellRef);
String[] parts = cellReference.getCellRefParts(cellRef); assertEquals(0, cellReference.getRow());
int row = cellReference.getRowNumFromRef(parts[1]);
assertEquals(0, row);
cellRef = "A12"; cellRef = "A12";
cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
parts = cellReference.getCellRefParts(cellRef); assertEquals(11, cellReference.getRow());
row = cellReference.getRowNumFromRef(parts[1]);
assertEquals(11, row);
cellRef = "AS121"; cellRef = "AS121";
cellReference = new CellReference(cellRef); cellReference = new CellReference(cellRef);
parts = cellReference.getCellRefParts(cellRef); assertEquals(120, cellReference.getRow());
row = cellReference.getRowNumFromRef(parts[1]);
assertEquals(120, row);
} }
public void testConvertNumToColString() { public void testConvertNumToColString() {
short col = 702; short col = 702;
String collRef = new CellReference().convertNumToColString(col); String collRef = new CellReference(0, col).formatAsString();
assertEquals("AAA", collRef); assertEquals("AAA1", collRef);
System.err.println("***");
short col2 = 0;
String collRef2 = new CellReference().convertNumToColString(col2);
assertEquals("A", collRef2);
short col3 = 27;
String collRef3 = new CellReference().convertNumToColString(col3);
assertEquals("AB", collRef3);
}
short col2 = 0;
String collRef2 = new CellReference(0, col2).formatAsString();
assertEquals("A1", collRef2);
short col3 = 27;
String collRef3 = new CellReference(0, col3).formatAsString();
assertEquals("AB1", collRef3);
short col4 = 2080;
String collRef4 = new CellReference(0, col4).formatAsString();
assertEquals("CBA1", collRef4);
}
} }