Вы находитесь на странице: 1из 23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features

Busy Developers' Guide to HSSF and XSSF Features


Busy Developers' Guide to Features Want to use HSSF and XSSF read and write spreadsheets in a hurry? This guide is for you. If you're after more in-depth coverage of the HSSF and XSSF user-APIs, please consult the HOWTO guide as it contains actual descriptions of how to use this stuff. Index of Features How to create a new workbook How to create a sheet How to create cells How to create date cells Working with different types of cells Iterate over rows and cells Getting the cell contents Text Extraction Files vs InputStreams Aligning cells Working with borders Fills and color Merging cells Working with fonts Custom colors Reading and writing Use newlines in cells. Create user defined data formats Fit Sheet to One Page Set print area for a sheet Set page numbers on the footer of a sheet Shift rows Set a sheet as selected Set the zoom magnification for a sheet Create split and freeze panes Repeating rows and columns Headers and Footers Drawing Shapes Styling Shapes Shapes and Graphics2d Outlining Images Named Ranges and Named Cells How to set cell comments How to adjust column width to fit the contents Hyperlinks Data Validations Embedded Objects Autofilters Conditional Formatting Hiding and Un-Hiding Rows Features

New Workbook
W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ; W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s x " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

New Sheet
W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; / /o rn e wX S S F W o r k b o o k ( ) ; S h e e ts h e e t 1=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; S h e e ts h e e t 2=w b . c r e a t e S h e e t ( " s e c o n ds h e e t " ) ; / /N o t et h a ts h e e tn a m ei sE x c e lm u s tn o te x c e e d3 1c h a r a c t e r s / /a n dm u s tn o tc o n t a i na n yo ft h ea n yo ft h ef o l l o w i n gc h a r a c t e r s : / /0 x 0 0 0 0 / /0 x 0 0 0 3 / /c o l o n( : ) / /b a c k s l a s h( \ )

poi.apache.org/spreadsheet/quick-guide.html#CellContents

1/23

3/25/13
/ /b a c k s l a s h( \ ) / /a s t e r i s k( * ) / /q u e s t i o nm a r k( ? ) / /f o r w a r ds l a s h( / ) / /o p e n i n gs q u a r eb r a c k e t( [ ) / /c l o s i n gs q u a r eb r a c k e t( ] )

Busy Developers' Guide to HSSF and XSSF Features

/ /Y o uc a nu s eo r g . a p a c h e . p o i . s s . u t i l . W o r k b o o k U t i l # c r e a t e S a f e S h e e t N a m e ( S t r i n gn a m e P r o p o s a l ) } / /f o ras a f ew a yt oc r e a t ev a l i dn a m e s ,t h i su t i l i t yr e p l a c e si n v a l i dc h a r a c t e r sw i t has p a c e( '' ) S t r i n gs a f e N a m e=W o r k b o o k U t i l . c r e a t e S a f e S h e e t N a m e ( " [ O ' B r i e n ' ss a l e s * ? ] " ) ;/ /r e t u r n s"O ' B r i e n ' ss a l e s S h e e ts h e e t 3=w b . c r e a t e S h e e t ( s a f e N a m e ) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

"

Creating Cells
W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; / / W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ; C r e a t i o n H e l p e rc r e a t e H e l p e r=w b . g e t C r e a t i o n H e l p e r ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; / /C r e a t ear o wa n dp u ts o m ec e l l si ni t .R o w sa r e0b a s e d . R o wr o w=s h e e t . c r e a t e R o w ( ( s h o r t ) 0 ) ; / /C r e a t eac e l la n dp u tav a l u ei ni t . C e l lc e l l=r o w . c r e a t e C e l l ( 0 ) ; c e l l . s e t C e l l V a l u e ( 1 ) ; / /O rd oi to no n el i n e . r o w . c r e a t e C e l l ( 1 ) . s e t C e l l V a l u e ( 1 . 2 ) ; r o w . c r e a t e C e l l ( 2 ) . s e t C e l l V a l u e ( c r e a t e H e l p e r . c r e a t e R i c h T e x t S t r i n g ( " T h i si sas t r i n g " ) ) ; r o w . c r e a t e C e l l ( 3 ) . s e t C e l l V a l u e ( t r u e ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Creating Date Cells


W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; / / W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ; C r e a t i o n H e l p e rc r e a t e H e l p e r=w b . g e t C r e a t i o n H e l p e r ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; / /C r e a t ear o wa n dp u ts o m ec e l l si ni t .R o w sa r e0b a s e d . R o wr o w=s h e e t . c r e a t e R o w ( 0 ) ; / /C r e a t eac e l la n dp u tad a t ev a l u ei ni t . T h ef i r s tc e l li sn o ts t y l e d / /a sad a t e . C e l lc e l l=r o w . c r e a t e C e l l ( 0 ) ; c e l l . s e t C e l l V a l u e ( n e wD a t e ( ) ) ; / /w es t y l et h es e c o n dc e l la sad a t e( a n dt i m e ) . I ti si m p o r t a n tt o / /c r e a t ean e wc e l ls t y l ef r o mt h ew o r k b o o ko t h e r w i s ey o uc a ne n du p / /m o d i f y i n gt h eb u i l ti ns t y l ea n de f f e c t i n gn o to n l yt h i sc e l lb u to t h e rc e l l s . C e l l S t y l ec e l l S t y l e=w b . c r e a t e C e l l S t y l e ( ) ; c e l l S t y l e . s e t D a t a F o r m a t ( c r e a t e H e l p e r . c r e a t e D a t a F o r m a t ( ) . g e t F o r m a t ( " m / d / y yh : m m " ) ) ; c e l l=r o w . c r e a t e C e l l ( 1 ) ; c e l l . s e t C e l l V a l u e ( n e wD a t e ( ) ) ; c e l l . s e t C e l l S t y l e ( c e l l S t y l e ) ; / / y o uc a na l s os e td a t ea sj a v a . u t i l . C a l e n d a r c e l l=r o w . c r e a t e C e l l ( 2 ) ; c e l l . s e t C e l l V a l u e ( C a l e n d a r . g e t I n s t a n c e ( ) ) ; c e l l . s e t C e l l S t y l e ( c e l l S t y l e ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Working with different types of cells


poi.apache.org/spreadsheet/quick-guide.html#CellContents
W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ;

2/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; R o wr o w=s h e e t . c r e a t e R o w ( ( s h o r t ) 2 ) ; r o w . c r e a t e C e l l ( 0 ) . s e t C e l l V a l u e ( 1 . 1 ) ; r o w . c r e a t e C e l l ( 1 ) . s e t C e l l V a l u e ( n e wD a t e ( ) ) ; r o w . c r e a t e C e l l ( 2 ) . s e t C e l l V a l u e ( C a l e n d a r . g e t I n s t a n c e ( ) ) ; r o w . c r e a t e C e l l ( 3 ) . s e t C e l l V a l u e ( " as t r i n g " ) ; r o w . c r e a t e C e l l ( 4 ) . s e t C e l l V a l u e ( t r u e ) ; r o w . c r e a t e C e l l ( 5 ) . s e t C e l l T y p e ( C e l l . C E L L _ T Y P E _ E R R O R ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Files vs InputStreams
When opening a workbook, either a .xls HSSFWorkbook, or a .xlsx XSSFWorkbook, the Workbook can be loaded from either a File or an InputStream. Using a File object allows for lower memory consumption, while an InputStream requires more memory as it has to buffer the whole file. If using WorkbookFactory, it's very easy to use one or the other: / /U s eaf i l e W o r k b o o kw b=W o r k b o o k F a c t o r y . c r e a t e ( n e wF i l e ( " M y E x c e l . x l s " ) ) ; / /U s ea nI n p u t S t r e a m ,n e e d sm o r em e m o r y W o r k b o o kw b=W o r k b o o k F a c t o r y . c r e a t e ( n e wF i l e I n p u t S t r e a m ( " M y E x c e l . x l s x " ) ) ; If using HSSFWorkbook or XSSFWorkbook directly, you should generally go through NPOIFSFileSystem or OPCPackage, to have full control of the lifecycle (including closing the file when done): / /H S S F W o r k b o o k ,F i l e N P O I F S F i l e S y t e mf s=n e wN P O I F S F i l e S y s t e m ( n e wF i l e ( " f i l e . x l s " ) ) ; H S S F W o r k b o o kw b=n e wH S S F W o r k b o o k ( f s . g e t R o o t ( ) ) ; . . . . f s . c l o s e ( ) ; / /H S S F W o r k b o o k ,I n p u t S t r e a m ,n e e d sm o r em e m o r y N P O I F S F i l e S y t e mf s=n e wN P O I F S F i l e S y s t e m ( m y I n p u t S t r e a m ) ; H S S F W o r k b o o kw b=n e wH S S F W o r k b o o k ( f s . g e t R o o t ( ) ) ; / /X S S F W o r k b o o k ,F i l e O P C P a c k a g ep k g=O P C P a c k a g e . o p e n ( n e wF i l e ( " f i l e . x l s x " ) ) ; X S S F W o r k b o o kw b=n e wX S S F W o r k b o o k ( p k g ) ; . . . . p k g . c l o s e ( ) ; / /X S S F W o r k b o o k ,I n p u t S t r e a m ,n e e d sm o r em e m o r y O P C P a c k a g ep k g=O P C P a c k a g e . o p e n ( m y I n p u t S t r e a m ) ; X S S F W o r k b o o kw b=n e wX S S F W o r k b o o k ( p k g ) ; . . . . p k g . c l o s e ( ) ;

Demonstrates various alignment options


p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s ) t h r o w sE x c e p t i o n{ W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ;/ / o rn e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( ) ; R o wr o w=s h e e t . c r e a t e R o w ( ( s h o r t )2 ) ; r o w . s e t H e i g h t I n P o i n t s ( 3 0 ) ; c r e a t e C e l l ( w b ,r o w ,( s h o r t )0 ,C e l l S t y l e . A L I G N _ C E N T E R ,C e l l S t y l e . V E R T I C A L _ B O T T O M ) ; c r e a t e C e l l ( w b ,r o w ,( s h o r t )1 ,C e l l S t y l e . A L I G N _ C E N T E R _ S E L E C T I O N ,C e l l S t y l e . V E R T I C A L _ B O T T O M ) ; c r e a t e C e l l ( w b ,r o w ,( s h o r t )2 ,C e l l S t y l e . A L I G N _ F I L L ,C e l l S t y l e . V E R T I C A L _ C E N T E R ) ; c r e a t e C e l l ( w b ,r o w ,( s h o r t )3 ,C e l l S t y l e . A L I G N _ G E N E R A L ,C e l l S t y l e . V E R T I C A L _ C E N T E R ) ; c r e a t e C e l l ( w b ,r o w ,( s h o r t )4 ,C e l l S t y l e . A L I G N _ J U S T I F Y ,C e l l S t y l e . V E R T I C A L _ J U S T I F Y ) ; c r e a t e C e l l ( w b ,r o w ,( s h o r t )5 ,C e l l S t y l e . A L I G N _ L E F T ,C e l l S t y l e . V E R T I C A L _ T O P ) ; c r e a t e C e l l ( w b ,r o w ,( s h o r t )6 ,C e l l S t y l e . A L I G N _ R I G H T ,C e l l S t y l e . V E R T I C A L _ T O P ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " x s s f a l i g n . x l s x " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ; } / * * *C r e a t e sac e l la n da l i g n si tac e r t a i nw a y . *

poi.apache.org/spreadsheet/quick-guide.html#CellContents

3/23

3/25/13

* *@ p a r a mw b t h ew o r k b o o k *@ p a r a mr o w t h er o wt oc r e a t et h ec e l li n *@ p a r a mc o l u m nt h ec o l u m nn u m b e rt oc r e a t et h ec e l li n *@ p a r a mh a l i g nt h eh o r i z o n t a la l i g n m e n tf o rt h ec e l l . * / p r i v a t es t a t i cv o i dc r e a t e C e l l ( W o r k b o o kw b ,R o wr o w ,s h o r tc o l u m n ,s h o r th a l i g n ,s h o r tv a l i g n ){ C e l lc e l l=r o w . c r e a t e C e l l ( c o l u m n ) ; c e l l . s e t C e l l V a l u e ( " A l i g nI t " ) ; C e l l S t y l ec e l l S t y l e=w b . c r e a t e C e l l S t y l e ( ) ; c e l l S t y l e . s e t A l i g n m e n t ( h a l i g n ) ; c e l l S t y l e . s e t V e r t i c a l A l i g n m e n t ( v a l i g n ) ; c e l l . s e t C e l l S t y l e ( c e l l S t y l e ) ; }

Busy Developers' Guide to HSSF and XSSF Features

Working with borders


W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; / /C r e a t ear o wa n dp u ts o m ec e l l si ni t .R o w sa r e0b a s e d . R o wr o w=s h e e t . c r e a t e R o w ( 1 ) ; / /C r e a t eac e l la n dp u tav a l u ei ni t . C e l lc e l l=r o w . c r e a t e C e l l ( 1 ) ; c e l l . s e t C e l l V a l u e ( 4 ) ; / /S t y l et h ec e l lw i t hb o r d e r sa l la r o u n d . C e l l S t y l es t y l e=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e . s e t B o r d e r B o t t o m ( C e l l S t y l e . B O R D E R _ T H I N ) ; s t y l e . s e t B o t t o m B o r d e r C o l o r ( I n d e x e d C o l o r s . B L A C K . g e t I n d e x ( ) ) ; s t y l e . s e t B o r d e r L e f t ( C e l l S t y l e . B O R D E R _ T H I N ) ; s t y l e . s e t L e f t B o r d e r C o l o r ( I n d e x e d C o l o r s . G R E E N . g e t I n d e x ( ) ) ; s t y l e . s e t B o r d e r R i g h t ( C e l l S t y l e . B O R D E R _ T H I N ) ; s t y l e . s e t R i g h t B o r d e r C o l o r ( I n d e x e d C o l o r s . B L U E . g e t I n d e x ( ) ) ; s t y l e . s e t B o r d e r T o p ( C e l l S t y l e . B O R D E R _ M E D I U M _ D A S H E D ) ; s t y l e . s e t T o p B o r d e r C o l o r ( I n d e x e d C o l o r s . B L A C K . g e t I n d e x ( ) ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Iterate over rows and cells


Sometimes, you'd like to just iterate over all the rows in a sheet, or all the cells in a row. This is possible with a simple for loop. Luckily, this is very easy. Row defines a CellIterator inner class to handle iterating over the cells (get one with a call to row.cellIterator()), and Sheet provides a rowIterator() method to give an iterator over all the rows. These implement the java.lang.Iterable interface to allow foreach loops. S h e e ts h e e t=w b . g e t S h e e t A t ( 0 ) ; f o r( R o wr o w:s h e e t ){ f o r( C e l lc e l l:r o w ){ / /D os o m e t h i n gh e r e } }

Iterate over cells, with control of missing / blank cells


In some cases, when iterating, you need full control over how missing or blank cells are treated, and you need to ensure you visit every cell and not just those defined in the file. (The CellIterator will only return the cells defined in the file, which is largely those with values or stylings, but it depends on Excel). In cases such as these, you should fetch the first and last column information for a row, then call getCell(int, MissingCellPolicy) to fetch the cell. Use a MissingCellPolicy to control how blank or null cells are handled. / /D e c i d ew h i c hr o w st op r o c e s s i n tr o w S t a r t=M a t h . m i n ( 1 5 ,s h e e t . g e t F i r s t R o w N u m ( ) ) ; i n tr o w E n d=M a t h . m a x ( 1 4 0 0 ,s h e e t . g e t L a s t R o w N u m ( ) ) ; f o r( i n tr o w N u m=r o w S t a r t ;r o w N u m<r o w E n d ;r o w N u m + + ){ R o wr=s h e e t . g e t R o w ( r o w N u m ) ; i n tl a s t C o l u m n=M a t h . m a x ( r . g e t L a s t C e l l N u m ( ) ,M Y _ M I N I M U M _ C O L U M N _ C O U N T ) ; f o r( i n tc n=0 ;c n<l a s t C o l u m n ;c n + + ){ C e l lc=r . g e t C e l l ( c n ,R o w . R E T U R N _ B L A N K _ A S _ N U L L ) ; i f( c= =n u l l ){ / /T h es p r e a d s h e e ti se m p t yi nt h i sc e l l }e l s e{

poi.apache.org/spreadsheet/quick-guide.html#CellContents

4/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


}e l s e{ / /D os o m e t h i n gu s e f u lw i t ht h ec e l l ' sc o n t e n t s } } }

Getting the cell contents


To get the contents of a cell, you first need to know what kind of cell it is (asking a string cell for its numeric contents will get you a NumberFormatException for example). So, you will want to switch on the cell's type, and then call the appropriate getter for that cell. In the code below, we loop over every cell in one sheet, print out the cell's reference (eg A3), and then the cell's contents. / /i m p o r to r g . a p a c h e . p o i . s s . u s e r m o d e l . * ; S h e e ts h e e t 1=w b . g e t S h e e t A t ( 0 ) ; f o r( R o wr o w:s h e e t 1 ){ f o r( C e l lc e l l:r o w ){ C e l l R e f e r e n c ec e l l R e f=n e wC e l l R e f e r e n c e ( r o w . g e t R o w N u m ( ) ,c e l l . g e t C o l u m n I n d e x ( ) ) ; S y s t e m . o u t . p r i n t ( c e l l R e f . f o r m a t A s S t r i n g ( ) ) ; S y s t e m . o u t . p r i n t ( "-" ) ; s w i t c h( c e l l . g e t C e l l T y p e ( ) ){ c a s eC e l l . C E L L _ T Y P E _ S T R I N G : S y s t e m . o u t . p r i n t l n ( c e l l . g e t R i c h S t r i n g C e l l V a l u e ( ) . g e t S t r i n g ( ) ) ; b r e a k ; c a s eC e l l . C E L L _ T Y P E _ N U M E R I C : i f( D a t e U t i l . i s C e l l D a t e F o r m a t t e d ( c e l l ) ){ S y s t e m . o u t . p r i n t l n ( c e l l . g e t D a t e C e l l V a l u e ( ) ) ; }e l s e{ S y s t e m . o u t . p r i n t l n ( c e l l . g e t N u m e r i c C e l l V a l u e ( ) ) ; } b r e a k ; c a s eC e l l . C E L L _ T Y P E _ B O O L E A N : S y s t e m . o u t . p r i n t l n ( c e l l . g e t B o o l e a n C e l l V a l u e ( ) ) ; b r e a k ; c a s eC e l l . C E L L _ T Y P E _ F O R M U L A : S y s t e m . o u t . p r i n t l n ( c e l l . g e t C e l l F o r m u l a ( ) ) ; b r e a k ; d e f a u l t : S y s t e m . o u t . p r i n t l n ( ) ; } } }

Text Extraction
For most text extraction requirements, the standard ExcelExtractor class should provide all you need. I n p u t S t r e a mi n p=n e wF i l e I n p u t S t r e a m ( " w o r k b o o k . x l s " ) ; H S S F W o r k b o o kw b=n e wH S S F W o r k b o o k ( n e wP O I F S F i l e S y s t e m ( i n p ) ) ; E x c e l E x t r a c t o re x t r a c t o r=n e wE x c e l E x t r a c t o r ( w b ) ; e x t r a c t o r . s e t F o r m u l a s N o t R e s u l t s ( t r u e ) ; e x t r a c t o r . s e t I n c l u d e S h e e t N a m e s ( f a l s e ) ; S t r i n gt e x t=e x t r a c t o r . g e t T e x t ( ) ; For very fancy text extraction, XLS to CSV etc, take a look at /src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java

Fills and colors


W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; / /C r e a t ear o wa n dp u ts o m ec e l l si ni t .R o w sa r e0b a s e d . R o wr o w=s h e e t . c r e a t e R o w ( ( s h o r t )1 ) ; / /A q u ab a c k g r o u n d C e l l S t y l es t y l e=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e . s e t F i l l B a c k g r o u n d C o l o r ( I n d e x e d C o l o r s . A Q U A . g e t I n d e x ( ) ) ; s t y l e . s e t F i l l P a t t e r n ( C e l l S t y l e . B I G _ S P O T S ) ; C e l lc e l l=r o w . c r e a t e C e l l ( ( s h o r t )1 ) ; c e l l . s e t C e l l V a l u e ( " X " ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; / /O r a n g e" f o r e g r o u n d " ,f o r e g r o u n db e i n gt h ef i l lf o r e g r o u n dn o tt h ef o n tc o l o r . s t y l e=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e . s e t F i l l F o r e g r o u n d C o l o r ( I n d e x e d C o l o r s . O R A N G E . g e t I n d e x ( ) ) ; s t y l e . s e t F i l l P a t t e r n ( C e l l S t y l e . S O L I D _ F O R E G R O U N D ) ;

poi.apache.org/spreadsheet/quick-guide.html#CellContents

5/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


s t y l e . s e t F i l l P a t t e r n ( C e l l S t y l e . S O L I D _ F O R E G R O U N D ) ; c e l l=r o w . c r e a t e C e l l ( ( s h o r t )2 ) ; c e l l . s e t C e l l V a l u e ( " X " ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Merging cells
W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; R o wr o w=s h e e t . c r e a t e R o w ( ( s h o r t )1 ) ; C e l lc e l l=r o w . c r e a t e C e l l ( ( s h o r t )1 ) ; c e l l . s e t C e l l V a l u e ( " T h i si sat e s to fm e r g i n g " ) ; s h e e t . a d d M e r g e d R e g i o n ( n e wC e l l R a n g e A d d r e s s ( 1 ,/ / f i r s tr o w( 0 b a s e d ) 1 ,/ / l a s tr o w ( 0 b a s e d ) 1 ,/ / f i r s tc o l u m n( 0 b a s e d ) 2 / / l a s tc o l u m n ( 0 b a s e d ) ) ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Working with fonts


W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; / /C r e a t ear o wa n dp u ts o m ec e l l si ni t .R o w sa r e0b a s e d . R o wr o w=s h e e t . c r e a t e R o w ( 1 ) ; / /C r e a t ean e wf o n ta n da l t e ri t . F o n tf o n t=w b . c r e a t e F o n t ( ) ; f o n t . s e t F o n t H e i g h t I n P o i n t s ( ( s h o r t ) 2 4 ) ; f o n t . s e t F o n t N a m e ( " C o u r i e rN e w " ) ; f o n t . s e t I t a l i c ( t r u e ) ; f o n t . s e t S t r i k e o u t ( t r u e ) ; / /F o n t sa r es e ti n t oas t y l es oc r e a t ean e wo n et ou s e . C e l l S t y l es t y l e=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e . s e t F o n t ( f o n t ) ; / /C r e a t eac e l la n dp u tav a l u ei ni t . C e l lc e l l=r o w . c r e a t e C e l l ( 1 ) ; c e l l . s e t C e l l V a l u e ( " T h i si sat e s to ff o n t s " ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ; Note, the maximum number of unique fonts in a workbook is limited to 32767 ( the maximum positive short). You should re-use fonts in your apllications instead of creating a font for each cell. Examples: Wrong: f o r( i n ti=0 ;i<1 0 0 0 0 ;i + + ){ R o wr o w=s h e e t . c r e a t e R o w ( i ) ; C e l lc e l l=r o w . c r e a t e C e l l ( ( s h o r t )0 ) ; C e l l S t y l es t y l e=w o r k b o o k . c r e a t e C e l l S t y l e ( ) ; F o n tf o n t=w o r k b o o k . c r e a t e F o n t ( ) ; f o n t . s e t B o l d w e i g h t ( F o n t . B O L D W E I G H T _ B O L D ) ; s t y l e . s e t F o n t ( f o n t ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; } Correct: C e l l S t y l es t y l e=w o r k b o o k . c r e a t e C e l l S t y l e ( ) ; F o n tf o n t=w o r k b o o k . c r e a t e F o n t ( ) ;

poi.apache.org/spreadsheet/quick-guide.html#CellContents

6/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


F o n tf o n t=w o r k b o o k . c r e a t e F o n t ( ) ; f o n t . s e t B o l d w e i g h t ( F o n t . B O L D W E I G H T _ B O L D ) ; s t y l e . s e t F o n t ( f o n t ) ; f o r( i n ti=0 ;i<1 0 0 0 0 ;i + + ){ R o wr o w=s h e e t . c r e a t e R o w ( i ) ; C e l lc e l l=r o w . c r e a t e C e l l ( ( s h o r t )0 ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; }

Custom colors
HSSF: H S S F W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; H S S F S h e e ts h e e t=w b . c r e a t e S h e e t ( ) ; H S S F R o wr o w=s h e e t . c r e a t e R o w ( ( s h o r t )0 ) ; H S S F C e l lc e l l=r o w . c r e a t e C e l l ( ( s h o r t )0 ) ; c e l l . s e t C e l l V a l u e ( " D e f a u l tP a l e t t e " ) ; / / a p p l ys o m ec o l o r sf r o mt h es t a n d a r dp a l e t t e , / /a si nt h ep r e v i o u se x a m p l e s . / / w e ' l lu s er e dt e x to nal i m eb a c k g r o u n d H S S F C e l l S t y l es t y l e=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e . s e t F i l l F o r e g r o u n d C o l o r ( H S S F C o l o r . L I M E . i n d e x ) ; s t y l e . s e t F i l l P a t t e r n ( H S S F C e l l S t y l e . S O L I D _ F O R E G R O U N D ) ; H S S F F o n tf o n t=w b . c r e a t e F o n t ( ) ; f o n t . s e t C o l o r ( H S S F C o l o r . R E D . i n d e x ) ; s t y l e . s e t F o n t ( f o n t ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; / / s a v ew i t ht h ed e f a u l tp a l e t t e F i l e O u t p u t S t r e a mo u t=n e wF i l e O u t p u t S t r e a m ( " d e f a u l t _ p a l e t t e . x l s " ) ; w b . w r i t e ( o u t ) ; o u t . c l o s e ( ) ; / / n o w ,l e t ' sr e p l a c eR E Da n dL I M Ei nt h ep a l e t t e / /w i t ham o r ea t t r a c t i v ec o m b i n a t i o n / /( l o v i n g l yb o r r o w e df r o mf r e e b s d . o r g ) c e l l . s e t C e l l V a l u e ( " M o d i f i e dP a l e t t e " ) ; / / c r e a t i n gac u s t o mp a l e t t ef o rt h ew o r k b o o k H S S F P a l e t t ep a l e t t e=w b . g e t C u s t o m P a l e t t e ( ) ; / / r e p l a c i n gt h es t a n d a r dr e dw i t hf r e e b s d . o r gr e d p a l e t t e . s e t C o l o r A t I n d e x ( H S S F C o l o r . R E D . i n d e x , ( b y t e )1 5 3 , / / R G Br e d( 0 2 5 5 ) ( b y t e )0 , / / R G Bg r e e n ( b y t e )0 / / R G Bb l u e ) ; / / r e p l a c i n gl i m ew i t hf r e e b s d . o r gg o l d p a l e t t e . s e t C o l o r A t I n d e x ( H S S F C o l o r . L I M E . i n d e x ,( b y t e )2 5 5 ,( b y t e )2 0 4 ,( b y t e )1 0 2 ) ; / / s a v ew i t ht h em o d i f i e dp a l e t t e / /n o t et h a tw h e r e v e rw eh a v ep r e v i o u s l yu s e dR E Do rL I M E ,t h e / /n e wc o l o r sm a g i c a l l ya p p e a r o u t=n e wF i l e O u t p u t S t r e a m ( " m o d i f i e d _ p a l e t t e . x l s " ) ; w b . w r i t e ( o u t ) ; o u t . c l o s e ( ) ; XSSF: X S S F W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ; X S S F S h e e ts h e e t=w b . c r e a t e S h e e t ( ) ; X S S F R o wr o w=s h e e t . c r e a t e R o w ( 0 ) ; X S S F C e l lc e l l=r o w . c r e a t e C e l l (0 ) ; c e l l . s e t C e l l V a l u e ( " c u s t o mX S S Fc o l o r s " ) ; X S S F C e l l S t y l es t y l e 1=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e 1 . s e t F i l l F o r e g r o u n d C o l o r ( n e wX S S F C o l o r ( n e wj a v a . a w t . C o l o r ( 1 2 8 ,0 ,1 2 8 ) ) ) ; s t y l e 1 . s e t F i l l P a t t e r n ( C e l l S t y l e . S O L I D _ F O R E G R O U N D ) ;

Reading and Rewriting Workbooks


I n p u t S t r e a mi n p=n e wF i l e I n p u t S t r e a m ( " w o r k b o o k . x l s " ) ; / / I n p u t S t r e a mi n p=n e wF i l e I n p u t S t r e a m ( " w o r k b o o k . x l s x " ) ;

poi.apache.org/spreadsheet/quick-guide.html#CellContents

7/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


W o r k b o o kw b=W o r k b o o k F a c t o r y . c r e a t e ( i n p ) ; S h e e ts h e e t=w b . g e t S h e e t A t ( 0 ) ; R o wr o w=s h e e t . g e t R o w ( 2 ) ; C e l lc e l l=r o w . g e t C e l l ( 3 ) ; i f( c e l l= =n u l l ) c e l l=r o w . c r e a t e C e l l ( 3 ) ; c e l l . s e t C e l l T y p e ( C e l l . C E L L _ T Y P E _ S T R I N G ) ; c e l l . s e t C e l l V a l u e ( " at e s t " ) ; / /W r i t et h eo u t p u tt oaf i l e F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Using newlines in cells


W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( ) ; / / o rn e wH S S F W o r k b o o k ( ) ;

R o wr o w=s h e e t . c r e a t e R o w ( 2 ) ; C e l lc e l l=r o w . c r e a t e C e l l ( 2 ) ; c e l l . s e t C e l l V a l u e ( " U s e\ nw i t hw o r dw r a po nt oc r e a t ean e wl i n e " ) ; / / t oe n a b l en e w l i n e sy o un e e ds e tac e l ls t y l e sw i t hw r a p = t r u e C e l l S t y l ec s=w b . c r e a t e C e l l S t y l e ( ) ; c s . s e t W r a p T e x t ( t r u e ) ; c e l l . s e t C e l l S t y l e ( c s ) ; / / i n c r e a s er o wh e i g h tt oa c c o m o d a t et w ol i n e so ft e x t r o w . s e t H e i g h t I n P o i n t s ( ( 2 * s h e e t . g e t D e f a u l t R o w H e i g h t I n P o i n t s ( ) ) ) ; / / a d j u s tc o l u m nw i d t ht of i tt h ec o n t e n t s h e e t . a u t o S i z e C o l u m n ( ( s h o r t ) 2 ) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " o o x m l n e w l i n e s . x l s x " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Data Formats
W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " f o r m a ts h e e t " ) ; C e l l S t y l es t y l e ; D a t a F o r m a tf o r m a t=w b . c r e a t e D a t a F o r m a t ( ) ; R o wr o w ; C e l lc e l l ; s h o r tr o w N u m=0 ; s h o r tc o l N u m=0 ; r o w=s h e e t . c r e a t e R o w ( r o w N u m + + ) ; c e l l=r o w . c r e a t e C e l l ( c o l N u m ) ; c e l l . s e t C e l l V a l u e ( 1 1 1 1 1 . 2 5 ) ; s t y l e=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e . s e t D a t a F o r m a t ( f o r m a t . g e t F o r m a t ( " 0 . 0 " ) ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; r o w=s h e e t . c r e a t e R o w ( r o w N u m + + ) ; c e l l=r o w . c r e a t e C e l l ( c o l N u m ) ; c e l l . s e t C e l l V a l u e ( 1 1 1 1 1 . 2 5 ) ; s t y l e=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e . s e t D a t a F o r m a t ( f o r m a t . g e t F o r m a t ( " # , # # 0 . 0 0 0 0 " ) ) ; c e l l . s e t C e l l S t y l e ( s t y l e ) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Fit Sheet to One Page


W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " f o r m a ts h e e t " ) ; P r i n t S e t u pp s=s h e e t . g e t P r i n t S e t u p ( ) ; s h e e t . s e t A u t o b r e a k s ( t r u e ) ; p s . s e t F i t H e i g h t ( ( s h o r t ) 1 ) ; p s . s e t F i t W i d t h ( ( s h o r t ) 1 ) ;

poi.apache.org/spreadsheet/quick-guide.html#CellContents

8/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


/ /C r e a t ev a r i o u sc e l l sa n dr o w sf o rs p r e a d s h e e t . F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Set Print Area


W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " S h e e t 1 " ) ; / / s e t st h ep r i n ta r e af o rt h ef i r s ts h e e t w b . s e t P r i n t A r e a ( 0 ," $ A $ 1 : $ C $ 2 " ) ; / / A l t e r n a t i v e l y : w b . s e t P r i n t A r e a ( 0 ,/ / s h e e ti n d e x 0 ,/ / s t a r tc o l u m n 1 ,/ / e n dc o l u m n 0 ,/ / s t a r tr o w 0 / / e n dr o w ) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Set Page Numbers on Footer


W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ;/ /o rn e wX S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " f o r m a ts h e e t " ) ; F o o t e rf o o t e r=s h e e t . g e t F o o t e r ( ) ; f o o t e r . s e t R i g h t (" P a g e"+H e a d e r F o o t e r . p a g e ( )+"o f"+H e a d e r F o o t e r . n u m P a g e s ( )) ;

/ /C r e a t ev a r i o u sc e l l sa n dr o w sf o rs p r e a d s h e e t . F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Using the Convenience Functions


The convenience functions provide utility features such as setting borders around merged regions and changing style attributes without explicitly creating new styles. W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; / /o rn e wX S S F W o r k b o o k ( ) S h e e ts h e e t 1=w b . c r e a t e S h e e t (" n e ws h e e t ") ; / /C r e a t eam e r g e dr e g i o n R o wr o w=s h e e t 1 . c r e a t e R o w (1) ; R o wr o w 2=s h e e t 1 . c r e a t e R o w (2) ; C e l lc e l l=r o w . c r e a t e C e l l (1) ; c e l l . s e t C e l l V a l u e (" T h i si sat e s to fm e r g i n g ") ; C e l l R a n g e A d d r e s sr e g i o n=C e l l R a n g e A d d r e s s . v a l u e O f ( " B 2 : E 5 " ) ; s h e e t 1 . a d d M e r g e d R e g i o n (r e g i o n) ; / /S e tt h eb o r d e ra n db o r d e rc o l o r s . f i n a ls h o r tb o r d e r M e d i u m D a s h e d=C e l l S t y l e . B O R D E R _ M E D I U M _ D A S H E D ; R e g i o n U t i l . s e t B o r d e r B o t t o m (b o r d e r M e d i u m D a s h e d , r e g i o n ,s h e e t 1 ,w b) ; R e g i o n U t i l . s e t B o r d e r T o p (b o r d e r M e d i u m D a s h e d , r e g i o n ,s h e e t 1 ,w b) ; R e g i o n U t i l . s e t B o r d e r L e f t (b o r d e r M e d i u m D a s h e d , r e g i o n ,s h e e t 1 ,w b) ; R e g i o n U t i l . s e t B o r d e r R i g h t (b o r d e r M e d i u m D a s h e d , r e g i o n ,s h e e t 1 ,w b) ; R e g i o n U t i l . s e t B o t t o m B o r d e r C o l o r ( I n d e x e d C o l o r s . A Q U A . g e t I n d e x ( ) ,r e g i o n ,s h e e t 1 ,w b ) ; R e g i o n U t i l . s e t T o p B o r d e r C o l o r ( I n d e x e d C o l o r s . A Q U A . g e t I n d e x ( ) ,r e g i o n ,s h e e t 1 ,w b ) ; R e g i o n U t i l . s e t L e f t B o r d e r C o l o r ( I n d e x e d C o l o r s . A Q U A . g e t I n d e x ( ) ,r e g i o n ,s h e e t 1 ,w b ) ; R e g i o n U t i l . s e t R i g h t B o r d e r C o l o r ( I n d e x e d C o l o r s . A Q U A . g e t I n d e x ( ) ,r e g i o n ,s h e e t 1 ,w b ) ; / /S h o w ss o m eu s a g e so fH S S F C e l l U t i l C e l l S t y l es t y l e=w b . c r e a t e C e l l S t y l e ( ) ; s t y l e . s e t I n d e n t i o n ( ( s h o r t ) 4 ) ; C e l l U t i l . c r e a t e C e l l ( r o w ,8 ," T h i si st h ev a l u eo ft h ec e l l " ,s t y l e ) ; C e l lc e l l 2=C e l l U t i l . c r e a t e C e l l (r o w 2 ,8 ," T h i si st h ev a l u eo ft h ec e l l " ) ; C e l l U t i l . s e t A l i g n m e n t ( c e l l 2 ,w b ,C e l l S t y l e . A L I G N _ C E N T E R ) ;

poi.apache.org/spreadsheet/quick-guide.html#CellContents

9/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


C e l l U t i l . s e t A l i g n m e n t ( c e l l 2 ,w b ,C e l l S t y l e . A L I G N _ C E N T E R ) ; / /W r i t eo u tt h ew o r k b o o k F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m (" w o r k b o o k . x l s ") ; w b . w r i t e (f i l e O u t) ; f i l e O u t . c l o s e ( ) ;

Shift rows up or down on a sheet


W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " r o ws h e e t " ) ; / /C r e a t ev a r i o u sc e l l sa n dr o w sf o rs p r e a d s h e e t . / /S h i f tr o w s6-1 1o nt h es p r e a d s h e e tt ot h et o p( r o w s0-5 ) s h e e t . s h i f t R o w s ( 5 ,1 0 ,5 ) ;

Set a sheet as selected


W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " r o ws h e e t " ) ; s h e e t . s e t S e l e c t e d ( t r u e ) ;

Set the zoom magnification


The zoom is expressed as a fraction. For example to express a zoom of 75% use 3 for the numerator and 4 for the denominator. W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t 1=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; s h e e t 1 . s e t Z o o m ( 3 , 4 ) ; / /7 5p e r c e n tm a g n i f i c a t i o n

Splits and freeze panes


There are two types of panes you can create; freeze panes and split panes. A freeze pane is split by columns and rows. You create a freeze pane using the following mechanism: sheet1.createFreezePane( 3, 2, 3, 2 ); The first two parameters are the columns and rows you wish to split by. The second two parameters indicate the cells that are visible in the bottom right quadrant. Split pains appear differently. The split area is divided into four separate work area's. The split occurs at the pixel level and the user is able to adjust the split by dragging it to a new position. Split panes are created with the following call: sheet2.createSplitPane( 2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT ); The first parameter is the x position of the split. This is in 1/20th of a point. A point in this case seems to equate to a pixel. The second parameter is the y position of the split. Again in 1/20th of a point. The last parameter indicates which pane currently has the focus. This will be one of Sheet.PANE_LOWER_LEFT, PANE_LOWER_RIGHT, PANE_UPPER_RIGHT or PANE_UPPER_LEFT. W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t 1=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; S h e e ts h e e t 2=w b . c r e a t e S h e e t ( " s e c o n ds h e e t " ) ; S h e e ts h e e t 3=w b . c r e a t e S h e e t ( " t h i r ds h e e t " ) ; S h e e ts h e e t 4=w b . c r e a t e S h e e t ( " f o u r t hs h e e t " ) ; / /F r e e z ej u s to n er o w s h e e t 1 . c r e a t e F r e e z e P a n e (0 ,1 ,0 ,1) ; / /F r e e z ej u s to n ec o l u m n s h e e t 2 . c r e a t e F r e e z e P a n e (1 ,0 ,1 ,0) ; / /F r e e z et h ec o l u m n sa n dr o w s( f o r g e ta b o u ts c r o l l i n gp o s i t i o no ft h el o w e rr i g h tq u a d r a n t ) . s h e e t 3 . c r e a t e F r e e z e P a n e (2 ,2) ; / /C r e a t eas p l i tw i t ht h el o w e rl e f ts i d eb e i n gt h ea c t i v eq u a d r a n t s h e e t 4 . c r e a t e S p l i t P a n e (2 0 0 0 ,2 0 0 0 ,0 ,0 ,S h e e t . P A N E _ L O W E R _ L E F T) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Repeating rows and columns


It's possible to set up repeating rows and columns in your printouts by using the setRepeatingRows() and setRepeatingColumns() methods in the Sheet class.

poi.apache.org/spreadsheet/quick-guide.html#CellContents

10/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features

These methods expect a CellRangeAddress parameter which specifies the range for the rows or columns to repeat. For setRepeatingRows(), it should specify a range of rows to repeat, with the column part spanning all columns. For setRepeatingColums(), it should specify a range of columns to repeat, with the row part spanning all rows. If the parameter is null, the repeating rows or columns will be removed. W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t 1=w b . c r e a t e S h e e t ( " S h e e t 1 " ) ; S h e e ts h e e t 2=w b . c r e a t e S h e e t ( " S h e e t 2 " ) ; / /o rn e wX S S F W o r k b o o k ( ) ;

/ /S e tt h er o w st or e p e a tf r o mr o w4t o5o nt h ef i r s ts h e e t . s h e e t 1 . s e t R e p e a t i n g R o w s ( C e l l R a n g e A d d r e s s . v a l u e O f ( " 4 : 5 " ) ) ; / /S e tt h ec o l u m n st or e p e a tf r o mc o l u m nAt oCo nt h es e c o n ds h e e t s h e e t 2 . s e t R e p e a t i n g C o l u m n s ( C e l l R a n g e A d d r e s s . v a l u e O f ( " A : C " ) ) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Headers and Footers


Example is for headers but applies directly to footers. W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; H e a d e rh e a d e r=s h e e t . g e t H e a d e r ( ) ; h e a d e r . s e t C e n t e r ( " C e n t e rH e a d e r " ) ; h e a d e r . s e t L e f t ( " L e f tH e a d e r " ) ; h e a d e r . s e t R i g h t ( H S S F H e a d e r . f o n t ( " S t e n c i l N o r m a l " ," I t a l i c " )+ H S S F H e a d e r . f o n t S i z e ( ( s h o r t )1 6 )+" R i g h tw /S t e n c i l N o r m a lI t a l i cf o n ta n ds i z e1 6 " ) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( " w o r k b o o k . x l s " ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Drawing Shapes
POI supports drawing shapes using the Microsoft Office drawing tools. Shapes on a sheet are organized in a hiearchy of groups and and shapes. The top-most shape is the patriarch. This is not visisble on the sheet at all. To start drawing you need to call c r e a t e P a t r i a r c hon the H S S F S h e e tclass. This has the effect erasing any other shape information stored in that sheet. By default POI will leave shape records alone in the sheet unless you make a call to this method. To create a shape you have to go through the following steps: 1. 2. 3. 4. 5. Create the patriarch. Create an anchor to position the shape on the sheet. Ask the patriarch to create the shape. Set the shape type (line, oval, rectangle etc...) Set any other style details converning the shape. (eg: line thickness, etc...) H S S F P a t r i a r c hp a t r i a r c h=s h e e t . c r e a t e D r a w i n g P a t r i a r c h ( ) ; a=n e wH S S F C l i e n t A n c h o r (0 ,0 ,1 0 2 3 ,2 5 5 ,( s h o r t )1 ,0 ,( s h o r t )1 ,0) ; H S S F S i m p l e S h a p es h a p e 1=p a t r i a r c h . c r e a t e S i m p l e S h a p e ( a 1 ) ; s h a p e 1 . s e t S h a p e T y p e ( H S S F S i m p l e S h a p e . O B J E C T _ T Y P E _ L I N E ) ; Text boxes are created using a different call: H S S F T e x t b o xt e x t b o x 1=p a t r i a r c h . c r e a t e T e x t b o x ( n e wH S S F C l i e n t A n c h o r ( 0 , 0 , 0 , 0 , ( s h o r t ) 1 , 1 , ( s h o r t ) 2 , 2 ) ) ; t e x t b o x 1 . s e t S t r i n g ( n e wH S S F R i c h T e x t S t r i n g ( " T h i si sat e s t " )) ; It's possible to use different fonts to style parts of the text in the textbox. Here's how: H S S F F o n tf o n t=w b . c r e a t e F o n t ( ) ; f o n t . s e t I t a l i c ( t r u e ) ; f o n t . s e t U n d e r l i n e ( H S S F F o n t . U _ D O U B L E ) ; H S S F R i c h T e x t S t r i n gs t r i n g=n e wH S S F R i c h T e x t S t r i n g ( " W o o ! ! ! " ) ; s t r i n g . a p p l y F o n t ( 2 , 5 , f o n t ) ; t e x t b o x . s e t S t r i n g ( s t r i n g) ; Just as can be done manually using Excel, it is possible to group shapes together. This is done by calling c r e a t e G r o u p ( )and then creating the shapes using those groups. It's also possible to create groups within groups. Warning
Any group you create should contain at least two other shapes or subgroups.

Here's how to create a shape group:

poi.apache.org/spreadsheet/quick-guide.html#CellContents

11/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


/ /C r e a t eas h a p eg r o u p . H S S F S h a p e G r o u pg r o u p=p a t r i a r c h . c r e a t e G r o u p ( n e wH S S F C l i e n t A n c h o r ( 0 , 0 , 9 0 0 , 2 0 0 , ( s h o r t ) 2 , 2 , ( s h o r t ) 2 , 2 ) ) ; / /C r e a t eac o u p l eo fl i n e si nt h eg r o u p . H S S F S i m p l e S h a p es h a p e 1=g r o u p . c r e a t e S h a p e ( n e wH S S F C h i l d A n c h o r ( 3 , 3 , 5 0 0 , 5 0 0 ) ) ; s h a p e 1 . s e t S h a p e T y p e ( H S S F S i m p l e S h a p e . O B J E C T _ T Y P E _ L I N E ) ; (( H S S F C h i l d A n c h o r )s h a p e 1 . g e t A n c h o r ( )) . s e t A n c h o r ( ( s h o r t ) 3 , 3 , 5 0 0 , 5 0 0 ) ; H S S F S i m p l e S h a p es h a p e 2=g r o u p . c r e a t e S h a p e ( n e wH S S F C h i l d A n c h o r ( ( s h o r t ) 1 , 2 0 0 , 4 0 0 , 6 0 0 ) ) ; s h a p e 2 . s e t S h a p e T y p e ( H S S F S i m p l e S h a p e . O B J E C T _ T Y P E _ L I N E ) ;

If you're being observant you'll noticed that the shapes that are added to the group use a new type of anchor: the H S S F C h i l d A n c h o r . What happens is that the created group has it's own coordinate space for shapes that are placed into it. POI defaults this to (0,0,1023,255) but you are able to change it as desired. Here's how: m y G r o u p . s e t C o o r d i n a t e s ( 1 0 , 1 0 , 2 0 , 2 0 ) ;/ /t o p l e f t ,b o t t o m r i g h t If you create a group within a group it's also going to have it's own coordinate space.

Styling Shapes
By default shapes can look a little plain. It's possible to apply different styles to the shapes however. The sorts of things that can currently be done are: Change the fill color. Make a shape with no fill color. Change the thickness of the lines. Change the style of the lines. Eg: dashed, dotted. Change the line color. Here's an examples of how this is done: H S S F S i m p l e S h a p es=p a t r i a r c h . c r e a t e S i m p l e S h a p e ( a ) ; s . s e t S h a p e T y p e ( H S S F S i m p l e S h a p e . O B J E C T _ T Y P E _ O V A L ) ; s . s e t L i n e S t y l e C o l o r ( 1 0 , 1 0 , 1 0 ) ; s . s e t F i l l C o l o r ( 9 0 , 1 0 , 2 0 0 ) ; s . s e t L i n e W i d t h ( H S S F S h a p e . L I N E W I D T H _ O N E _ P T*3 ) ; s . s e t L i n e S t y l e ( H S S F S h a p e . L I N E S T Y L E _ D O T S Y S ) ;

Shapes and Graphics2d


While the native POI shape drawing commands are the recommended way to draw shapes in a shape it's sometimes desirable to use a standard API for compatibility with external libraries. With this in mind we created some wrappers for G r a p h i c sand G r a p h i c s 2 d . Warning
It's important to not however before continuing that G r a p h i c s 2 dis a poor match to the capabilities of the Microsoft Office drawing commands. The older G r a p h i c sclass offers a closer match but is still a square peg in a round hole.

All Graphics commands are issued into an H S S F S h a p e G r o u p . Here's how it's done: a=n e wH S S F C l i e n t A n c h o r (0 ,0 ,1 0 2 3 ,2 5 5 ,( s h o r t )1 ,0 ,( s h o r t )1 ,0) ; g r o u p=p a t r i a r c h . c r e a t e G r o u p (a) ; g r o u p . s e t C o o r d i n a t e s (0 ,0 ,8 0*4,1 2*2 3 ) ; f l o a tv e r t i c a l P o i n t s P e r P i x e l=a . g e t A n c h o r H e i g h t I n P o i n t s ( s h e e t )/( f l o a t ) M a t h . a b s ( g r o u p . g e t Y 2 ( )-g r o u p . g e t Y 1 ( ) ) ; g=n e wE s c h e r G r a p h i c s (g r o u p ,w b ,C o l o r . b l a c k ,v e r t i c a l P o i n t s P e r P i x e l) ; g 2 d=n e wE s c h e r G r a p h i c s 2 d (g) ; d r a w C h e m i c a l S t r u c t u r e (g 2 d) ; The first thing we do is create the group and set it's coordinates to match what we plan to draw. Next we calculate a reasonable fontSizeMultipler then create the EscherGraphics object. Since what we really want is a G r a p h i c s 2 dobject we create an EscherGraphics2d object and pass in the graphics object we created. Finally we call a routine that draws into the EscherGraphics2d object. The vertical points per pixel deserves some more explanation. One of the difficulties in converting Graphics calls into escher drawing calls is that Excel does not have the concept of absolute pixel positions. It measures it's cell widths in 'characters' and the cell heights in points. Unfortunately it's not defined exactly what type of character it's measuring. Presumably this is due to the fact that the Excel will be using different fonts on different platforms or even within the same platform. Because of this constraint we've had to implement the concept of a verticalPointsPerPixel. This the amount the font should be scaled by when you issue commands such as drawString(). To calculate this value use the follow formula: m u l t i p l e r=g r o u p H e i g h t I n P o i n t s/h e i g h t O f G r o u p The height of the group is calculated fairly simply by calculating the difference between the y coordinates of the bounding box of the shape. The height of the group can be calculated by using a convenience called H S S F C l i e n t A n c h o r . g e t A n c h o r H e i g h t I n P o i n t s ( ) . Many of the functions supported by the graphics classes are not complete. Here's some of the functions that are known to work. fillRect() fillOval() drawString() drawOval()

poi.apache.org/spreadsheet/quick-guide.html#CellContents

12/23

3/25/13

drawOval() drawLine() clearRect()

Busy Developers' Guide to HSSF and XSSF Features

Functions that are not supported will return and log a message using the POI logging infrastructure (disabled by default).

Outlining
Outlines are great for grouping sections of information together and can be added easily to columns and rows using the POI API. Here's how: W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t 1=w b . c r e a t e S h e e t ( " n e ws h e e t " ) ; s h e e t 1 . g r o u p R o w (5 ,1 4) ; s h e e t 1 . g r o u p R o w (7 ,1 4) ; s h e e t 1 . g r o u p R o w (1 6 ,1 9) ; s h e e t 1 . g r o u p C o l u m n (( s h o r t ) 4 ,( s h o r t ) 7) ; s h e e t 1 . g r o u p C o l u m n (( s h o r t ) 9 ,( s h o r t ) 1 2) ; s h e e t 1 . g r o u p C o l u m n (( s h o r t ) 1 0 ,( s h o r t ) 1 1) ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( f i l e n a m e ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ; To collapse (or expand) an outline use the following calls: s h e e t 1 . s e t R o w G r o u p C o l l a p s e d (7 ,t r u e) ; s h e e t 1 . s e t C o l u m n G r o u p C o l l a p s e d (( s h o r t ) 4 ,t r u e) ; The row/column you choose should contain an already created group. It can be anywhere within the group. Images Images are part of the drawing support. To add an image just call c r e a t e P i c t u r e ( )on the drawing patriarch. At the time of writing the following types are supported: PNG JPG DIB It should be noted that any existing drawings may be erased once you add a image to a sheet. / / c r e a t ean e ww o r k b o o k W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ;/ / o rn e wH S S F W o r k b o o k ( ) ; / / a d dp i c t u r ed a t at ot h i sw o r k b o o k . I n p u t S t r e a mi s=n e wF i l e I n p u t S t r e a m ( " i m a g e 1 . j p e g " ) ; b y t e [ ]b y t e s=I O U t i l s . t o B y t e A r r a y ( i s ) ; i n tp i c t u r e I d x=w b . a d d P i c t u r e ( b y t e s ,W o r k b o o k . P I C T U R E _ T Y P E _ J P E G ) ; i s . c l o s e ( ) ; C r e a t i o n H e l p e rh e l p e r=w b . g e t C r e a t i o n H e l p e r ( ) ; / / c r e a t es h e e t S h e e ts h e e t=w b . c r e a t e S h e e t ( ) ; / /C r e a t et h ed r a w i n gp a t r i a r c h . T h i si st h et o pl e v e lc o n t a i n e rf o ra l ls h a p e s . D r a w i n gd r a w i n g=s h e e t . c r e a t e D r a w i n g P a t r i a r c h ( ) ; / / a d dap i c t u r es h a p e C l i e n t A n c h o ra n c h o r=h e l p e r . c r e a t e C l i e n t A n c h o r ( ) ; / / s e tt o p l e f tc o r n e ro ft h ep i c t u r e , / / s u b s e q u e n tc a l lo fP i c t u r e # r e s i z e ( )w i l lo p e r a t er e l a t i v et oi t a n c h o r . s e t C o l 1 ( 3 ) ; a n c h o r . s e t R o w 1 ( 2 ) ; P i c t u r ep i c t=d r a w i n g . c r e a t e P i c t u r e ( a n c h o r ,p i c t u r e I d x ) ; / / a u t o s i z ep i c t u r er e l a t i v et oi t st o p l e f tc o r n e r p i c t . r e s i z e ( ) ; / / s a v ew o r k b o o k S t r i n gf i l e=" p i c t u r e . x l s " ; i f ( w bi n s t a n c e o fX S S F W o r k b o o k )f i l e+ =" x " ; F i l e O u t p u t S t r e a mf i l e O u t=n e wF i l e O u t p u t S t r e a m ( f i l e ) ; w b . w r i t e ( f i l e O u t ) ; f i l e O u t . c l o s e ( ) ;

Warning
Picture.resize() works only for JPEG and PNG. Other formats are not yet supported.

poi.apache.org/spreadsheet/quick-guide.html#CellContents

13/23

3/25/13
Reading images from a workbook:

Busy Developers' Guide to HSSF and XSSF Features

L i s tl s t=w o r k b o o k . g e t A l l P i c t u r e s ( ) ; f o r( I t e r a t o ri t=l s t . i t e r a t o r ( ) ;i t . h a s N e x t ( ) ;){ P i c t u r e D a t ap i c t=( P i c t u r e D a t a ) i t . n e x t ( ) ; S t r i n ge x t=p i c t . s u g g e s t F i l e E x t e n s i o n ( ) ; b y t e [ ]d a t a=p i c t . g e t D a t a ( ) ; i f( e x t . e q u a l s ( " j p e g " ) ) { F i l e O u t p u t S t r e a mo u t=n e wF i l e O u t p u t S t r e a m ( " p i c t . j p g " ) ; o u t . w r i t e ( d a t a ) ; o u t . c l o s e ( ) ; } }

Named Ranges and Named Cells Named Range is a way to refer to a group of cells by a name. Named Cell is a degenerate case of Named Range in that the 'group of cells' contains exactly one cell. You can create as well as refer to cells in a workbook by their named range. When working with Named Ranges, the classes: org.apache.poi.hssf.util.CellReference and & org.apache.poi.hssf.util.AreaReference are used (these work for both XSSF and HSSF, despite the package name). Creating Named Range / Named Cell / /s e t u pc o d e S t r i n gs n a m e=" T e s t S h e e t " ,c n a m e=" T e s t N a m e " ,c v a l u e=" T e s t V a l " ; W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( s n a m e ) ; s h e e t . c r e a t e R o w ( 0 ) . c r e a t e C e l l ( ( s h o r t )0 ) . s e t C e l l V a l u e ( c v a l u e ) ; / /1 .c r e a t en a m e dr a n g ef o ras i n g l ec e l lu s i n ga r e a r e f e r e n c e N a m en a m e d C e l l=w b . c r e a t e N a m e ( ) ; n a m e d C e l l . s e t N a m e N a m e ( c n a m e ) ; S t r i n gr e f e r e n c e=s n a m e + " ! A 1 : A 1 " ;/ /a r e ar e f e r e n c e n a m e d C e l l . s e t R e f e r s T o F o r m u l a ( r e f e r e n c e ) ; / /2 .c r e a t en a m e dr a n g ef o ras i n g l ec e l lu s i n gc e l l r e f e r e n c e N a m en a m e d C e l 2=w b . c r e a t e N a m e ( ) ; n a m e d C e l 2 . s e t N a m e N a m e ( c n a m e ) ; S t r i n gr e f e r e n c e=s n a m e + " ! A 1 " ;/ /c e l lr e f e r e n c e n a m e d C e l 2 . s e t R e f e r s T o F o r m u l a ( r e f e r e n c e ) ; / /3 .c r e a t en a m e dr a n g ef o ra na r e au s i n gA r e a R e f e r e n c e N a m en a m e d C e l 3=w b . c r e a t e N a m e ( ) ; n a m e d C e l 3 . s e t N a m e N a m e ( c n a m e ) ; S t r i n gr e f e r e n c e=s n a m e + " ! A 1 : C 5 " ;/ /a r e ar e f e r e n c e n a m e d C e l 3 . s e t R e f e r s T o F o r m u l a ( r e f e r e n c e ) ; / /4 .c r e a t en a m e df o r m u l a N a m en a m e d C e l 4=w b . c r e a t e N a m e ( ) ; n a m e d C e l 4 . s e t N a m e N a m e ( " m y _ s u m " ) ; n a m e d C e l 4 . s e t R e f e r s T o F o r m u l a ( " S U M ( s n a m e + ! $ I $ 2 : $ I $ 6 ) " ) ; Reading from Named Range / Named Cell / /s e t u pc o d e S t r i n gc n a m e=" T e s t N a m e " ; W o r k b o o kw b=g e t M y W o r k b o o k ( ) ;/ /r e t r i e v ew o r k b o o k / /r e t r i e v et h en a m e dr a n g e i n tn a m e d C e l l I d x=w b . g e t N a m e I n d e x ( c e l l N a m e ) ; N a m ea N a m e d C e l l=w b . g e t N a m e A t ( n a m e d C e l l I d x ) ; / /r e t r i e v et h ec e l la tt h en a m e dr a n g ea n dt e s ti t sc o n t e n t s A r e a R e f e r e n c ea r e f=n e wA r e a R e f e r e n c e ( a N a m e d C e l l . g e t R e f e r s T o F o r m u l a ( ) ) ; C e l l R e f e r e n c e [ ]c r e f s=a r e f . g e t A l l R e f e r e n c e d C e l l s ( ) ; f o r( i n ti = 0 ;i < c r e f s . l e n g t h ;i + + ){ S h e e ts=w b . g e t S h e e t ( c r e f s [ i ] . g e t S h e e t N a m e ( ) ) ; R o wr=s h e e t . g e t R o w ( c r e f s [ i ] . g e t R o w ( ) ) ; C e l lc=r . g e t C e l l ( c r e f s [ i ] . g e t C o l ( ) ) ; / /e x t r a c tt h ec e l lc o n t e n t sb a s e do nc e l lt y p ee t c . } Reading from non-contiguous Named Ranges / /S e t u pc o d e S t r i n gc n a m e=" T e s t N a m e " ; W o r k b o o kw b=g e t M y W o r k b o o k ( ) ;/ /r e t r i e v ew o r k b o o k

poi.apache.org/spreadsheet/quick-guide.html#CellContents

14/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features


/ /R e t r i e v et h en a m e dr a n g e / /W i l lb es o m e t h i n gl i k e" $ C $ 1 0 , $ D $ 1 2 : $ D $ 1 4 " ; i n tn a m e d C e l l I d x=w b . g e t N a m e I n d e x ( c e l l N a m e ) ; N a m ea N a m e d C e l l=w b . g e t N a m e A t ( n a m e d C e l l I d x ) ; / /R e t r i e v et h ec e l la tt h en a m e dr a n g ea n dt e s ti t sc o n t e n t s / /W i l lg e tb a c ko n eA r e a R e f e r e n c ef o rC 1 0 ,a n d / / a n o t h e rf o rD 1 2t oD 1 4 A r e a R e f e r e n c e [ ]a r e f s=A r e a R e f e r e n c e . g e n e r a t e C o n t i g u o u s ( a N a m e d C e l l . g e t R e f e r s T o F o r m u l a ( ) ) ; f o r( i n ti = 0 ;i < a r e f s . l e n g t h ;i + + ){ / /O n l yg e tt h ec o r n e r so ft h eA r e a / /( u s ea r e f s [ i ] . g e t A l l R e f e r e n c e d C e l l s ( )t og e ta l lc e l l s ) C e l l R e f e r e n c e [ ]c r e f s=a r e f s [ i ] . g e t C e l l s ( ) ; f o r( i n tj = 0 ;j < c r e f s . l e n g t h ;j + + ){ / /C h e c ki tt u r n si n t or e a ls t u f f S h e e ts=w b . g e t S h e e t ( c r e f s [ j ] . g e t S h e e t N a m e ( ) ) ; R o wr=s . g e t R o w ( c r e f s [ j ] . g e t R o w ( ) ) ; C e l lc=r . g e t C e l l ( c r e f s [ j ] . g e t C o l ( ) ) ; / /D os o m e t h i n gw i t ht h i sc o r n e rc e l l } }

Note, when a cell is deleted, Excel does not delete the attached named range. As result, workbook can contain named ranges that point to cells that no longer exist. You should check the validity of a reference before constructing AreaReference i f ( n a m e . i s D e l e t e d ( ) ) { / / n a m e dr a n g ep o i n t st oad e l e t e dc e l l . }e l s e{ A r e a R e f e r e n c er e f=n e wA r e a R e f e r e n c e ( n a m e . g e t R e f e r s T o F o r m u l a ( ) ) ; }

Cell Comments - HSSF and XSSF A comment is a rich text note that is attached to & associated with a cell, separate from other cell content. Comment content is stored separate from the cell, and is displayed in a drawing object (like a text box) that is separate from, but associated with, a cell W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ;/ / o rn e wH S S F W o r k b o o k ( ) ; C r e a t i o n H e l p e rf a c t o r y=w b . g e t C r e a t i o n H e l p e r ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( ) ; R o w lr o w =s h e e t . c r e a t e R o w ( 3 ) ; C e l lc e l l=r o w . c r e a t e C e l l ( 5 ) ; c e l l . s e t C e l l V a l u e ( " F 4 " ) ; D r a w i n gd r a w i n g=s h e e t . c r e a t e D r a w i n g P a t r i a r c h ( ) ; / /W h e nt h ec o m m e n tb o xi sv i s i b l e ,h a v ei ts h o wi na1 x 3s p a c e C l i e n t A n c h o ra n c h o r=f a c t o r y . c r e a t e C l i e n t A n c h o r ( ) ; a n c h o r . s e t C o l 1 ( c e l l . g e t C o l u m n I n d e x ( ) ) ; a n c h o r . s e t C o l 2 ( c e l l . g e t C o l u m n I n d e x ( ) + 1 ) ; a n c h o r . s e t R o w 1 ( r o w . g e t R o w N u l ( ) ) ; a n c h o r . s e t R o w 2 ( r o w . g e t R o w N u l ( ) + 3 ) ; / /C r e a t et h ec o m m e n ta n ds e tt h et e x t + a u t h o r C o m m e n tc o m m e n t=d r a w i n g . c r e a t e C e l l C o m m e n t ( a n c h o r ) ; R i c h T e x t S t r i n gs t r=f a c t o r y . c r e a t e R i c h T e x t S t r i n g ( " H e l l o ,W o r l d ! " ) ; c o m m e n t . s e t S t r i n g ( s t r ) ; c o m m e n t . s e t A u t h o r ( " A p a c h eP O I " ) ; / /A s s i g nt h ec o m m e n tt ot h ec e l l c e l l . s e t C e l l C o m m e n t ( c o m m e n t ) ; S t r i n gf n a m e=" c o m m e n t x s s f . x l s " ; i f ( w bi n s t a n c e o fX S S F W o r k b o o k )f n a m e+ =" x " ; F i l e O u t p u t S t r e a mo u t=n e wF i l e O u t p u t S t r e a m ( f n a m e ) ; w b . w r i t e ( o u t ) ; o u t . c l o s e ( ) ; Reading cell comments C e l lc e l l=s h e e t . g e t ( 3 ) . g e t C o l u m n ( ( s h o r t ) 1 ) ; C o m m e n tc o m m e n t=c e l l . g e t C e l l C o m m e n t ( ) ; i f( c o m m e n t! =n u l l ){ R i c h T e x t S t r i n gs t r=c o m m e n t . g e t S t r i n g ( ) ; S t r i n ga u t h o r=c o m m e n t . g e t A u t h o r ( ) ; } / / a l t e r n a t i v e l yy o uc a nr e t r i e v ec e l lc o m m e n t sb y( r o w ,c o l u m n )

poi.apache.org/spreadsheet/quick-guide.html#CellContents

15/23

3/25/13

/ / a l t e r n a t i v e l yy o uc a nr e t r i e v ec e l lc o m m e n t sb y( r o w ,c o l u m n ) c o m m e n t=s h e e t . g e t C e l l C o m m e n t ( 3 ,1 ) ;

Busy Developers' Guide to HSSF and XSSF Features

Adjust column width to fit the contents S h e e ts h e e t=w o r k b o o k . g e t S h e e t A t ( 0 ) ; s h e e t . a u t o S i z e C o l u m n ( 0 ) ;/ / a d j u s tw i d t ho ft h ef i r s tc o l u m n s h e e t . a u t o S i z e C o l u m n ( 1 ) ;/ / a d j u s tw i d t ho ft h es e c o n dc o l u m n Note, that Sheet#autoSizeColumn() does not evaluate formula cells, the width of formula cells is calculated based on the cached formula result. If your workbook has many formulas then it is a good idea to evaluate them before auto-sizing. Warning
To calculate column width Sheet.autoSizeColumn uses Java2D classes that throw exception if graphical environment is not available. In case if graphical environment is not available, you must tell Java that you are running in headless mode and set the following system property: j a v a . a w t . h e a d l e s s = t r u e.

How to read hyperlinks S h e e ts h e e t=w o r k b o o k . g e t S h e e t A t ( 0 ) ; C e l lc e l l=s h e e t . g e t R o w ( 0 ) . g e t C e l l ( ( s h o r t ) 0 ) ; H y p e r l i n kl i n k=c e l l . g e t H y p e r l i n k ( ) ; i f ( l i n k! =n u l l ) { S y s t e m . o u t . p r i n t l n ( l i n k . g e t A d d r e s s ( ) ) ; } How to create hyperlinks W o r k b o o kw b=n e wX S S F W o r k b o o k ( ) ;/ / o rn e wH S S F W o r k b o o k ( ) ; C r e a t i o n H e l p e rc r e a t e H e l p e r=w b . g e t C r e a t i o n H e l p e r ( ) ; / / c e l ls t y l ef o rh y p e r l i n k s / / b yd e f a u l th y p e r l i n k sa r eb l u ea n du n d e r l i n e d C e l l S t y l eh l i n k _ s t y l e=w b . c r e a t e C e l l S t y l e ( ) ; F o n th l i n k _ f o n t=w b . c r e a t e F o n t ( ) ; h l i n k _ f o n t . s e t U n d e r l i n e ( F o n t . U _ S I N G L E ) ; h l i n k _ f o n t . s e t C o l o r ( I n d e x e d C o l o r s . B L U E . g e t I n d e x ( ) ) ; h l i n k _ s t y l e . s e t F o n t ( h l i n k _ f o n t ) ; C e l lc e l l ; S h e e ts h e e t=w b . c r e a t e S h e e t ( " H y p e r l i n k s " ) ; / / U R L c e l l=s h e e t . c r e a t e R o w ( 0 ) . c r e a t e C e l l ( ( s h o r t ) 0 ) ; c e l l . s e t C e l l V a l u e ( " U R LL i n k " ) ; H y p e r l i n kl i n k=c r e a t e H e l p e r . c r e a t e H y p e r l i n k ( H y p e r l i n k . L I N K _ U R L ) ; l i n k . s e t A d d r e s s ( " h t t p : / / p o i . a p a c h e . o r g / " ) ; c e l l . s e t H y p e r l i n k ( l i n k ) ; c e l l . s e t C e l l S t y l e ( h l i n k _ s t y l e ) ; / / l i n kt oaf i l ei nt h ec u r r e n td i r e c t o r y c e l l=s h e e t . c r e a t e R o w ( 1 ) . c r e a t e C e l l ( ( s h o r t ) 0 ) ; c e l l . s e t C e l l V a l u e ( " F i l eL i n k " ) ; l i n k=c r e a t e H e l p e r . c r e a t e H y p e r l i n k ( H y p e r l i n k . L I N K _ F I L E ) ; l i n k . s e t A d d r e s s ( " l i n k 1 . x l s " ) ; c e l l . s e t H y p e r l i n k ( l i n k ) ; c e l l . s e t C e l l S t y l e ( h l i n k _ s t y l e ) ; / / e m a i ll i n k c e l l=s h e e t . c r e a t e R o w ( 2 ) . c r e a t e C e l l ( ( s h o r t ) 0 ) ; c e l l . s e t C e l l V a l u e ( " E m a i lL i n k " ) ; l i n k=c r e a t e H e l p e r . c r e a t e H y p e r l i n k ( H y p e r l i n k . L I N K _ E M A I L ) ; / / n o t e ,i fs u b j e c tc o n t a i n sw h i t es p a c e s ,m a k es u r et h e ya r eu r l e n c o d e d l i n k . s e t A d d r e s s ( " m a i l t o : p o i @ a p a c h e . o r g ? s u b j e c t = H y p e r l i n k s " ) ; c e l l . s e t H y p e r l i n k ( l i n k ) ; c e l l . s e t C e l l S t y l e ( h l i n k _ s t y l e ) ; / / l i n kt oap l a c ei nt h i sw o r k b o o k / / c r e a t eat a r g e ts h e e ta n dc e l l S h e e ts h e e t 2=w b . c r e a t e S h e e t ( " T a r g e tS h e e t " ) ; s h e e t 2 . c r e a t e R o w ( 0 ) . c r e a t e C e l l ( ( s h o r t ) 0 ) . s e t C e l l V a l u e ( " T a r g e tC e l l " ) ; c e l l=s h e e t . c r e a t e R o w ( 3 ) . c r e a t e C e l l ( ( s h o r t ) 0 ) ; c e l l . s e t C e l l V a l u e ( " W o r k s h e e tL i n k " ) ; H y p e r l i n kl i n k 2=c r e a t e H e l p e r . c r e a t e H y p e r l i n k ( H y p e r l i n k . L I N K _ D O C U M E N T ) ; l i n k 2 . s e t A d d r e s s ( " ' T a r g e tS h e e t ' ! A 1 " ) ; c e l l . s e t H y p e r l i n k ( l i n k 2 ) ;

poi.apache.org/spreadsheet/quick-guide.html#CellContents

16/23

3/25/13

c e l l . s e t H y p e r l i n k ( l i n k 2 ) ; c e l l . s e t C e l l S t y l e ( h l i n k _ s t y l e ) ;

Busy Developers' Guide to HSSF and XSSF Features

F i l e O u t p u t S t r e a mo u t=n e wF i l e O u t p u t S t r e a m ( " h y p e r i n k s . x l s x " ) ; w b . w r i t e ( o u t ) ; o u t . c l o s e ( ) ;

Data Validations As of version 3.8, POI has slightly different syntax to work with data validations with .xls and .xlsx formats. hssf.usermodel (binary .xls format) Check the value a user enters into a cell against one or more predefined value(s). The following code will limit the value the user can enter into cell A1 to one of three integer values, 10, 20 or 30. H S S F W o r k b o o kw o r k b o o k=n e wH S S F W o r k b o o k ( ) ; H S S F S h e e ts h e e t=w o r k b o o k . c r e a t e S h e e t ( " D a t aV a l i d a t i o n " ) ; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,0 ,0 ) ; D V C o n s t r a i n td v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e E x p l i c i t L i s t C o n s t r a i n t ( n e wS t r i n g [ ] { " 1 0 " ," 2 0 " ," 3 0 " } ) ; D a t a V a l i d a t i o nd a t a V a l i d a t i o n=n e wH S S F D a t a V a l i d a t i o n ( a d d r e s s L i s t ,d v C o n s t r a i n t ) ; d a t a V a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( t r u e ) ; s h e e t . a d d V a l i d a t i o n D a t a ( d a t a V a l i d a t i o n ) ; Drop Down Lists: This code will do the same but offer the user a drop down list to select a value from. H S S F W o r k b o o kw o r k b o o k=n e wH S S F W o r k b o o k ( ) ; H S S F S h e e ts h e e t=w o r k b o o k . c r e a t e S h e e t ( " D a t aV a l i d a t i o n " ) ; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,0 ,0 ) ; D V C o n s t r a i n td v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e E x p l i c i t L i s t C o n s t r a i n t ( n e wS t r i n g [ ] { " 1 0 " ," 2 0 " ," 3 0 " } ) ; D a t a V a l i d a t i o nd a t a V a l i d a t i o n=n e wH S S F D a t a V a l i d a t i o n ( a d d r e s s L i s t ,d v C o n s t r a i n t ) ; d a t a V a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( f a l s e ) ; s h e e t . a d d V a l i d a t i o n D a t a ( d a t a V a l i d a t i o n ) ; Messages On Error: To create a message box that will be shown to the user if the value they enter is invalid. d a t a V a l i d a t i o n . s e t E r r o r S t y l e ( D a t a V a l i d a t i o n . E r r o r S t y l e . S T O P ) ; d a t a V a l i d a t i o n . c r e a t e E r r o r B o x ( " B o xT i t l e " ," M e s s a g eT e x t " ) ; Replace 'Box Title' with the text you wish to display in the message box's title bar and 'Message Text' with the text of your error message. Prompts: To create a prompt that the user will see when the cell containing the data validation receives focus d a t a V a l i d a t i o n . c r e a t e P r o m p t B o x ( " T i t l e " ," M e s s a g eT e x t " ) ; d a t a V a l i d a t i o n . s e t S h o w P r o m p t B o x ( t r u e ) ; The text encapsulated in the first parameter passed to the createPromptBox() method will appear emboldened and as a title to the prompt whilst the second will be displayed as the text of the message. The createExplicitListConstraint() method can be passed and array of String(s) containing interger, floating point, dates or text values. Further Data Validations: To obtain a validation that would check the value entered was, for example, an integer between 10 and 100, use the DVConstraint.createNumericConstraint(int, int, String, String) factory method. d v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e N u m e r i c C o n s t r a i n t ( D V C o n s t r a i n t . V a l i d a t i o n T y p e . I N T E G E R , D V C o n s t r a i n t . O p e r a t o r T y p e . B E T W E E N ," 1 0 " ," 1 0 0 " ) ; Look at the javadoc for the other validation and operator types; also note that not all validation types are supported for this method. The values passed to the two String parameters can be formulas; the '=' symbol is used to denote a formula d v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e N u m e r i c C o n s t r a i n t ( D V C o n s t r a i n t . V a l i d a t i o n T y p e . I N T E G E R , D V C o n s t r a i n t . O p e r a t o r T y p e . B E T W E E N ," = S U M ( A 1 : A 3 ) " ," 1 0 0 " ) ; It is not possible to create a drop down list if the createNumericConstraint() method is called, the setSuppressDropDownArrow(false)

poi.apache.org/spreadsheet/quick-guide.html#CellContents

17/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features

It is not possible to create a drop down list if the createNumericConstraint() method is called, the setSuppressDropDownArrow(false) method call will simply be ignored. Date and time constraints can be created by calling the createDateConstraint(int, String, String, String) or the createTimeConstraint(int, String, String). Both are very similar to the above and are explained in the javadoc. Creating Data Validations From Spreadsheet Cells. The contents of specific cells can be used to provide the values for the data validation and the DVConstraint.createFormulaListConstraint(String) method supports this. To specify that the values come from a contiguous range of cells do either of the following: d v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " $ A $ 1 : $ A $ 3 " ) ; or N a m en a m e d R a n g e=w o r k b o o k . c r e a t e N a m e ( ) ; n a m e d R a n g e . s e t N a m e N a m e ( " l i s t 1 " ) ; n a m e d R a n g e . s e t R e f e r s T o F o r m u l a ( " $ A $ 1 : $ A $ 3 " ) ; d v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " l i s t 1 " ) ; and in both cases the user will be able to select from a drop down list containing the values from cells A1, A2 and A3. The data does not have to be as the data validation. To select the data from a different sheet however, the sheet must be given a name when created and that name should be used in the formula. So assuming the existence of a sheet named 'Data Sheet' this will work: N a m en a m e d R a n g e=w o r k b o o k . c r e a t e N a m e ( ) ; n a m e d R a n g e . s e t N a m e N a m e ( " l i s t 1 " ) ; n a m e d R a n g e . s e t R e f e r s T o F o r m u l a ( " ' D a t aS h e e t ' ! $ A $ 1 : $ A $ 3 " ) ; d v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " l i s t 1 " ) ; as will this: d v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " ' D a t aS h e e t ' ! $ A $ 1 : $ A $ 3 " ) ; whilst this will not: N a m en a m e d R a n g e=w o r k b o o k . c r e a t e N a m e ( ) ; n a m e d R a n g e . s e t N a m e N a m e ( " l i s t 1 " ) ; n a m e d R a n g e . s e t R e f e r s T o F o r m u l a ( " ' S h e e t 1 ' ! $ A $ 1 : $ A $ 3 " ) ; d v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " l i s t 1 " ) ; and nor will this: d v C o n s t r a i n t=D V C o n s t r a i n t . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " ' S h e e t 1 ' ! $ A $ 1 : $ A $ 3 " ) ;

xssf.usermodel (.xlsx format) Data validations work similarly when you are creating an xml based, SpreadsheetML, workbook file; but there are differences. Explicit casts are required, for example, in a few places as much of the support for data validations in the xssf stream was built into the unifying ss stream, of which more later. Other differences are noted with comments in the code. Check the value the user enters into a cell against one or more predefined value(s). X S S F W o r k b o o kw o r k b o o k=n e wX S S F W o r k b o o k ( ) ; X S S F S h e e ts h e e t=w o r k b o o k . c r e a t e S h e e t ( " D a t aV a l i d a t i o n " ) ; X S S F D a t a V a l i d a t i o n H e l p e rd v H e l p e r=n e wX S S F D a t a V a l i d a t i o n H e l p e r ( s h e e t ) ; X S S F D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=( X S S F D a t a V a l i d a t i o n C o n s t r a i n t ) d v H e l p e r . c r e a t e E x p l i c i t L i s t C o n s t r a i n t ( n e wS t r i n g [ ] { " 1 1 " ," 2 1 " ," 3 1 " } ) ; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,0 ,0 ) ; X S S F D a t a V a l i d a t i o nv a l i d a t i o n= ( X S S F D a t a V a l i d a t i o n ) d v H e l p e r . c r e a t e V a l i d a t i o n ( d v C o n s t r a i n t ,a d d r e s s L i s t ) ; / /H e r et h eb o o l e a nv a l u ef a l s ei sp a s s e dt ot h es e t S u p p r e s s D r o p D o w n A r r o w ( ) / /m e t h o d .I nt h eh s s f . u s e r m o d e le x a m p l e sa b o v e ,t h ev a l u ep a s s e dt ot h i s / /m e t h o di st r u e . v a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( f a l s e ) ; / /N o t et h i se x t r am e t h o dc a l l .I ft h i sm e t h o dc a l li so m i t t e d ,o ri ft h e / /b o o l e a nv a l u ef a l s ei sp a s s e d ,t h e nE x c e lw i l ln o tv a l i d a t et h ev a l u et h e / /u s e re n t e r si n t ot h ec e l l . v a l i d a t i o n . s e t S h o w E r r o r B o x ( t r u e ) ; s h e e t . a d d V a l i d a t i o n D a t a ( v a l i d a t i o n ) ; Drop Down Lists: This code will do the same but offer the user a drop down list to select a value from. X S S F W o r k b o o kw o r k b o o k=n e wX S S F W o r k b o o k ( ) ; X S S F S h e e ts h e e t=w o r k b o o k . c r e a t e S h e e t ( " D a t aV a l i d a t i o n " ) ; X S S F D a t a V a l i d a t i o n H e l p e rd v H e l p e r=n e wX S S F D a t a V a l i d a t i o n H e l p e r ( s h e e t ) ;

poi.apache.org/spreadsheet/quick-guide.html#CellContents

18/23

3/25/13

X S S F D a t a V a l i d a t i o n H e l p e rd v H e l p e r=n e wX S S F D a t a V a l i d a t i o n H e l p e r ( s h e e t ) ; X S S F D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=( X S S F D a t a V a l i d a t i o n C o n s t r a i n t ) d v H e l p e r . c r e a t e E x p l i c i t L i s t C o n s t r a i n t ( n e wS t r i n g [ ] { " 1 1 " ," 2 1 " ," 3 1 " } ) ; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,0 ,0 ) ; X S S F D a t a V a l i d a t i o nv a l i d a t i o n=( X S S F D a t a V a l i d a t i o n ) d v H e l p e r . c r e a t e V a l i d a t i o n ( d v C o n s t r a i n t ,a d d r e s s L i s t ) ; v a l i d a t i o n . s e t S h o w E r r o r B o x ( t r u e ) ; s h e e t . a d d V a l i d a t i o n D a t a ( v a l i d a t i o n ) ;

Busy Developers' Guide to HSSF and XSSF Features

Note that the call to the setSuppressDropDowmArrow() method can either be simply excluded or replaced with: v a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( t r u e ) ; Prompts and Error Messages: These both exactly mirror the hssf.usermodel so please refer to the 'Messages On Error:' and 'Prompts:' sections above. Further Data Validations: To obtain a validation that would check the value entered was, for example, an integer between 10 and 100, use the XSSFDataValidationHelper(s) createNumericConstraint(int, int, String, String) factory method. X S S F D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=( X S S F D a t a V a l i d a t i o n C o n s t r a i n t ) d v H e l p e r . c r e a t e N u m e r i c C o n s t r a i n t ( X S S F D a t a V a l i d a t i o n C o n s t r a i n t . V a l i d a t i o n T y p e . I N T E G E R , X S S F D a t a V a l i d a t i o n C o n s t r a i n t . O p e r a t o r T y p e . B E T W E E N , " 1 0 " ," 1 0 0 " ) ; The values passed to the final two String parameters can be formulas; the '=' symbol is used to denote a formula. Thus, the following would create a validation the allows values only if they fall between the results of summing two cell ranges X S S F D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=( X S S F D a t a V a l i d a t i o n C o n s t r a i n t ) d v H e l p e r . c r e a t e N u m e r i c C o n s t r a i n t ( X S S F D a t a V a l i d a t i o n C o n s t r a i n t . V a l i d a t i o n T y p e . I N T E G E R , X S S F D a t a V a l i d a t i o n C o n s t r a i n t . O p e r a t o r T y p e . B E T W E E N , " = S U M ( A 1 : A 1 0 ) " ," = S U M ( B 2 4 : B 2 7 ) " ) ; It is not possible to create a drop down list if the createNumericConstraint() method is called, the setSuppressDropDownArrow(true) method call will simply be ignored. Please check the javadoc for other constraint types as examples for those will not be included here. There are, for example, methods defined on the XSSFDataValidationHelper class allowing you to create the following types of constraint; date, time, decimal, integer, numeric, formula, text length and custom constraints. Creating Data Validations From Spread Sheet Cells: One other type of constraint not mentioned above is the formula list constraint. It allows you to create a validation that takes it value(s) from a range of cells. This code X S S F D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=( X S S F D a t a V a l i d a t i o n C o n s t r a i n t ) d v H e l p e r . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " $ A $ 1 : $ F $ 1 " ) ; would create a validation that took it's values from cells in the range A1 to F1. The usefulness of this technique can be extended if you use named ranges like this; X S S F N a m en a m e=w o r k b o o k . c r e a t e N a m e ( ) ; n a m e . s e t N a m e N a m e ( " d a t a " ) ; n a m e . s e t R e f e r s T o F o r m u l a ( " $ B $ 1 : $ F $ 1 " ) ; X S S F D a t a V a l i d a t i o n H e l p e rd v H e l p e r=n e wX S S F D a t a V a l i d a t i o n H e l p e r ( s h e e t ) ; X S S F D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=( X S S F D a t a V a l i d a t i o n C o n s t r a i n t ) d v H e l p e r . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " d a t a " ) ; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,0 ,0 ) ; X S S F D a t a V a l i d a t i o nv a l i d a t i o n=( X S S F D a t a V a l i d a t i o n ) d v H e l p e r . c r e a t e V a l i d a t i o n ( d v C o n s t r a i n t ,a d d r e s s L i s t ) ; v a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( t r u e ) ; v a l i d a t i o n . s e t S h o w E r r o r B o x ( t r u e ) ; s h e e t . a d d V a l i d a t i o n D a t a ( v a l i d a t i o n ) ; OpenOffice Calc has slightly different rules with regard to the scope of names. Excel supports both Workbook and Sheet scope for a name but Calc does not, it seems only to support Sheet scope for a name. Thus it is often best to fully qualify the name for the region or area something like this; X S S F N a m en a m e=w o r k b o o k . c r e a t e N a m e ( ) ; n a m e . s e t N a m e N a m e ( " d a t a " ) ; n a m e . s e t R e f e r s T o F o r m u l a ( " ' D a t aV a l i d a t i o n ' ! $ B $ 1 : $ F $ 1 " ) ; . . . . This does open a further, interesting opportunity however and that is to place all of the data for the validation(s) into named ranges of cells on a hidden sheet within the workbook. These ranges can then be explicitly identified in the setRefersToFormula() method argument. ss.usermodel The classes within the ss.usermodel package allow developers to create code that can be used to generate both binary (.xls) and SpreadsheetML (.xlsx) workbooks.

poi.apache.org/spreadsheet/quick-guide.html#CellContents

The techniques used to create data validations share much in common with the xssf.usermodel examples above. As a result just one or two

19/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features

The techniques used to create data validations share much in common with the xssf.usermodel examples above. As a result just one or two examples will be presented here. Check the value the user enters into a cell against one or more predefined value(s). W o r k b o o kw o r k b o o k=n e wX S S F W o r k b o o k ( ) ; / /o rn e wH S S F W o r k b o o k S h e e ts h e e t=w o r k b o o k . c r e a t e S h e e t ( " D a t aV a l i d a t i o n " ) ; D a t a V a l i d a t i o n H e l p e rd v H e l p e r=s h e e t . g e t D a t a V a l i d a t i o n H e l p e r ( ) ; D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=d v H e l p e r . c r e a t e E x p l i c i t L i s t C o n s t r a i n t ( n e wS t r i n g [ ] { " 1 3 " ," 2 3 " ," 3 3 " } ) ; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,0 ,0 ) ; D a t a V a l i d a t i o nv a l i d a t i o n=d v H e l p e r . c r e a t e V a l i d a t i o n ( d v C o n s t r a i n t ,a d d r e s s L i s t ) ; / /N o t et h ec h e c ko nt h ea c t u a lt y p eo ft h eD a t a V a l i d a t i o no b j e c t . / /I fi ti sa ni n s t a n c eo ft h eX S S F D a t a V a l i d a t i o nc l a s st h e nt h e / /b o o l e a nv a l u e' f a l s e 'm u s tb ep a s s e dt ot h es e t S u p p r e s s D r o p D o w n A r r o w ( ) / /m e t h o da n da ne x p l i c i tc a l lm a d et ot h es e t S h o w E r r o r B o x ( )m e t h o d . i f ( v a l i d a t i o ni n s t a n c e o fX S S F D a t a V a l i d a t i o n ){ v a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( f a l s e ) ; v a l i d a t i o n . s e t S h o w E r r o r B o x ( t r u e ) ; } e l s e{ / /I ft h eD a t a v a l i d a t i o nc o n t a i n sa ni n s t a n c eo ft h eH S S F D a t a V a l i d a t i o n / /c l a s st h e n' t r u e 's h o u l db ep a s s e dt ot h es e t S u p p r e s s D r o p D o w n A r r o w ( ) / /m e t h o da n dt h ec a l lt os e t S h o w E r r o r B o x ( )i sn o tn e c e s s a r y . v a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( t r u e ) ; } s h e e t . a d d V a l i d a t i o n D a t a ( v a l i d a t i o n ) ; Drop Down Lists: This code will do the same but offer the user a drop down list to select a value from. W o r k b o o kw o r k b o o k=n e wX S S F W o r k b o o k ( ) ; / /o rn e wH S S F W o r k b o o k S h e e ts h e e t=w o r k b o o k . c r e a t e S h e e t ( " D a t aV a l i d a t i o n " ) ; D a t a V a l i d a t i o n H e l p e rd v H e l p e r=s h e e t . g e t D a t a V a l i d a t i o n H e l p e r ( ) ; D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=d v H e l p e r . c r e a t e E x p l i c i t L i s t C o n s t r a i n t ( n e wS t r i n g [ ] { " 1 3 " ," 2 3 " ," 3 3 " } ) ; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,0 ,0 ) ; D a t a V a l i d a t i o nv a l i d a t i o n=d v H e l p e r . c r e a t e V a l i d a t i o n ( d v C o n s t r a i n t ,a d d r e s s L i s t ) ; / /N o t et h ec h e c ko nt h ea c t u a lt y p eo ft h eD a t a V a l i d a t i o no b j e c t . / /I fi ti sa ni n s t a n c eo ft h eX S S F D a t a V a l i d a t i o nc l a s st h e nt h e / /b o o l e a nv a l u e' f a l s e 'm u s tb ep a s s e dt ot h es e t S u p p r e s s D r o p D o w n A r r o w ( ) / /m e t h o da n da ne x p l i c i tc a l lm a d et ot h es e t S h o w E r r o r B o x ( )m e t h o d . i f ( v a l i d a t i o ni n s t a n c e o fX S S F D a t a V a l i d a t i o n ){ v a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( t r u e ) ; v a l i d a t i o n . s e t S h o w E r r o r B o x ( t r u e ) ; } e l s e{ / /I ft h eD a t a v a l i d a t i o nc o n t a i n sa ni n s t a n c eo ft h eH S S F D a t a V a l i d a t i o n / /c l a s st h e n' t r u e 's h o u l db ep a s s e dt ot h es e t S u p p r e s s D r o p D o w n A r r o w ( ) / /m e t h o da n dt h ec a l lt os e t S h o w E r r o r B o x ( )i sn o tn e c e s s a r y . v a l i d a t i o n . s e t S u p p r e s s D r o p D o w n A r r o w ( f a l s e ) ; } s h e e t . a d d V a l i d a t i o n D a t a ( v a l i d a t i o n ) ; Prompts and Error Messages: These both exactly mirror the hssf.usermodel so please refer to the 'Messages On Error:' and 'Prompts:' sections above. As the differences between the ss.usermodel and xssf.usermodel examples are small - restricted largely to the way the DataValidationHelper is obtained, the lack of any need to explicitly cast data types and the small difference in behaviour between the hssf and xssf interpretation of the setSuppressDropDowmArrow() method, no further examples will be included in this section. Advanced Data Validations. Dependent Drop Down Lists. In some cases, it may be necessary to present to the user a sheet which contains more than one drop down list. Further, the choice the user makes in one drop down list may affect the options that are presented to them in the second or subsequent drop down lists. One technique that may be used to implement this behaviour will now be explained. There are two keys to the technique; one is to use named areas or regions of cells to hold the data for the drop down lists, the second is to use the INDIRECT() function to convert between the name and the actual addresses of the cells. In the example section there is a complete working example- called LinkedDropDownLists.java - that demonstrates how to create linked or dependent drop down lists. Only the more relevant points are explained here. To create two drop down lists where the options shown in the second depend upon the selection made in the first, begin by creating a named region of cells to hold all of the data for populating the first drop down list. Next, create a data validation that will look to this named area for its data, something like this; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,0 ,0 ) ; D a t a V a l i d a t i o n H e l p e rd v H e l p e r=s h e e t . g e t D a t a V a l i d a t i o n H e l p e r ( ) ; D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=d v H e l p e r . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " C H O I C E S " ) ; D a t a V a l i d a t i o nv a l i d a t i o n=d v H e l p e r . c r e a t e V a l i d a t i o n ( d v C o n s t r a i n t ,a d d r e s s L i s t ) ;

poi.apache.org/spreadsheet/quick-guide.html#CellContents

20/23

3/25/13
d v C o n s t r a i n t ,a d d r e s s L i s t ) ; s h e e t . a d d V a l i d a t i o n D a t a ( v a l i d a t i o n ) ;

Busy Developers' Guide to HSSF and XSSF Features

Note that the name of the area - in the example above it is 'CHOICES' - is simply passed to the createFormulaListConstraint() method. This is sufficient to cause Excel to populate the drop down list with data from that named region. Next, for each of the options the user could select in the first drop down list, create a matching named region of cells. The name of that region should match the text the user could select in the first drop down list. Note, in the example, all upper case letters are used in the names of the regions of cells. Now, very similar code can be used to create a second, linked, drop down list; C e l l R a n g e A d d r e s s L i s ta d d r e s s L i s t=n e wC e l l R a n g e A d d r e s s L i s t ( 0 ,0 ,1 ,1 ) ; D a t a V a l i d a t i o n C o n s t r a i n td v C o n s t r a i n t=d v H e l p e r . c r e a t e F o r m u l a L i s t C o n s t r a i n t ( " I N D I R E C T ( U P P E R ( $ A $ 1 ) ) " ) ; D a t a V a l i d a t i o nv a l i d a t i o n=d v H e l p e r . c r e a t e V a l i d a t i o n ( d v C o n s t r a i n t ,a d d r e s s L i s t ) ; s h e e t . a d d V a l i d a t i o n D a t a ( v a l i d a t i o n ) ; The key here is in the following Excel function - INDIRECT(UPPER($A$1)) - which is used to populate the second, linked, drop down list. Working from the inner-most pair of brackets, it instructs Excel to look at the contents of cell A1, to convert what it reads there into upper case as upper case letters are used in the names of each region - and then convert this name into the addresses of those cells that contain the data to populate another drop down list. Embedded Objects It is possible to perform more detailed processing of an embedded Excel, Word or PowerPoint document, or to work with any other type of embedded object. HSSF: P O I F S F i l e S y s t e mf s=n e wP O I F S F i l e S y s t e m ( n e wF i l e I n p u t S t r e a m ( " e x c e l _ w i t h _ e m b e d e d . x l s " ) ) ; H S S F W o r k b o o kw o r k b o o k=n e wH S S F W o r k b o o k ( f s ) ; f o r( H S S F O b j e c t D a t ao b j:w o r k b o o k . g e t A l l E m b e d d e d O b j e c t s ( ) ){ / / t h eO L E 2C l a s sN a m eo ft h eo b j e c t S t r i n go l e N a m e=o b j . g e t O L E 2 C l a s s N a m e ( ) ; i f( o l e N a m e . e q u a l s ( " W o r k s h e e t " ) ){ D i r e c t o r y N o d ed n=( D i r e c t o r y N o d e )o b j . g e t D i r e c t o r y ( ) ; H S S F W o r k b o o ke m b e d d e d W o r k b o o k=n e wH S S F W o r k b o o k ( d n ,f s ,f a l s e ) ; / / S y s t e m . o u t . p r i n t l n ( e n t r y . g e t N a m e ( )+" :"+e m b e d d e d W o r k b o o k . g e t N u m b e r O f S h e e t s ( ) ) ; }e l s ei f( o l e N a m e . e q u a l s ( " D o c u m e n t " ) ){ D i r e c t o r y N o d ed n=( D i r e c t o r y N o d e )o b j . g e t D i r e c t o r y ( ) ; H W P F D o c u m e n te m b e d d e d W o r d D o c u m e n t=n e wH W P F D o c u m e n t ( d n ,f s ) ; / / S y s t e m . o u t . p r i n t l n ( e n t r y . g e t N a m e ( )+" :"+e m b e d d e d W o r d D o c u m e n t . g e t R a n g e ( ) . t e x t ( ) ) ; } e l s ei f( o l e N a m e . e q u a l s ( " P r e s e n t a t i o n " ) ){ D i r e c t o r y N o d ed n=( D i r e c t o r y N o d e )o b j . g e t D i r e c t o r y ( ) ; S l i d e S h o we m b e d d e d P o w e r P o i n t D o c u m e n t=n e wS l i d e S h o w ( n e wH S L F S l i d e S h o w ( d n ,f s ) ) ; / / S y s t e m . o u t . p r i n t l n ( e n t r y . g e t N a m e ( )+" :"+e m b e d d e d P o w e r P o i n t D o c u m e n t . g e t S l i d e s ( ) . l e n g t h ) ; }e l s e{ i f ( o b j . h a s D i r e c t o r y E n t r y ( ) ) { / /T h eD i r e c t o r y E n t r yi saD o c u m e n t N o d e .E x a m i n ei t se n t r i e st of i n do u tw h a ti ti s D i r e c t o r y N o d ed n=( D i r e c t o r y N o d e )o b j . g e t D i r e c t o r y ( ) ; f o r( I t e r a t o re n t r i e s=d n . g e t E n t r i e s ( ) ;e n t r i e s . h a s N e x t ( ) ; ){ E n t r ye n t r y=( E n t r y )e n t r i e s . n e x t ( ) ; / / S y s t e m . o u t . p r i n t l n ( o l e N a m e+" . "+e n t r y . g e t N a m e ( ) ) ; } }e l s e{ / /T h e r ei sn oD i r e c t o r y E n t r y / /R e c o v e rt h eo b j e c t ' sd a t af r o mt h eH S S F O b j e c t D a t ai n s t a n c e . b y t e [ ]o b j e c t D a t a=o b j . g e t O b j e c t D a t a ( ) ; } } } XSSF: X S S F W o r k b o o kw o r k b o o k=n e wX S S F W o r k b o o k ( " e x c e l _ w i t h _ e m b e d e d . x l s x " ) ; f o r( P a c k a g e P a r tp P a r t:w o r k b o o k . g e t A l l E m b e d d s ( ) ){ S t r i n gc o n t e n t T y p e=p P a r t . g e t C o n t e n t T y p e ( ) ; / /E x c e lW o r k b o o k-e i t h e rb i n a r yo rO p e n X M L i f( c o n t e n t T y p e . e q u a l s ( " a p p l i c a t i o n / v n d . m s e x c e l " ) ){ H S S F W o r k b o o ke m b e d d e d W o r k b o o k=n e wH S S F W o r k b o o k ( p P a r t . g e t I n p u t S t r e a m ( ) ) ; } / /E x c e lW o r k b o o k-O p e n X M Lf i l ef o r m a t e l s ei f( c o n t e n t T y p e . e q u a l s ( " a p p l i c a t i o n / v n d . o p e n x m l f o r m a t s o f f i c e d o c u m e n t . s p r e a d s h e e t m l . s h e e t " ) ){ O P C P a c k a g ed o c P a c k a g e=O P C P a c k a g e . o p e n ( p P a r t . g e t I n p u t S t r e a m ( ) ) ; X S S F W o r k b o o ke m b e d d e d W o r k b o o k=n e wX S S F W o r k b o o k ( d o c P a c k a g e ) ; } / /W o r dD o c u m e n t-b i n a r y( O L E 2 C D F )f i l ef o r m a t e l s ei f( c o n t e n t T y p e . e q u a l s ( " a p p l i c a t i o n / m s w o r d " ) ){ H W P F D o c u m e n td o c u m e n t=n e wH W P F D o c u m e n t ( p P a r t . g e t I n p u t S t r e a m ( ) ) ; } / /W o r dD o c u m e n t-O p e n X M Lf i l ef o r m a t

poi.apache.org/spreadsheet/quick-guide.html#CellContents

21/23

3/25/13

/ /W o r dD o c u m e n t-O p e n X M Lf i l ef o r m a t e l s ei f( c o n t e n t T y p e . e q u a l s ( " a p p l i c a t i o n / v n d . o p e n x m l f o r m a t s o f f i c e d o c u m e n t . w o r d p r o c e s s i n g m l . d o c u m e n t " ) ){ O P C P a c k a g ed o c P a c k a g e=O P C P a c k a g e . o p e n ( p P a r t . g e t I n p u t S t r e a m ( ) ) ; X W P F D o c u m e n td o c u m e n t=n e wX W P F D o c u m e n t ( d o c P a c k a g e ) ; } / /P o w e r P o i n tD o c u m e n t-b i n a r yf i l ef o r m a t e l s ei f( c o n t e n t T y p e . e q u a l s ( " a p p l i c a t i o n / v n d . m s p o w e r p o i n t " ) ){ H S L F S l i d e S h o ws l i d e S h o w=n e wH S L F S l i d e S h o w ( p P a r t . g e t I n p u t S t r e a m ( ) ) ; } / /P o w e r P o i n tD o c u m e n t-O p e n X M Lf i l ef o r m a t e l s ei f( c o n t e n t T y p e . e q u a l s ( " a p p l i c a t i o n / v n d . o p e n x m l f o r m a t s o f f i c e d o c u m e n t . p r e s e n t a t i o n m l . p r e s e n t a t i o n " ) ){ O P C P a c k a g ed o c P a c k a g e=O P C P a c k a g e . o p e n ( p P a r t . g e t I n p u t S t r e a m ( ) ) ; X S L F S l i d e S h o ws l i d e S h o w=n e wX S L F S l i d e S h o w ( d o c P a c k a g e ) ; } / /A n yo t h e rt y p eo fe m b e d d e do b j e c t . e l s e{ S y s t e m . o u t . p r i n t l n ( " U n k n o w nE m b e d d e dD o c u m e n t :"+c o n t e n t T y p e ) ; I n p u t S t r e a mi n p u t S t r e a m=p P a r t . g e t I n p u t S t r e a m ( ) ; }

Busy Developers' Guide to HSSF and XSSF Features

} (Since POI-3.7) Autofilters W o r k b o o kw b=n e wH S S F W o r k b o o k ( ) ;/ / o rn e wX S S F W o r k b o o k ( ) ; S h e e ts h e e t=w b . c r e a t e S h e e t ( ) ; s h e e t . s e t A u t o F i l t e r ( C e l l R a n g e A d d r e s s . v a l u e O f ( " C 5 : F 2 0 0 " ) ) ;

Conditional Formatting W o r k b o o kw o r k b o o k=n e wH S S F W o r k b o o k ( ) ;/ /o rn e wX S S F W o r k b o o k ( ) ; S h e e ts h e e t=w o r k b o o k . c r e a t e S h e e t ( ) ; S h e e t C o n d i t i o n a l F o r m a t t i n gs h e e t C F=s h e e t . g e t S h e e t C o n d i t i o n a l F o r m a t t i n g ( ) ; C o n d i t i o n a l F o r m a t t i n g R u l er u l e 1=s h e e t C F . c r e a t e C o n d i t i o n a l F o r m a t t i n g R u l e ( C o m p a r i s o n O p e r a t o r . E Q U A L ," 0 " ) ; F o n t F o r m a t t i n gf o n t F m t=r u l e 1 . c r e a t e F o n t F o r m a t t i n g ( ) ; f o n t F m t . s e t F o n t S t y l e ( t r u e ,f a l s e ) ; f o n t F m t . s e t F o n t C o l o r I n d e x ( I n d e x e d C o l o r s . D A R K _ R E D . i n d e x ) ; B o r d e r F o r m a t t i n gb o r d F m t=r u l e 1 . c r e a t e B o r d e r F o r m a t t i n g ( ) ; b o r d F m t . s e t B o r d e r B o t t o m ( B o r d e r F o r m a t t i n g . B O R D E R _ T H I N ) ; b o r d F m t . s e t B o r d e r T o p ( B o r d e r F o r m a t t i n g . B O R D E R _ T H I C K ) ; b o r d F m t . s e t B o r d e r L e f t ( B o r d e r F o r m a t t i n g . B O R D E R _ D A S H E D ) ; b o r d F m t . s e t B o r d e r R i g h t ( B o r d e r F o r m a t t i n g . B O R D E R _ D O T T E D ) ; P a t t e r n F o r m a t t i n gp a t t e r n F m t=r u l e 1 . c r e a t e P a t t e r n F o r m a t t i n g ( ) ; p a t t e r n F m t . s e t F i l l B a c k g r o u n d C o l o r ( I n d e x e d C o l o r s . Y E L L O W . i n d e x ) ; C o n d i t i o n a l F o r m a t t i n g R u l er u l e 2=s h e e t C F . c r e a t e C o n d i t i o n a l F o r m a t t i n g R u l e ( C o m p a r i s o n O p e r a t o r . B E T W E E N ," 1 0 " ," 1 0 " ) ; C o n d i t i o n a l F o r m a t t i n g R u l e[ ]c f R u l e s= { r u l e 1 ,r u l e 2 } ; C e l l R a n g e A d d r e s s [ ]r e g i o n s={ C e l l R a n g e A d d r e s s . v a l u e O f ( " A 3 : A 5 " ) } ; s h e e t C F . a d d C o n d i t i o n a l F o r m a t t i n g ( r e g i o n s ,c f R u l e s ) ; See more examples on Excel conditional formatting in ConditionalFormats.java Hiding and Un-Hiding Rows Using Excel, it is possible to hide a row on a worksheet by selecting that row (or rows), right clicking once on the right hand mouse button and selecting 'Hide' from the pop=up menu that appears. To emulate this using POI, simply call the setZeroHeight() method on an instance of either XSSFRow or HSSFRow (the method is defined on the ss.usermodel.Row interface that both classes implement), like this: W o r k b o o kw o r k b o o k=n e wX S S F W o r k b o o k ( ) ; / /O Rn e wH S S F W o r k b o o k ( ) S h e e ts h e e t=w o r k b o o k . c r e a t e S h e e t ( 0 ) ; R o wr o w=w o r k b o o k . c r e a t e R o w ( 0 ) ; r o w . s e t Z e r o H e i g h t ( ) ; If the file were saved away to disc now, then the first row on the first sheet would not be visible. Using Excel, it is possible to unhide previously hidden rows by selecting the row above and the row below the one that is hidden and then pressing and holding down the Ctrl key, the Shift and the pressing the number 9 before releasing them all.

poi.apache.org/spreadsheet/quick-guide.html#CellContents

22/23

3/25/13

Busy Developers' Guide to HSSF and XSSF Features

pressing and holding down the Ctrl key, the Shift and the pressing the number 9 before releasing them all. To emulate this behaviour using POI do something like this: W o r k b o o kw o r k b o o k=W o r k b o o k F a c t o r y . c r e a t e ( n e wF i l e ( . . . . . . . ) ) ; S h e e t=w o r k b o o k . g e t S h e e t A t ( 0 ) ; I t e r a t o r < R o w >r o wI t e r=s h e e t . i t e r a t o r ( ) ; w h i l e ( r o w I t e r . h a s N e x t ( ) ){ R o wr o w=r o w I t e r . n e x t ( ) ; i f ( r o w . g e t Z e r o H e i g h t ( ) ){ r o w . s e t Z e r o H e i g h t ( f a l s e ) ; } } If the file were saved away to disc now, any previously hidden rows on the first sheet of the workbook would now be visible. The example illustrates two features. Firstly, that it is possible to unhide a row simply by calling the setZeroHeight() method and passing the boolean value 'false'. Secondly, it ilustrates how to test whther a row is hidden or not. Simply call the getZeroHeight() method and it will return 'true' if the row is hidden, 'false' otherwise.

poi.apache.org/spreadsheet/quick-guide.html#CellContents

23/23

Вам также может понравиться