@ -36,6 +36,7 @@ import com.fr.third.v2.org.apache.poi.ss.usermodel.Cell;
import com.fr.third.v2.org.apache.poi.ss.usermodel.CellStyle ;
import com.fr.third.v2.org.apache.poi.ss.usermodel.CellType ;
import com.fr.third.v2.org.apache.poi.ss.usermodel.FormulaError ;
import com.fr.third.v2.org.apache.poi.ss.usermodel.RichTextString ;
import com.fr.third.v2.org.apache.poi.ss.util.CellReference ;
import com.fr.third.v2.org.apache.poi.util.POILogFactory ;
import com.fr.third.v2.org.apache.poi.util.POILogger ;
@ -201,113 +202,116 @@ public class SheetDataWriter implements Closeable {
_numberLastFlushedRow = Math . max ( rownum , _numberLastFlushedRow ) ;
_numberOfCellsOfLastFlushedRow = row . getLastCellNum ( ) ;
_numberOfFlushedRows + + ;
beginRow ( rownum , row ) ;
int size = this . _numberOfCellsOfLastFlushedRow > 0 ? this . _numberOfCellsOfLastFlushedRow : 1 ;
StringBuilder sb = new StringBuilder ( size < < 6 ) ;
beginRow ( rownum , row , sb ) ;
Iterator < Cell > cells = row . allCellsIterator ( ) ;
int columnIndex = 0 ;
while ( cells . hasNext ( ) ) {
writeCell ( columnIndex + + , cells . next ( ) ) ;
writeCell ( columnIndex + + , cells . next ( ) , sb ) ;
}
endRow ( ) ;
endRow ( sb ) ;
this . _out . write ( sb . toString ( ) ) ;
}
void beginRow ( int rownum , SXSSFRow row ) throws IOException {
_out . write ( "<row" ) ;
writeAttribute ( "r" , Integer . toString ( rownum + 1 ) ) ;
void beginRow ( int rownum , SXSSFRow row , StringBuilder sb ) throws IOException {
sb . append ( "<row" ) ;
writeAttribute ( "r" , Integer . toString ( rownum + 1 ) , sb ) ;
if ( row . hasCustomHeight ( ) ) {
writeAttribute ( "customHeight" , "true" ) ;
writeAttribute ( "ht" , Float . toString ( row . getHeightInPoints ( ) ) ) ;
writeAttribute ( "customHeight" , "true" , sb ) ;
writeAttribute ( "ht" , Float . toString ( row . getHeightInPoints ( ) ) , sb ) ;
}
if ( row . getZeroHeight ( ) ) {
writeAttribute ( "hidden" , "true" ) ;
writeAttribute ( "hidden" , "true" , sb ) ;
}
if ( row . isFormatted ( ) ) {
writeAttribute ( "s" , Integer . toString ( row . getRowStyleIndex ( ) ) ) ;
writeAttribute ( "customFormat" , "1" ) ;
writeAttribute ( "s" , Integer . toString ( row . getRowStyleIndex ( ) ) , sb ) ;
writeAttribute ( "customFormat" , "1" , sb ) ;
}
if ( row . getOutlineLevel ( ) ! = 0 ) {
writeAttribute ( "outlineLevel" , Integer . toString ( row . getOutlineLevel ( ) ) ) ;
writeAttribute ( "outlineLevel" , Integer . toString ( row . getOutlineLevel ( ) ) , sb ) ;
}
if ( row . getHidden ( ) ! = null ) {
writeAttribute ( "hidden" , row . getHidden ( ) ? "1" : "0" ) ;
writeAttribute ( "hidden" , row . getHidden ( ) ? "1" : "0" , sb ) ;
}
if ( row . getCollapsed ( ) ! = null ) {
writeAttribute ( "collapsed" , row . getCollapsed ( ) ? "1" : "0" ) ;
writeAttribute ( "collapsed" , row . getCollapsed ( ) ? "1" : "0" , sb ) ;
}
_out . write ( ">\n" ) ;
sb . append ( ">\n" ) ;
this . _rownum = rownum ;
}
void endRow ( ) throws IOException {
_out . write ( "</row>\n" ) ;
void endRow ( StringBuilder sb ) throws IOException {
sb . append ( "</row>\n" ) ;
}
public void writeCell ( int columnIndex , Cell cell ) throws IOException {
public void writeCell ( int columnIndex , Cell cell , StringBuilder sb ) throws IOException {
if ( cell = = null ) {
return ;
}
String ref = new CellReference ( _rownum , columnIndex ) . formatAsString ( ) ;
_out . write ( "<c" ) ;
writeAttribute ( "r" , ref ) ;
sb . append ( "<c" ) ;
writeAttribute ( "r" , ref , sb ) ;
CellStyle cellStyle = cell . getCellStyle ( ) ;
if ( cellStyle . getIndex ( ) ! = 0 ) {
// need to convert the short to unsigned short as the indexes can be up to 64k
// ideally we would use int for this index, but that would need changes to some more
// APIs
writeAttribute ( "s" , Integer . toString ( cellStyle . getIndex ( ) & 0xffff ) ) ;
writeAttribute ( "s" , Integer . toString ( cellStyle . getIndex ( ) & 0xffff ) , sb ) ;
}
CellType cellType = cell . getCellType ( ) ;
switch ( cellType ) {
case BLANK : {
_out . write ( '>' ) ;
sb . append ( '>' ) ;
break ;
}
case FORMULA : {
switch ( cell . getCachedFormulaResultType ( ) ) {
case NUMERIC :
writeAttribute ( "t" , "n" ) ;
writeAttribute ( "t" , "n" , sb ) ;
break ;
case STRING :
writeAttribute ( "t" , STCellType . STR . toString ( ) ) ;
writeAttribute ( "t" , STCellType . STR . toString ( ) , sb ) ;
break ;
case BOOLEAN :
writeAttribute ( "t" , "b" ) ;
writeAttribute ( "t" , "b" , sb ) ;
break ;
case ERROR :
writeAttribute ( "t" , "e" ) ;
writeAttribute ( "t" , "e" , sb ) ;
break ;
}
_out . write ( "><f>" ) ;
outputQuotedString ( cell . getCellFormula ( ) ) ;
_out . write ( "</f>" ) ;
sb . append ( "><f>" ) ;
outputQuotedString ( cell . getCellFormula ( ) , sb ) ;
sb . append ( "</f>" ) ;
switch ( cell . getCachedFormulaResultType ( ) ) {
case NUMERIC :
double nval = cell . getNumericCellValue ( ) ;
if ( ! Double . isNaN ( nval ) ) {
_out . write ( "<v>" ) ;
_out . write ( Double . toString ( nval ) ) ;
_out . write ( "</v>" ) ;
sb . append ( "<v>" ) ;
sb . append ( Double . toString ( nval ) ) ;
sb . append ( "</v>" ) ;
}
break ;
case STRING :
String value = cell . getStringCellValue ( ) ;
if ( value ! = null & & ! value . isEmpty ( ) ) {
_out . write ( "<v>" ) ;
_out . write ( value ) ;
_out . write ( "</v>" ) ;
sb . append ( "<v>" ) ;
sb . append ( value ) ;
sb . append ( "</v>" ) ;
}
break ;
case BOOLEAN :
_out . write ( "><v>" ) ;
_out . write ( cell . getBooleanCellValue ( ) ? "1" : "0" ) ;
_out . write ( "</v>" ) ;
sb . append ( "><v>" ) ;
sb . append ( cell . getBooleanCellValue ( ) ? "1" : "0" ) ;
sb . append ( "</v>" ) ;
break ;
case ERROR : {
FormulaError error = FormulaError . forInt ( cell . getErrorCellValue ( ) ) ;
_out . write ( "><v>" ) ;
_out . write ( error . getString ( ) ) ;
_out . write ( "</v>" ) ;
sb . append ( "><v>" ) ;
sb . append ( error . getString ( ) ) ;
sb . append ( "</v>" ) ;
break ;
}
}
@ -315,81 +319,81 @@ public class SheetDataWriter implements Closeable {
}
case STRING : {
if ( _sharedStringSource ! = null & & cell . isRichText ( ) ) {
XSSF RichTextString rt = new XSSFRichTextString ( cell . getStringCellValue ( ) ) ;
RichTextString rt = cell . getRich StringCellValue ( ) ;
int sRef = _sharedStringSource . addSharedStringItem ( rt ) ;
writeAttribute ( "t" , STCellType . S . toString ( ) ) ;
_out . write ( "><v>" ) ;
_out . write ( String . valueOf ( sRef ) ) ;
_out . write ( "</v>" ) ;
writeAttribute ( "t" , STCellType . S . toString ( ) , sb ) ;
sb . append ( "><v>" ) ;
sb . append ( String . valueOf ( sRef ) ) ;
sb . append ( "</v>" ) ;
} else {
writeAttribute ( "t" , "inlineStr" ) ;
_out . write ( "><is><t" ) ;
writeAttribute ( "t" , "inlineStr" , sb ) ;
sb . append ( "><is><t" ) ;
if ( hasLeadingTrailingSpaces ( cell . getStringCellValue ( ) ) ) {
writeAttribute ( "xml:space" , "preserve" ) ;
writeAttribute ( "xml:space" , "preserve" , sb ) ;
}
_out . write ( ">" ) ;
outputQuotedString ( cell . getStringCellValue ( ) ) ;
_out . write ( "</t></is>" ) ;
sb . append ( ">" ) ;
outputQuotedString ( cell . getStringCellValue ( ) , sb ) ;
sb . append ( "</t></is>" ) ;
}
break ;
}
case NUMERIC_STRING : {
_out . write ( " t=\"n\"><v>" ) ;
_out . write ( cell . getNumericStringCellValue ( ) ) ;
_out . write ( "</v>" ) ;
sb . append ( " t=\"n\"><v>" ) ;
sb . append ( cell . getNumericStringCellValue ( ) ) ;
sb . append ( "</v>" ) ;
break ;
}
case NUMERIC_BIG_DECIMAL : {
_out . write ( " t=\"n\">" ) ;
_out . write ( "<v>" ) ;
_out . write ( cell . getNumericBigDecimalCellValue ( ) . toString ( ) ) ;
_out . write ( "</v>" ) ;
sb . append ( " t=\"n\">" ) ;
sb . append ( "<v>" ) ;
sb . append ( cell . getNumericBigDecimalCellValue ( ) . toString ( ) ) ;
sb . append ( "</v>" ) ;
break ;
}
case NUMERIC_BIG_INTEGER : {
_out . write ( " t=\"n\">" ) ;
_out . write ( "<v>" ) ;
_out . write ( cell . getNumericBigIntegerCellValue ( ) . toString ( ) ) ;
_out . write ( "</v>" ) ;
sb . append ( " t=\"n\">" ) ;
sb . append ( "<v>" ) ;
sb . append ( cell . getNumericBigIntegerCellValue ( ) . toString ( ) ) ;
sb . append ( "</v>" ) ;
break ;
}
case NUMERIC : {
writeAttribute ( "t" , "n" ) ;
_out . write ( "><v>" ) ;
_out . write ( Double . toString ( cell . getNumericCellValue ( ) ) ) ;
_out . write ( "</v>" ) ;
writeAttribute ( "t" , "n" , sb ) ;
sb . append ( "><v>" ) ;
sb . append ( Double . toString ( cell . getNumericCellValue ( ) ) ) ;
sb . append ( "</v>" ) ;
break ;
}
case BOOLEAN : {
writeAttribute ( "t" , "b" ) ;
_out . write ( "><v>" ) ;
_out . write ( cell . getBooleanCellValue ( ) ? "1" : "0" ) ;
_out . write ( "</v>" ) ;
writeAttribute ( "t" , "b" , sb ) ;
sb . append ( "><v>" ) ;
sb . append ( cell . getBooleanCellValue ( ) ? "1" : "0" ) ;
sb . append ( "</v>" ) ;
break ;
}
case ERROR : {
FormulaError error = FormulaError . forInt ( cell . getErrorCellValue ( ) ) ;
writeAttribute ( "t" , "e" ) ;
_out . write ( "><v>" ) ;
_out . write ( error . getString ( ) ) ;
_out . write ( "</v>" ) ;
writeAttribute ( "t" , "e" , sb ) ;
sb . append ( "><v>" ) ;
sb . append ( error . getString ( ) ) ;
sb . append ( "</v>" ) ;
break ;
}
default : {
throw new IllegalStateException ( "Invalid cell type: " + cellType ) ;
}
}
_out . write ( "</c>" ) ;
sb . append ( "</c>" ) ;
}
private void writeAttribute ( String name , String value ) throws IOException {
_out . write ( ' ' ) ;
_out . write ( name ) ;
_out . write ( "=\"" ) ;
_out . write ( value ) ;
_out . write ( '\"' ) ;
private void writeAttribute ( String name , String value , StringBuilder sb ) throws IOException {
sb . append ( ' ' ) ;
sb . append ( name ) ;
sb . append ( "=\"" ) ;
sb . append ( value ) ;
sb . append ( '\"' ) ;
}
/ * *
@ -405,7 +409,7 @@ public class SheetDataWriter implements Closeable {
return false ;
}
protected void outputQuotedString ( String s ) throws IOException {
protected void outputQuotedString ( String s , StringBuilder sb ) throws IOException {
if ( s = = null | | s . length ( ) = = 0 ) {
return ;
}
@ -413,29 +417,29 @@ public class SheetDataWriter implements Closeable {
for ( String codepoint : new StringCodepointsIterable ( s ) ) {
switch ( codepoint ) {
case "<" :
_out . write ( "<" ) ;
sb . append ( "<" ) ;
break ;
case ">" :
_out . write ( ">" ) ;
sb . append ( ">" ) ;
break ;
case "&" :
_out . write ( "&" ) ;
sb . append ( "&" ) ;
break ;
case "\"" :
_out . write ( """ ) ;
sb . append ( """ ) ;
break ;
// Special characters
case "\n" :
_out . write ( "
" ) ;
sb . append ( "
" ) ;
break ;
case "\r" :
_out . write ( "
" ) ;
sb . append ( "
" ) ;
break ;
case "\t" :
_out . write ( "	" ) ;
sb . append ( "	" ) ;
break ;
case "\u00A0" : // NO-BREAK SPACE
_out . write ( " " ) ;
sb . append ( " " ) ;
break ;
default :
if ( codepoint . length ( ) = = 1 ) {
@ -443,12 +447,12 @@ public class SheetDataWriter implements Closeable {
// YK: XmlBeans silently replaces all ISO control characters ( < 32) with question marks.
// the same rule applies to "not a character" symbols.
if ( replaceWithQuestionMark ( c ) ) {
_out . write ( '?' ) ;
sb . append ( '?' ) ;
} else {
_out . write ( c ) ;
sb . append ( c ) ;
}
} else {
_out . write ( codepoint ) ;
sb . append ( codepoint ) ;
}
break ;
}