Support for outlining. Enjoy.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/branches/REL_2_BRANCH@353574 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
54082fe268
commit
6a753e13ea
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
|
||||
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
|
||||
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd">
|
||||
|
||||
<document>
|
||||
<header>
|
||||
<title>Busy Developers' Guide to HSSF Features</title>
|
||||
<authors>
|
||||
<person email="glens@apache.org" name="Glen Stampoultzis" id="CO"/>
|
||||
<person email="glens@apache.org" name="Glen Stampoultzis" id="GS"/>
|
||||
</authors>
|
||||
</header>
|
||||
<body>
|
||||
@ -44,6 +44,7 @@
|
||||
<li><link href="#DrawingShapes">Drawing Shapes.</link></li>
|
||||
<li><link href="#StylingShapes">Styling Shapes.</link></li>
|
||||
<li><link href="#Graphics2d">Shapes and Graphics2d.</link></li>
|
||||
<li><link href="#Outlining">Outlining.</link></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section><title>Features</title>
|
||||
@ -902,6 +903,42 @@
|
||||
using the POI logging infrastructure (disabled by default).
|
||||
</p>
|
||||
</section>
|
||||
<anchor id="Outlining"/>
|
||||
<section>
|
||||
<title>Outlining</title>
|
||||
<p>
|
||||
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:
|
||||
</p>
|
||||
<source>
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupRow( 5, 14 );
|
||||
sheet1.groupRow( 7, 14 );
|
||||
sheet1.groupRow( 16, 19 );
|
||||
|
||||
sheet1.groupColumn( (short)4, (short)7 );
|
||||
sheet1.groupColumn( (short)9, (short)12 );
|
||||
sheet1.groupColumn( (short)10, (short)11 );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
</source>
|
||||
<p>
|
||||
To collapse (or expand) an outline use the following calls:
|
||||
</p>
|
||||
<source>
|
||||
sheet1.setRowGroupCollapsed( 7, true );
|
||||
sheet1.setColumnGroupCollapsed( (short)4, true );
|
||||
</source>
|
||||
<p>
|
||||
The row/column you choose should contain an already
|
||||
created group. It can be anywhere within the group.
|
||||
</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</body>
|
||||
|
@ -0,0 +1,284 @@
|
||||
|
||||
/* ====================================================================
|
||||
Copyright 2002-2004 Apache Software Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.usermodel.examples;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Creates outlines.
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class Outlines
|
||||
{
|
||||
private Outlines(){}
|
||||
|
||||
public static void main(String[] args)
|
||||
throws IOException
|
||||
{
|
||||
createCase1( "outline1.xls" );
|
||||
System.out.println( "outline1.xls written. Two expanded groups." );
|
||||
createCase2( "outline2.xls" );
|
||||
System.out.println( "outline2.xls written. Two groups. Inner group collapsed." );
|
||||
createCase3( "outline3.xls" );
|
||||
System.out.println( "outline3.xls written. Two groups. Both collapsed." );
|
||||
createCase4( "outline4.xls" );
|
||||
System.out.println( "outline4.xls written. Two groups. Collapsed then inner group expanded." );
|
||||
createCase5( "outline5.xls" );
|
||||
System.out.println( "outline5.xls written. Two groups. Collapsed then reexpanded." );
|
||||
createCase6( "outline6.xls" );
|
||||
System.out.println( "outline6.xls written. Two groups with matching end points. Second group collapsed." );
|
||||
createCase7( "outline7.xls" );
|
||||
System.out.println( "outline7.xls written. Row outlines." );
|
||||
createCase8( "outline8.xls" );
|
||||
System.out.println( "outline8.xls written. Row outlines. Inner group collapsed." );
|
||||
createCase9( "outline9.xls" );
|
||||
System.out.println( "outline9.xls written. Row outlines. Both collapsed." );
|
||||
createCase10( "outline10.xls" );
|
||||
System.out.println( "outline10.xls written. Row outlines. Collapsed then inner group expanded." );
|
||||
createCase11( "outline11.xls" );
|
||||
System.out.println( "outline11.xls written. Row outlines. Collapsed then expanded." );
|
||||
createCase12( "outline12.xls" );
|
||||
System.out.println( "outline12.xls written. Row outlines. Two row groups with matching end points. Second group collapsed." );
|
||||
createCase13( "outline13.xls" );
|
||||
System.out.println( "outline13.xls written. Mixed bag." );
|
||||
}
|
||||
|
||||
private static void createCase1( String filename ) throws IOException{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupColumn( (short)4, (short)7 );
|
||||
|
||||
for (int row = 0; row < 200; row++)
|
||||
{
|
||||
HSSFRow r = sheet1.createRow( row );
|
||||
for (int column = 0; column < 200; column++)
|
||||
{
|
||||
HSSFCell c = r.createCell( (short) column );
|
||||
c.setCellValue( column );
|
||||
}
|
||||
}
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase2( String filename ) throws IOException{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupColumn( (short)2, (short)10 );
|
||||
sheet1.groupColumn( (short)4, (short)7 );
|
||||
sheet1.setColumnGroupCollapsed( (short)4, true );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase3( String filename ) throws IOException{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupColumn( (short)2, (short)10 );
|
||||
sheet1.groupColumn( (short)4, (short)7 );
|
||||
sheet1.setColumnGroupCollapsed( (short)4, true );
|
||||
sheet1.setColumnGroupCollapsed( (short)2, true );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase4( String filename ) throws IOException{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupColumn( (short)2, (short)10 );
|
||||
sheet1.groupColumn( (short)4, (short)7 );
|
||||
sheet1.setColumnGroupCollapsed( (short)4, true );
|
||||
sheet1.setColumnGroupCollapsed( (short)2, true );
|
||||
|
||||
sheet1.setColumnGroupCollapsed( (short)4, false );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase5( String filename ) throws IOException{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupColumn( (short)2, (short)10 );
|
||||
sheet1.groupColumn( (short)4, (short)7 );
|
||||
sheet1.setColumnGroupCollapsed( (short)4, true );
|
||||
sheet1.setColumnGroupCollapsed( (short)2, true );
|
||||
|
||||
sheet1.setColumnGroupCollapsed( (short)4, false );
|
||||
sheet1.setColumnGroupCollapsed( (short)3, false );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase6( String filename ) throws IOException{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupColumn( (short)2, (short)10 );
|
||||
sheet1.groupColumn( (short)4, (short)10 );
|
||||
sheet1.setColumnGroupCollapsed( (short)4, true );
|
||||
sheet1.setColumnGroupCollapsed( (short)2, true );
|
||||
|
||||
sheet1.setColumnGroupCollapsed( (short)3, false );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase7( String filename )
|
||||
throws IOException
|
||||
{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupRow( 5, 14 );
|
||||
sheet1.groupRow( 7, 10 );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase8( String filename )
|
||||
throws IOException
|
||||
{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupRow( 5, 14 );
|
||||
sheet1.groupRow( 7, 10 );
|
||||
sheet1.setRowGroupCollapsed( 7, true );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase9( String filename )
|
||||
throws IOException
|
||||
{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupRow( 5, 14 );
|
||||
sheet1.groupRow( 7, 10 );
|
||||
sheet1.setRowGroupCollapsed( 7, true );
|
||||
sheet1.setRowGroupCollapsed( 5, true );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
|
||||
private static void createCase10( String filename )
|
||||
throws IOException
|
||||
{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupRow( 5, 14 );
|
||||
sheet1.groupRow( 7, 10 );
|
||||
sheet1.setRowGroupCollapsed( 7, true );
|
||||
sheet1.setRowGroupCollapsed( 5, true );
|
||||
sheet1.setRowGroupCollapsed( 8, false );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase11( String filename )
|
||||
throws IOException
|
||||
{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupRow( 5, 14 );
|
||||
sheet1.groupRow( 7, 10 );
|
||||
sheet1.setRowGroupCollapsed( 7, true );
|
||||
sheet1.setRowGroupCollapsed( 5, true );
|
||||
sheet1.setRowGroupCollapsed( 8, false );
|
||||
sheet1.setRowGroupCollapsed( 14, false );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase12( String filename )
|
||||
throws IOException
|
||||
{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupRow( 5, 14 );
|
||||
sheet1.groupRow( 7, 14 );
|
||||
sheet1.setRowGroupCollapsed( 7, true );
|
||||
sheet1.setRowGroupCollapsed( 5, true );
|
||||
sheet1.setRowGroupCollapsed( 6, false );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
private static void createCase13( String filename )
|
||||
throws IOException
|
||||
{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet("new sheet");
|
||||
|
||||
sheet1.groupRow( 5, 14 );
|
||||
sheet1.groupRow( 7, 14 );
|
||||
sheet1.groupRow( 16, 19 );
|
||||
|
||||
sheet1.groupColumn( (short)4, (short)7 );
|
||||
sheet1.groupColumn( (short)9, (short)12 );
|
||||
sheet1.groupColumn( (short)10, (short)11 );
|
||||
|
||||
FileOutputStream fileOut = new FileOutputStream(filename);
|
||||
wb.write(fileOut);
|
||||
fileOut.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -122,8 +122,9 @@ public class Workbook implements Model
|
||||
* @return Workbook object
|
||||
*/
|
||||
public static Workbook createWorkbook(List recs) {
|
||||
log.log(DEBUG, "Workbook (readfile) created with reclen=",
|
||||
new Integer(recs.size()));
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "Workbook (readfile) created with reclen=",
|
||||
new Integer(recs.size()));
|
||||
Workbook retval = new Workbook();
|
||||
ArrayList records = new ArrayList(recs.size() / 3);
|
||||
|
||||
@ -132,85 +133,100 @@ public class Workbook implements Model
|
||||
|
||||
if (rec.getSid() == EOFRecord.sid) {
|
||||
records.add(rec);
|
||||
log.log(DEBUG, "found workbook eof record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found workbook eof record at " + k);
|
||||
break;
|
||||
}
|
||||
switch (rec.getSid()) {
|
||||
|
||||
case BoundSheetRecord.sid :
|
||||
log.log(DEBUG, "found boundsheet record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found boundsheet record at " + k);
|
||||
retval.boundsheets.add(rec);
|
||||
retval.records.setBspos( k );
|
||||
break;
|
||||
|
||||
case SSTRecord.sid :
|
||||
log.log(DEBUG, "found sst record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found sst record at " + k);
|
||||
retval.sst = ( SSTRecord ) rec;
|
||||
break;
|
||||
|
||||
case FontRecord.sid :
|
||||
log.log(DEBUG, "found font record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found font record at " + k);
|
||||
retval.records.setFontpos( k );
|
||||
retval.numfonts++;
|
||||
break;
|
||||
|
||||
case ExtendedFormatRecord.sid :
|
||||
log.log(DEBUG, "found XF record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found XF record at " + k);
|
||||
retval.records.setXfpos( k );
|
||||
retval.numxfs++;
|
||||
break;
|
||||
|
||||
case TabIdRecord.sid :
|
||||
log.log(DEBUG, "found tabid record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found tabid record at " + k);
|
||||
retval.records.setTabpos( k );
|
||||
break;
|
||||
|
||||
case ProtectRecord.sid :
|
||||
log.log(DEBUG, "found protect record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found protect record at " + k);
|
||||
retval.records.setProtpos( k );
|
||||
break;
|
||||
|
||||
case BackupRecord.sid :
|
||||
log.log(DEBUG, "found backup record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found backup record at " + k);
|
||||
retval.records.setBackuppos( k );
|
||||
break;
|
||||
case ExternSheetRecord.sid :
|
||||
log.log(DEBUG, "found extern sheet record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found extern sheet record at " + k);
|
||||
retval.externSheet = ( ExternSheetRecord ) rec;
|
||||
break;
|
||||
case NameRecord.sid :
|
||||
log.log(DEBUG, "found name record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found name record at " + k);
|
||||
retval.names.add(rec);
|
||||
// retval.records.namepos = k;
|
||||
// retval.records.namepos = k;
|
||||
break;
|
||||
case SupBookRecord.sid :
|
||||
log.log(DEBUG, "found SupBook record at " + k);
|
||||
// retval.records.supbookpos = k;
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found SupBook record at " + k);
|
||||
// retval.records.supbookpos = k;
|
||||
break;
|
||||
case FormatRecord.sid :
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found format record at " + k);
|
||||
retval.formats.add(rec);
|
||||
retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode();
|
||||
break;
|
||||
case FormatRecord.sid :
|
||||
log.log(DEBUG, "found format record at " + k);
|
||||
retval.formats.add(rec);
|
||||
retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode();
|
||||
break;
|
||||
case DateWindow1904Record.sid :
|
||||
log.log(DEBUG, "found datewindow1904 record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found datewindow1904 record at " + k);
|
||||
retval.uses1904datewindowing = ((DateWindow1904Record)rec).getWindowing() == 1;
|
||||
break;
|
||||
case PaletteRecord.sid:
|
||||
log.log(DEBUG, "found palette record at " + k);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "found palette record at " + k);
|
||||
retval.records.setPalettepos( k );
|
||||
default :
|
||||
}
|
||||
records.add(rec);
|
||||
}
|
||||
//What if we dont have any ranges and supbooks
|
||||
// if (retval.records.supbookpos == 0) {
|
||||
// retval.records.supbookpos = retval.records.bspos + 1;
|
||||
// retval.records.namepos = retval.records.supbookpos + 1;
|
||||
// }
|
||||
// if (retval.records.supbookpos == 0) {
|
||||
// retval.records.supbookpos = retval.records.bspos + 1;
|
||||
// retval.records.namepos = retval.records.supbookpos + 1;
|
||||
// }
|
||||
|
||||
retval.records.setRecords(records);
|
||||
log.log(DEBUG, "exit create workbook from existing file function");
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "exit create workbook from existing file function");
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -220,7 +236,8 @@ public class Workbook implements Model
|
||||
*/
|
||||
public static Workbook createWorkbook()
|
||||
{
|
||||
log.log( DEBUG, "creating new workbook from scratch" );
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log( DEBUG, "creating new workbook from scratch" );
|
||||
Workbook retval = new Workbook();
|
||||
ArrayList records = new ArrayList( 30 );
|
||||
ArrayList formats = new ArrayList( 8 );
|
||||
@ -296,7 +313,8 @@ public class Workbook implements Model
|
||||
|
||||
records.add( retval.createEOF() );
|
||||
retval.records.setRecords(records);
|
||||
log.log( DEBUG, "exit create new workbook from scratch" );
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log( DEBUG, "exit create new workbook from scratch" );
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -403,8 +421,9 @@ public class Workbook implements Model
|
||||
*/
|
||||
|
||||
public void setSheetBof(int sheetnum, int pos) {
|
||||
log.log(DEBUG, "setting bof for sheetnum =", new Integer(sheetnum),
|
||||
" at pos=", new Integer(pos));
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "setting bof for sheetnum =", new Integer(sheetnum),
|
||||
" at pos=", new Integer(pos));
|
||||
checkSheets(sheetnum);
|
||||
(( BoundSheetRecord ) boundsheets.get(sheetnum))
|
||||
.setPositionOfBof(pos);
|
||||
@ -535,7 +554,8 @@ public class Workbook implements Model
|
||||
*/
|
||||
|
||||
public int getNumSheets() {
|
||||
log.log(DEBUG, "getNumSheets=", new Integer(boundsheets.size()));
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "getNumSheets=", new Integer(boundsheets.size()));
|
||||
return boundsheets.size();
|
||||
}
|
||||
|
||||
@ -546,7 +566,8 @@ public class Workbook implements Model
|
||||
*/
|
||||
|
||||
public int getNumExFormats() {
|
||||
log.log(DEBUG, "getXF=", new Integer(numxfs));
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "getXF=", new Integer(numxfs));
|
||||
return numxfs;
|
||||
}
|
||||
|
||||
@ -593,7 +614,8 @@ public class Workbook implements Model
|
||||
*/
|
||||
|
||||
public int addSSTString(String string, boolean use16bits) {
|
||||
log.log(DEBUG, "insert to sst string='", string, "' and use16bits= ",
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "insert to sst string='", string, "' and use16bits= ",
|
||||
new Boolean(use16bits));
|
||||
if (sst == null) {
|
||||
insertSST();
|
||||
@ -626,8 +648,9 @@ public class Workbook implements Model
|
||||
}
|
||||
String retval = sst.getString(str);
|
||||
|
||||
log.log(DEBUG, "Returning SST for index=", new Integer(str),
|
||||
" String= ", retval);
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "Returning SST for index=", new Integer(str),
|
||||
" String= ", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -639,7 +662,8 @@ public class Workbook implements Model
|
||||
*/
|
||||
|
||||
public void insertSST() {
|
||||
log.log(DEBUG, "creating new SST via insertSST!");
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "creating new SST via insertSST!");
|
||||
sst = ( SSTRecord ) createSST();
|
||||
records.add(records.size() - 1, createExtendedSST());
|
||||
records.add(records.size() - 2, sst);
|
||||
@ -682,7 +706,8 @@ public class Workbook implements Model
|
||||
|
||||
public int serialize( int offset, byte[] data )
|
||||
{
|
||||
log.log( DEBUG, "Serializing Workbook with offsets" );
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log( DEBUG, "Serializing Workbook with offsets" );
|
||||
|
||||
int pos = 0;
|
||||
|
||||
@ -707,7 +732,8 @@ public class Workbook implements Model
|
||||
pos += record.serialize( pos + offset, data ); // rec.length;
|
||||
}
|
||||
}
|
||||
log.log( DEBUG, "Exiting serialize workbook" );
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log( DEBUG, "Exiting serialize workbook" );
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,509 @@
|
||||
package org.apache.poi.hssf.record.aggregates;
|
||||
|
||||
import org.apache.poi.hssf.record.ColumnInfoRecord;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Glen Stampoultzis
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ColumnInfoRecordsAggregate
|
||||
extends Record
|
||||
{
|
||||
int size = 0;
|
||||
List records = null;
|
||||
|
||||
public ColumnInfoRecordsAggregate()
|
||||
{
|
||||
records = new ArrayList();
|
||||
}
|
||||
|
||||
/** You never fill an aggregate */
|
||||
protected void fillFields(byte [] data, short size, int offset)
|
||||
{
|
||||
}
|
||||
|
||||
/** Not required by an aggregate */
|
||||
protected void validateSid(short id)
|
||||
{
|
||||
}
|
||||
|
||||
/** It's an aggregate... just made something up */
|
||||
public short getSid()
|
||||
{
|
||||
return -1012;
|
||||
}
|
||||
|
||||
public int getRecordSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator getIterator()
|
||||
{
|
||||
return records.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a deep clone of the record
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
ColumnInfoRecordsAggregate rec = new ColumnInfoRecordsAggregate();
|
||||
for ( Iterator colIter = getIterator(); colIter.hasNext(); )
|
||||
{
|
||||
//return the cloned Row Record & insert
|
||||
ColumnInfoRecord col = (ColumnInfoRecord) ( (ColumnInfoRecord) colIter.next() ).clone();
|
||||
rec.insertColumn( col );
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a column into the aggregate (at the end of the list).
|
||||
*/
|
||||
public void insertColumn( ColumnInfoRecord col )
|
||||
{
|
||||
size += col.getRecordSize();
|
||||
records.add( col );
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a column into the aggregate (at the position specified
|
||||
* by <code>idx</code>.
|
||||
*/
|
||||
public void insertColumn( int idx, ColumnInfoRecord col )
|
||||
{
|
||||
size += col.getRecordSize();
|
||||
records.add( idx, col );
|
||||
}
|
||||
|
||||
public int getNumColumns( )
|
||||
{
|
||||
return records.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* called by the class that is responsible for writing this sucker.
|
||||
* Subclasses should implement this so that their data is passed back in a
|
||||
* byte array.
|
||||
*
|
||||
* @param offset offset to begin writing at
|
||||
* @param data byte array containing instance data
|
||||
* @return number of bytes written
|
||||
*/
|
||||
public int serialize(int offset, byte [] data)
|
||||
{
|
||||
Iterator itr = records.iterator();
|
||||
int pos = offset;
|
||||
|
||||
while (itr.hasNext())
|
||||
{
|
||||
pos += (( Record ) itr.next()).serialize(pos, data);
|
||||
}
|
||||
return pos - offset;
|
||||
}
|
||||
|
||||
public int findStartOfColumnOutlineGroup(int idx)
|
||||
{
|
||||
// Find the start of the group.
|
||||
ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( idx );
|
||||
int level = columnInfo.getOutlineLevel();
|
||||
while (idx != 0)
|
||||
{
|
||||
ColumnInfoRecord prevColumnInfo = (ColumnInfoRecord) records.get( idx - 1 );
|
||||
if (columnInfo.getFirstColumn() - 1 == prevColumnInfo.getLastColumn())
|
||||
{
|
||||
if (prevColumnInfo.getOutlineLevel() < level)
|
||||
{
|
||||
break;
|
||||
}
|
||||
idx--;
|
||||
columnInfo = prevColumnInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
public int findEndOfColumnOutlineGroup(int idx)
|
||||
{
|
||||
// Find the end of the group.
|
||||
ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( idx );
|
||||
int level = columnInfo.getOutlineLevel();
|
||||
while (idx < records.size() - 1)
|
||||
{
|
||||
ColumnInfoRecord nextColumnInfo = (ColumnInfoRecord) records.get( idx + 1 );
|
||||
if (columnInfo.getLastColumn() + 1 == nextColumnInfo.getFirstColumn())
|
||||
{
|
||||
if (nextColumnInfo.getOutlineLevel() < level)
|
||||
{
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
columnInfo = nextColumnInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
public ColumnInfoRecord getColInfo(int idx)
|
||||
{
|
||||
return (ColumnInfoRecord) records.get( idx );
|
||||
}
|
||||
|
||||
public ColumnInfoRecord writeHidden( ColumnInfoRecord columnInfo, int idx, boolean hidden )
|
||||
{
|
||||
int level = columnInfo.getOutlineLevel();
|
||||
while (idx < records.size())
|
||||
{
|
||||
columnInfo.setHidden( hidden );
|
||||
if (idx + 1 < records.size())
|
||||
{
|
||||
ColumnInfoRecord nextColumnInfo = (ColumnInfoRecord) records.get( idx + 1 );
|
||||
if (columnInfo.getLastColumn() + 1 == nextColumnInfo.getFirstColumn())
|
||||
{
|
||||
if (nextColumnInfo.getOutlineLevel() < level)
|
||||
break;
|
||||
columnInfo = nextColumnInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
return columnInfo;
|
||||
}
|
||||
|
||||
public boolean isColumnGroupCollapsed( int idx )
|
||||
{
|
||||
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx );
|
||||
if (endOfOutlineGroupIdx >= records.size())
|
||||
return false;
|
||||
if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn())
|
||||
return false;
|
||||
else
|
||||
return getColInfo(endOfOutlineGroupIdx+1).getCollapsed();
|
||||
}
|
||||
|
||||
|
||||
public boolean isColumnGroupHiddenByParent( int idx )
|
||||
{
|
||||
// Look out outline details of end
|
||||
int endLevel;
|
||||
boolean endHidden;
|
||||
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx );
|
||||
if (endOfOutlineGroupIdx >= records.size())
|
||||
{
|
||||
endLevel = 0;
|
||||
endHidden = false;
|
||||
}
|
||||
else if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn())
|
||||
{
|
||||
endLevel = 0;
|
||||
endHidden = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
endLevel = getColInfo( endOfOutlineGroupIdx + 1).getOutlineLevel();
|
||||
endHidden = getColInfo( endOfOutlineGroupIdx + 1).getHidden();
|
||||
}
|
||||
|
||||
// Look out outline details of start
|
||||
int startLevel;
|
||||
boolean startHidden;
|
||||
int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx );
|
||||
if (startOfOutlineGroupIdx <= 0)
|
||||
{
|
||||
startLevel = 0;
|
||||
startHidden = false;
|
||||
}
|
||||
else if (getColInfo(startOfOutlineGroupIdx).getFirstColumn() - 1 != getColInfo(startOfOutlineGroupIdx - 1).getLastColumn())
|
||||
{
|
||||
startLevel = 0;
|
||||
startHidden = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
startLevel = getColInfo( startOfOutlineGroupIdx - 1).getOutlineLevel();
|
||||
startHidden = getColInfo( startOfOutlineGroupIdx - 1 ).getHidden();
|
||||
}
|
||||
|
||||
if (endLevel > startLevel)
|
||||
{
|
||||
return endHidden;
|
||||
}
|
||||
else
|
||||
{
|
||||
return startHidden;
|
||||
}
|
||||
}
|
||||
|
||||
public void collapseColumn( short columnNumber )
|
||||
{
|
||||
int idx = findColumnIdx( columnNumber, 0 );
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
// Find the start of the group.
|
||||
ColumnInfoRecord columnInfo = (ColumnInfoRecord) records.get( findStartOfColumnOutlineGroup( idx ) );
|
||||
|
||||
// Hide all the columns until the end of the group
|
||||
columnInfo = writeHidden( columnInfo, idx, true );
|
||||
|
||||
// Write collapse field
|
||||
setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.TRUE);
|
||||
}
|
||||
|
||||
public void expandColumn( short columnNumber )
|
||||
{
|
||||
int idx = findColumnIdx( columnNumber, 0 );
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
// If it is already exapanded do nothing.
|
||||
if (!isColumnGroupCollapsed(idx))
|
||||
return;
|
||||
|
||||
// Find the start of the group.
|
||||
int startIdx = findStartOfColumnOutlineGroup( idx );
|
||||
ColumnInfoRecord columnInfo = getColInfo( startIdx );
|
||||
|
||||
// Find the end of the group.
|
||||
int endIdx = findEndOfColumnOutlineGroup( idx );
|
||||
ColumnInfoRecord endColumnInfo = getColInfo( endIdx );
|
||||
|
||||
// expand:
|
||||
// colapsed bit must be unset
|
||||
// hidden bit gets unset _if_ surrounding groups are expanded you can determine
|
||||
// this by looking at the hidden bit of the enclosing group. You will have
|
||||
// to look at the start and the end of the current group to determine which
|
||||
// is the enclosing group
|
||||
// hidden bit only is altered for this outline level. ie. don't uncollapse contained groups
|
||||
if (!isColumnGroupHiddenByParent( idx ))
|
||||
{
|
||||
for (int i = startIdx; i <= endIdx; i++)
|
||||
{
|
||||
if (columnInfo.getOutlineLevel() == getColInfo(i).getOutlineLevel())
|
||||
getColInfo(i).setHidden( false );
|
||||
}
|
||||
}
|
||||
|
||||
// Write collapse field
|
||||
setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the ColumnInfo Record and sets it to a default column/width
|
||||
* @see org.apache.poi.hssf.record.ColumnInfoRecord
|
||||
* @return record containing a ColumnInfoRecord
|
||||
*/
|
||||
public static Record createColInfo()
|
||||
{
|
||||
ColumnInfoRecord retval = new ColumnInfoRecord();
|
||||
|
||||
retval.setColumnWidth(( short ) 2275);
|
||||
// was: retval.setOptions(( short ) 6);
|
||||
retval.setOptions(( short ) 2);
|
||||
retval.setXFIndex(( short ) 0x0f);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
public void setColumn(short column, Short width, Integer level, Boolean hidden, Boolean collapsed)
|
||||
{
|
||||
ColumnInfoRecord ci = null;
|
||||
int k = 0;
|
||||
|
||||
for (k = 0; k < records.size(); k++)
|
||||
{
|
||||
ci = ( ColumnInfoRecord ) records.get(k);
|
||||
if ((ci.getFirstColumn() <= column)
|
||||
&& (column <= ci.getLastColumn()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
ci = null;
|
||||
}
|
||||
|
||||
if (ci != null)
|
||||
{
|
||||
boolean widthChanged = width != null && ci.getColumnWidth() != width.shortValue();
|
||||
boolean levelChanged = level != null && ci.getOutlineLevel() != level.intValue();
|
||||
boolean hiddenChanged = hidden != null && ci.getHidden() != hidden.booleanValue();
|
||||
boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed.booleanValue();
|
||||
boolean columnChanged = widthChanged || levelChanged || hiddenChanged || collapsedChanged;
|
||||
if (!columnChanged)
|
||||
{
|
||||
// do nothing...nothing changed.
|
||||
}
|
||||
else if ((ci.getFirstColumn() == column)
|
||||
&& (ci.getLastColumn() == column))
|
||||
{ // if its only for this cell then
|
||||
setColumnInfoFields( ci, width, level, hidden, collapsed );
|
||||
}
|
||||
else if ((ci.getFirstColumn() == column)
|
||||
|| (ci.getLastColumn() == column))
|
||||
{
|
||||
// okay so the width is different but the first or last column == the column we'return setting
|
||||
// we'll just divide the info and create a new one
|
||||
if (ci.getFirstColumn() == column)
|
||||
{
|
||||
ci.setFirstColumn(( short ) (column + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
ci.setLastColumn(( short ) (column - 1));
|
||||
}
|
||||
ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();
|
||||
|
||||
nci.setFirstColumn(column);
|
||||
nci.setLastColumn(column);
|
||||
nci.setOptions(ci.getOptions());
|
||||
nci.setXFIndex(ci.getXFIndex());
|
||||
setColumnInfoFields( nci, width, level, hidden, collapsed );
|
||||
|
||||
insertColumn(k, nci);
|
||||
}
|
||||
else
|
||||
{
|
||||
//split to 3 records
|
||||
short lastcolumn = ci.getLastColumn();
|
||||
ci.setLastColumn(( short ) (column - 1));
|
||||
|
||||
ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();
|
||||
nci.setFirstColumn(column);
|
||||
nci.setLastColumn(column);
|
||||
nci.setOptions(ci.getOptions());
|
||||
nci.setXFIndex(ci.getXFIndex());
|
||||
setColumnInfoFields( nci, width, level, hidden, collapsed );
|
||||
insertColumn(++k, nci);
|
||||
|
||||
nci = ( ColumnInfoRecord ) createColInfo();
|
||||
nci.setFirstColumn((short)(column+1));
|
||||
nci.setLastColumn(lastcolumn);
|
||||
nci.setOptions(ci.getOptions());
|
||||
nci.setXFIndex(ci.getXFIndex());
|
||||
nci.setColumnWidth(ci.getColumnWidth());
|
||||
insertColumn(++k, nci);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// okay so there ISN'T a column info record that cover's this column so lets create one!
|
||||
ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();
|
||||
|
||||
nci.setFirstColumn(column);
|
||||
nci.setLastColumn(column);
|
||||
setColumnInfoFields( nci, width, level, hidden, collapsed );
|
||||
insertColumn(k, nci);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all non null fields into the <code>ci</code> parameter.
|
||||
*/
|
||||
private void setColumnInfoFields( ColumnInfoRecord ci, Short width, Integer level, Boolean hidden, Boolean collapsed )
|
||||
{
|
||||
if (width != null)
|
||||
ci.setColumnWidth(width.shortValue());
|
||||
if (level != null)
|
||||
ci.setOutlineLevel( level.shortValue() );
|
||||
if (hidden != null)
|
||||
ci.setHidden( hidden.booleanValue() );
|
||||
if (collapsed != null)
|
||||
ci.setCollapsed( collapsed.booleanValue() );
|
||||
}
|
||||
|
||||
public int findColumnIdx(int column, int fromIdx)
|
||||
{
|
||||
if (column < 0)
|
||||
throw new IllegalArgumentException( "column parameter out of range: " + column );
|
||||
if (fromIdx < 0)
|
||||
throw new IllegalArgumentException( "fromIdx parameter out of range: " + fromIdx );
|
||||
|
||||
ColumnInfoRecord ci;
|
||||
for (int k = fromIdx; k < records.size(); k++)
|
||||
{
|
||||
ci = ( ColumnInfoRecord ) records.get(k);
|
||||
if ((ci.getFirstColumn() <= column)
|
||||
&& (column <= ci.getLastColumn()))
|
||||
{
|
||||
return k;
|
||||
}
|
||||
ci = null;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void collapseColInfoRecords( int columnIdx )
|
||||
{
|
||||
if (columnIdx == 0)
|
||||
return;
|
||||
ColumnInfoRecord previousCol = (ColumnInfoRecord) records.get( columnIdx - 1);
|
||||
ColumnInfoRecord currentCol = (ColumnInfoRecord) records.get( columnIdx );
|
||||
boolean adjacentColumns = previousCol.getLastColumn() == currentCol.getFirstColumn() - 1;
|
||||
if (!adjacentColumns)
|
||||
return;
|
||||
|
||||
boolean columnsMatch =
|
||||
previousCol.getXFIndex() == currentCol.getXFIndex() &&
|
||||
previousCol.getOptions() == currentCol.getOptions() &&
|
||||
previousCol.getColumnWidth() == currentCol.getColumnWidth();
|
||||
|
||||
if (columnsMatch)
|
||||
{
|
||||
previousCol.setLastColumn( currentCol.getLastColumn() );
|
||||
records.remove( columnIdx );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an outline group for the specified columns.
|
||||
* @param fromColumn group from this column (inclusive)
|
||||
* @param toColumn group to this column (inclusive)
|
||||
* @param indent if true the group will be indented by one level,
|
||||
* if false indenting will be removed by one level.
|
||||
*/
|
||||
public void groupColumnRange(short fromColumn, short toColumn, boolean indent)
|
||||
{
|
||||
|
||||
// Set the level for each column
|
||||
int fromIdx = 0;
|
||||
for (int i = fromColumn; i <= toColumn; i++)
|
||||
{
|
||||
int level = 1;
|
||||
int columnIdx = findColumnIdx( i, Math.max(0,fromIdx) );
|
||||
if (columnIdx != -1)
|
||||
{
|
||||
level = ((ColumnInfoRecord)records.get( columnIdx )).getOutlineLevel();
|
||||
if (indent) level++; else level--;
|
||||
level = Math.max(0, level);
|
||||
level = Math.min(7, level);
|
||||
fromIdx = columnIdx - 1; // subtract 1 just in case this column is collapsed later.
|
||||
}
|
||||
setColumn((short)i, null, new Integer(level), null, null);
|
||||
columnIdx = findColumnIdx( i, Math.max(0, fromIdx ) );
|
||||
collapseColInfoRecords( columnIdx );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -20,12 +20,10 @@ package org.apache.poi.hssf.record.aggregates;
|
||||
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.RowRecord;
|
||||
import org.apache.poi.hssf.record.UnknownRecord;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -46,7 +44,6 @@ public class RowRecordsAggregate
|
||||
public RowRecordsAggregate()
|
||||
{
|
||||
records = new TreeMap();
|
||||
|
||||
}
|
||||
|
||||
public void insertRow(RowRecord row)
|
||||
@ -121,6 +118,7 @@ public class RowRecordsAggregate
|
||||
return k;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* called by the class that is responsible for writing this sucker.
|
||||
* Subclasses should implement this so that their data is passed back in a
|
||||
@ -186,15 +184,198 @@ public class RowRecordsAggregate
|
||||
return records.values().iterator();
|
||||
}
|
||||
|
||||
/** Performs a deep clone of the record*/
|
||||
public Object clone() {
|
||||
RowRecordsAggregate rec = new RowRecordsAggregate();
|
||||
for (Iterator rowIter = getIterator(); rowIter.hasNext();) {
|
||||
//return the cloned Row Record & insert
|
||||
RowRecord row = (RowRecord)((RowRecord)rowIter.next()).clone();
|
||||
rec.insertRow(row);
|
||||
}
|
||||
return rec;
|
||||
/**
|
||||
* Performs a deep clone of the record
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
RowRecordsAggregate rec = new RowRecordsAggregate();
|
||||
for ( Iterator rowIter = getIterator(); rowIter.hasNext(); )
|
||||
{
|
||||
//return the cloned Row Record & insert
|
||||
RowRecord row = (RowRecord) ( (RowRecord) rowIter.next() ).clone();
|
||||
rec.insertRow( row );
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
|
||||
public int findStartOfRowOutlineGroup(int row)
|
||||
{
|
||||
// Find the start of the group.
|
||||
RowRecord rowRecord = this.getRow( row );
|
||||
int level = rowRecord.getOutlineLevel();
|
||||
int currentRow = row;
|
||||
while (this.getRow( currentRow ) != null)
|
||||
{
|
||||
rowRecord = this.getRow( currentRow );
|
||||
if (rowRecord.getOutlineLevel() < level)
|
||||
return currentRow + 1;
|
||||
currentRow--;
|
||||
}
|
||||
|
||||
return currentRow + 1;
|
||||
}
|
||||
|
||||
public int findEndOfRowOutlineGroup( int row )
|
||||
{
|
||||
int level = getRow( row ).getOutlineLevel();
|
||||
int currentRow;
|
||||
for (currentRow = row; currentRow < this.getLastRowNum(); currentRow++)
|
||||
{
|
||||
if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return currentRow-1;
|
||||
}
|
||||
|
||||
public int writeHidden( RowRecord rowRecord, int row, boolean hidden )
|
||||
{
|
||||
int level = rowRecord.getOutlineLevel();
|
||||
while (rowRecord != null && this.getRow(row).getOutlineLevel() >= level)
|
||||
{
|
||||
rowRecord.setZeroHeight( hidden );
|
||||
row++;
|
||||
rowRecord = this.getRow( row );
|
||||
}
|
||||
return row - 1;
|
||||
}
|
||||
|
||||
public void collapseRow( int rowNumber )
|
||||
{
|
||||
|
||||
// Find the start of the group.
|
||||
int startRow = findStartOfRowOutlineGroup( rowNumber );
|
||||
RowRecord rowRecord = (RowRecord) getRow( startRow );
|
||||
|
||||
// Hide all the columns until the end of the group
|
||||
int lastRow = writeHidden( rowRecord, startRow, true );
|
||||
|
||||
// Write collapse field
|
||||
if (getRow(lastRow + 1) != null)
|
||||
{
|
||||
getRow(lastRow + 1).setColapsed( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
RowRecord row = createRow( lastRow + 1);
|
||||
row.setColapsed( true );
|
||||
insertRow( row );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a row record.
|
||||
*
|
||||
* @param row number
|
||||
* @return RowRecord created for the passed in row number
|
||||
* @see org.apache.poi.hssf.record.RowRecord
|
||||
*/
|
||||
public static RowRecord createRow(int row)
|
||||
{
|
||||
RowRecord rowrec = new RowRecord();
|
||||
|
||||
//rowrec.setRowNumber(( short ) row);
|
||||
rowrec.setRowNumber(row);
|
||||
rowrec.setHeight(( short ) 0xff);
|
||||
rowrec.setOptimize(( short ) 0x0);
|
||||
rowrec.setOptionFlags(( short ) 0x100); // seems necessary for outlining
|
||||
rowrec.setXFIndex(( short ) 0xf);
|
||||
return rowrec;
|
||||
}
|
||||
|
||||
public boolean isRowGroupCollapsed( int row )
|
||||
{
|
||||
int collapseRow = findEndOfRowOutlineGroup( row ) + 1;
|
||||
|
||||
if (getRow(collapseRow) == null)
|
||||
return false;
|
||||
else
|
||||
return getRow( collapseRow ).getColapsed();
|
||||
}
|
||||
|
||||
public void expandRow( int rowNumber )
|
||||
{
|
||||
int idx = rowNumber;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
// If it is already expanded do nothing.
|
||||
if (!isRowGroupCollapsed(idx))
|
||||
return;
|
||||
|
||||
// Find the start of the group.
|
||||
int startIdx = findStartOfRowOutlineGroup( idx );
|
||||
RowRecord row = getRow( startIdx );
|
||||
|
||||
// Find the end of the group.
|
||||
int endIdx = findEndOfRowOutlineGroup( idx );
|
||||
|
||||
// expand:
|
||||
// colapsed bit must be unset
|
||||
// hidden bit gets unset _if_ surrounding groups are expanded you can determine
|
||||
// this by looking at the hidden bit of the enclosing group. You will have
|
||||
// to look at the start and the end of the current group to determine which
|
||||
// is the enclosing group
|
||||
// hidden bit only is altered for this outline level. ie. don't uncollapse contained groups
|
||||
if ( !isRowGroupHiddenByParent( idx ) )
|
||||
{
|
||||
for ( int i = startIdx; i <= endIdx; i++ )
|
||||
{
|
||||
if ( row.getOutlineLevel() == getRow( i ).getOutlineLevel() )
|
||||
getRow( i ).setZeroHeight( false );
|
||||
else if (!isRowGroupCollapsed(i))
|
||||
getRow( i ).setZeroHeight( false );
|
||||
}
|
||||
}
|
||||
|
||||
// Write collapse field
|
||||
getRow( endIdx + 1 ).setColapsed( false );
|
||||
}
|
||||
|
||||
public boolean isRowGroupHiddenByParent( int row )
|
||||
{
|
||||
// Look out outline details of end
|
||||
int endLevel;
|
||||
boolean endHidden;
|
||||
int endOfOutlineGroupIdx = findEndOfRowOutlineGroup( row );
|
||||
if (getRow( endOfOutlineGroupIdx + 1 ) == null)
|
||||
{
|
||||
endLevel = 0;
|
||||
endHidden = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
endLevel = getRow( endOfOutlineGroupIdx + 1).getOutlineLevel();
|
||||
endHidden = getRow( endOfOutlineGroupIdx + 1).getZeroHeight();
|
||||
}
|
||||
|
||||
// Look out outline details of start
|
||||
int startLevel;
|
||||
boolean startHidden;
|
||||
int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row );
|
||||
if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null)
|
||||
{
|
||||
startLevel = 0;
|
||||
startHidden = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
startLevel = getRow( startOfOutlineGroupIdx - 1).getOutlineLevel();
|
||||
startHidden = getRow( startOfOutlineGroupIdx - 1 ).getZeroHeight();
|
||||
}
|
||||
|
||||
if (endLevel > startLevel)
|
||||
{
|
||||
return endHidden;
|
||||
}
|
||||
else
|
||||
{
|
||||
return startHidden;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -132,12 +132,14 @@ public class EscherGraphics
|
||||
|
||||
public void clipRect(int x, int y, int width, int height)
|
||||
{
|
||||
logger.log(POILogger.WARN,"clipRect not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"clipRect not supported");
|
||||
}
|
||||
|
||||
public void copyArea(int x, int y, int width, int height, int dx, int dy)
|
||||
{
|
||||
logger.log(POILogger.WARN,"copyArea not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"copyArea not supported");
|
||||
}
|
||||
|
||||
public Graphics create()
|
||||
@ -154,7 +156,8 @@ public class EscherGraphics
|
||||
public void drawArc(int x, int y, int width, int height,
|
||||
int startAngle, int arcAngle)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawArc not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawArc not supported");
|
||||
}
|
||||
|
||||
public boolean drawImage(Image img,
|
||||
@ -163,7 +166,8 @@ public class EscherGraphics
|
||||
Color bgcolor,
|
||||
ImageObserver observer)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawImage not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawImage not supported");
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -173,7 +177,8 @@ public class EscherGraphics
|
||||
int sx1, int sy1, int sx2, int sy2,
|
||||
ImageObserver observer)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawImage not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawImage not supported");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -240,18 +245,21 @@ public class EscherGraphics
|
||||
public void drawPolyline(int xPoints[], int yPoints[],
|
||||
int nPoints)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawPolyline not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawPolyline not supported");
|
||||
}
|
||||
|
||||
public void drawRect(int x, int y, int width, int height)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawRect not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawRect not supported");
|
||||
}
|
||||
|
||||
public void drawRoundRect(int x, int y, int width, int height,
|
||||
int arcWidth, int arcHeight)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawRoundRect not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawRoundRect not supported");
|
||||
}
|
||||
|
||||
public void drawString(String str, int x, int y)
|
||||
@ -317,13 +325,15 @@ public class EscherGraphics
|
||||
public void drawString(AttributedCharacterIterator iterator,
|
||||
int x, int y)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawString not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawString not supported");
|
||||
}
|
||||
|
||||
public void fillArc(int x, int y, int width, int height,
|
||||
int startAngle, int arcAngle)
|
||||
{
|
||||
logger.log(POILogger.WARN,"fillArc not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"fillArc not supported");
|
||||
}
|
||||
|
||||
public void fillOval(int x, int y, int width, int height)
|
||||
@ -383,7 +393,8 @@ public class EscherGraphics
|
||||
public void fillRoundRect(int x, int y, int width, int height,
|
||||
int arcWidth, int arcHeight)
|
||||
{
|
||||
logger.log(POILogger.WARN,"fillRoundRect not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"fillRoundRect not supported");
|
||||
}
|
||||
|
||||
public Shape getClip()
|
||||
@ -438,17 +449,20 @@ public class EscherGraphics
|
||||
|
||||
public void setPaintMode()
|
||||
{
|
||||
logger.log(POILogger.WARN,"setPaintMode not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"setPaintMode not supported");
|
||||
}
|
||||
|
||||
public void setXORMode(Color color)
|
||||
{
|
||||
logger.log(POILogger.WARN,"setXORMode not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"setXORMode not supported");
|
||||
}
|
||||
|
||||
public void translate(int x, int y)
|
||||
{
|
||||
logger.log(POILogger.WARN,"translate not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"translate not supported");
|
||||
}
|
||||
|
||||
public Color getBackground()
|
||||
|
@ -141,7 +141,8 @@ public class EscherGraphics2d extends Graphics2D
|
||||
|
||||
public void draw(Shape shape)
|
||||
{
|
||||
logger.log(POILogger.WARN,"copyArea not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"copyArea not supported");
|
||||
}
|
||||
|
||||
public void drawArc(int x, int y, int width, int height,
|
||||
@ -158,19 +159,22 @@ public class EscherGraphics2d extends Graphics2D
|
||||
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
|
||||
int sx2, int sy2, Color bgColor, ImageObserver imageobserver)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawImage() not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawImage() not supported");
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
|
||||
int sx2, int sy2, ImageObserver imageobserver)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawImage() not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawImage() not supported");
|
||||
return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, imageobserver);
|
||||
}
|
||||
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, Color bgColor, ImageObserver imageobserver)
|
||||
{
|
||||
logger.log(POILogger.WARN,"drawImage() not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"drawImage() not supported");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -285,7 +289,8 @@ public class EscherGraphics2d extends Graphics2D
|
||||
|
||||
public void fill(Shape shape)
|
||||
{
|
||||
logger.log(POILogger.WARN,"fill(Shape) not supported");
|
||||
if (logger.check( POILogger.WARN ))
|
||||
logger.log(POILogger.WARN,"fill(Shape) not supported");
|
||||
}
|
||||
|
||||
public void fillArc(int i, int j, int k, int l, int i1, int j1)
|
||||
|
@ -89,6 +89,7 @@ public class HSSFRow
|
||||
this.book = book;
|
||||
this.sheet = sheet;
|
||||
row = new RowRecord();
|
||||
row.setOptionFlags( (short)0x100 ); // seems necessary for outlining to work.
|
||||
row.setHeight((short) 0xff);
|
||||
row.setLastCol((short) -1);
|
||||
row.setFirstCol((short) -1);
|
||||
|
@ -134,7 +134,8 @@ public class HSSFSheet
|
||||
CellValueRecordInterface cval = sheet.getNextValueRecord();
|
||||
long timestart = System.currentTimeMillis();
|
||||
|
||||
log.log(DEBUG, "Time at start of cell creating in HSSF sheet = ",
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "Time at start of cell creating in HSSF sheet = ",
|
||||
new Long(timestart));
|
||||
HSSFRow lastrow = null;
|
||||
|
||||
@ -150,10 +151,12 @@ public class HSSFSheet
|
||||
if ( hrow != null )
|
||||
{
|
||||
lastrow = hrow;
|
||||
log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) );
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) );
|
||||
hrow.createCellFromRecord( cval );
|
||||
cval = sheet.getNextValueRecord();
|
||||
log.log( DEBUG, "record took ",
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log( DEBUG, "record took ",
|
||||
new Long( System.currentTimeMillis() - cellstart ) );
|
||||
}
|
||||
else
|
||||
@ -161,7 +164,8 @@ public class HSSFSheet
|
||||
cval = null;
|
||||
}
|
||||
}
|
||||
log.log(DEBUG, "total sheet cell creation took ",
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "total sheet cell creation took ",
|
||||
new Long(System.currentTimeMillis() - timestart));
|
||||
}
|
||||
|
||||
@ -173,8 +177,6 @@ public class HSSFSheet
|
||||
* @see org.apache.poi.hssf.usermodel.HSSFRow
|
||||
* @see #removeRow(HSSFRow)
|
||||
*/
|
||||
|
||||
//public HSSFRow createRow(short rownum)
|
||||
public HSSFRow createRow(int rownum)
|
||||
{
|
||||
HSSFRow row = new HSSFRow(book, sheet, rownum);
|
||||
@ -1251,6 +1253,47 @@ public class HSSFSheet
|
||||
return patriarch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands or collapses a column group.
|
||||
*
|
||||
* @param columnNumber One of the columns in the group.
|
||||
* @param collapsed true = collapse group, false = expand group.
|
||||
*/
|
||||
public void setColumnGroupCollapsed( short columnNumber, boolean collapsed )
|
||||
{
|
||||
sheet.setColumnGroupCollapsed( columnNumber, collapsed );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an outline for the provided column range.
|
||||
*
|
||||
* @param fromColumn beginning of the column range.
|
||||
* @param toColumn end of the column range.
|
||||
*/
|
||||
public void groupColumn(short fromColumn, short toColumn)
|
||||
{
|
||||
sheet.groupColumnRange( fromColumn, toColumn, true );
|
||||
}
|
||||
|
||||
public void ungroupColumn( short fromColumn, short toColumn )
|
||||
{
|
||||
sheet.groupColumnRange( fromColumn, toColumn, false );
|
||||
}
|
||||
|
||||
public void groupRow(int fromRow, int toRow)
|
||||
{
|
||||
sheet.groupRowRange( fromRow, toRow, true );
|
||||
}
|
||||
|
||||
public void ungroupRow(int fromRow, int toRow)
|
||||
{
|
||||
sheet.groupRowRange( fromRow, toRow, false );
|
||||
}
|
||||
|
||||
public void setRowGroupCollapsed( int row, boolean collapse )
|
||||
{
|
||||
sheet.setRowGroupCollapsed( row, collapse );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -46,8 +46,6 @@ import org.apache.poi.poifs.filesystem.Entry;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.ddf.*;
|
||||
|
||||
/**
|
||||
* High level representation of a workbook. This is the first object most users
|
||||
@ -759,7 +757,8 @@ public class HSSFWorkbook
|
||||
|
||||
public byte[] getBytes()
|
||||
{
|
||||
log.log(DEBUG, "HSSFWorkbook.getBytes()");
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(DEBUG, "HSSFWorkbook.getBytes()");
|
||||
|
||||
// before getting the workbook size we must tell the sheets that
|
||||
// serialization is about to occur.
|
||||
|
@ -42,7 +42,6 @@ public abstract class POILogger
|
||||
* package scope so it cannot be instantiated outside of the util
|
||||
* package. You need a POILogger? Go to the POILogFactory for one
|
||||
*
|
||||
* @param log the object that does the real work of logging
|
||||
*/
|
||||
POILogger()
|
||||
{}
|
||||
@ -55,7 +54,6 @@ public abstract class POILogger
|
||||
* Check if a logger is enabled to log at the specified level
|
||||
*
|
||||
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
|
||||
* @param obj1 The logger to check.
|
||||
*/
|
||||
abstract public boolean check(final int level);
|
||||
|
||||
|
58
src/testcases/org/apache/poi/hssf/model/TestSheet.java
Normal file
58
src/testcases/org/apache/poi/hssf/model/TestSheet.java
Normal file
@ -0,0 +1,58 @@
|
||||
|
||||
/* ====================================================================
|
||||
Copyright 2002-2004 Apache Software Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.record.BOFRecord;
|
||||
import org.apache.poi.hssf.record.EOFRecord;
|
||||
import org.apache.poi.hssf.record.DimensionsRecord;
|
||||
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Unit test for the Sheet class.
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class TestSheet extends TestCase
|
||||
{
|
||||
public void testCreateSheet() throws Exception
|
||||
{
|
||||
// Check we're adding row and cell aggregates
|
||||
List records = new ArrayList();
|
||||
records.add( new BOFRecord() );
|
||||
records.add( new DimensionsRecord() );
|
||||
records.add( new EOFRecord() );
|
||||
Sheet sheet = Sheet.createSheet( records, 0, 0 );
|
||||
|
||||
int pos = 0;
|
||||
assertTrue( sheet.records.get(pos++) instanceof BOFRecord );
|
||||
assertTrue( sheet.records.get(pos++) instanceof ColumnInfoRecordsAggregate );
|
||||
assertTrue( sheet.records.get(pos++) instanceof DimensionsRecord );
|
||||
assertTrue( sheet.records.get(pos++) instanceof RowRecordsAggregate );
|
||||
assertTrue( sheet.records.get(pos++) instanceof ValueRecordsAggregate );
|
||||
assertTrue( sheet.records.get(pos++) instanceof EOFRecord );
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user