Cell Style optimisations too
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@677057 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b2edbb5332
commit
58f0fc9eaf
@ -713,6 +713,18 @@ public class Workbook implements Model
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given ExtendedFormatRecord record from the
|
||||
* file's list. This will make all
|
||||
* subsequent font indicies drop by one,
|
||||
* so you'll need to update those yourself!
|
||||
*/
|
||||
public void removeExFormatRecord(ExtendedFormatRecord rec) {
|
||||
records.remove(rec); // this updates XfPos for us
|
||||
numxfs--;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* creates a new Cell-type Extneded Format Record and adds it to the end of
|
||||
|
@ -927,14 +927,13 @@ public class HSSFCell
|
||||
* object.
|
||||
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
|
||||
*/
|
||||
|
||||
public HSSFCellStyle getCellStyle()
|
||||
{
|
||||
short styleIndex=record.getXFIndex();
|
||||
ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(styleIndex);
|
||||
return new HSSFCellStyle(styleIndex, xf, book);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* used for internationalization, currently -1 for unchanged, 0 for compressed unicode or 1 for 16-bit
|
||||
*
|
||||
|
@ -173,6 +173,89 @@ public class HSSFOptimiser {
|
||||
* @param workbook The workbook in which to optimise the cell styles
|
||||
*/
|
||||
public static void optimiseCellStyles(HSSFWorkbook workbook) {
|
||||
// Where each style has ended up, and if we need to
|
||||
// delete the record for it. Start off with no change
|
||||
short[] newPos =
|
||||
new short[workbook.getWorkbook().getNumExFormats()];
|
||||
boolean[] zapRecords = new boolean[newPos.length];
|
||||
for(int i=0; i<newPos.length; i++) {
|
||||
newPos[i] = (short)i;
|
||||
zapRecords[i] = false;
|
||||
}
|
||||
|
||||
// Get each style record, so we can do deletes
|
||||
// without getting confused
|
||||
ExtendedFormatRecord[] xfrs = new ExtendedFormatRecord[newPos.length];
|
||||
for(int i=0; i<newPos.length; i++) {
|
||||
xfrs[i] = workbook.getWorkbook().getExFormatAt(i);
|
||||
}
|
||||
|
||||
// Loop over each style, seeing if it is the same
|
||||
// as an earlier one. If it is, point users of the
|
||||
// later duplicate copy to the earlier one, and
|
||||
// mark the later one as needing deleting
|
||||
// Only work on user added ones, which come after 20
|
||||
for(int i=21; i<newPos.length; i++) {
|
||||
// Check this one for being a duplicate
|
||||
// of an earlier one
|
||||
int earlierDuplicate = -1;
|
||||
for(int j=0; j<i && earlierDuplicate == -1; j++) {
|
||||
ExtendedFormatRecord xfCheck = workbook.getWorkbook().getExFormatAt(j);
|
||||
if(xfCheck.equals(xfrs[i])) {
|
||||
earlierDuplicate = j;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got a duplicate, mark it as such
|
||||
if(earlierDuplicate != -1) {
|
||||
newPos[i] = (short)earlierDuplicate;
|
||||
zapRecords[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the new positions based on
|
||||
// deletes that have occurred between
|
||||
// the start and them
|
||||
// Only work on user added ones, which come after 20
|
||||
for(int i=21; i<newPos.length; i++) {
|
||||
// Find the number deleted to that
|
||||
// point, and adjust
|
||||
short preDeletePos = newPos[i];
|
||||
short newPosition = preDeletePos;
|
||||
for(int j=0; j<preDeletePos; j++) {
|
||||
if(zapRecords[j]) newPosition--;
|
||||
}
|
||||
|
||||
// Update the new position
|
||||
newPos[i] = newPosition;
|
||||
}
|
||||
|
||||
// Zap the un-needed user style records
|
||||
for(int i=21; i<newPos.length; i++) {
|
||||
if(zapRecords[i]) {
|
||||
workbook.getWorkbook().removeExFormatRecord(
|
||||
xfrs[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, update the cells to point at
|
||||
// their new extended format records
|
||||
for(int sheetNum=0; sheetNum<workbook.getNumberOfSheets(); sheetNum++) {
|
||||
HSSFSheet s = workbook.getSheetAt(sheetNum);
|
||||
Iterator rIt = s.rowIterator();
|
||||
while(rIt.hasNext()) {
|
||||
HSSFRow row = (HSSFRow)rIt.next();
|
||||
Iterator cIt = row.cellIterator();
|
||||
while(cIt.hasNext()) {
|
||||
HSSFCell cell = (HSSFCell)cIt.next();
|
||||
short oldXf = cell.getCellValueRecord().getXFIndex();
|
||||
HSSFCellStyle newStyle = workbook.getCellStyleAt(
|
||||
newPos[oldXf]
|
||||
);
|
||||
cell.setCellStyle(newStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class TestHSSFOptimiser extends TestCase {
|
||||
@ -38,7 +40,7 @@ public class TestHSSFOptimiser extends TestCase {
|
||||
assertEquals(f, s.getFont(wb));
|
||||
|
||||
// Optimise styles
|
||||
// HSSFOptimiser.optimiseCellStyles(wb);
|
||||
HSSFOptimiser.optimiseCellStyles(wb);
|
||||
|
||||
assertEquals(5, wb.getNumberOfFonts());
|
||||
assertEquals(22, wb.getNumCellStyles());
|
||||
@ -77,6 +79,8 @@ public class TestHSSFOptimiser extends TestCase {
|
||||
|
||||
|
||||
// Use all three of the four in cell styles
|
||||
assertEquals(21, wb.getNumCellStyles());
|
||||
|
||||
HSSFCellStyle cs1 = wb.createCellStyle();
|
||||
cs1.setFont(f1);
|
||||
assertEquals(5, cs1.getFontIndex());
|
||||
@ -93,6 +97,8 @@ public class TestHSSFOptimiser extends TestCase {
|
||||
cs4.setFont(f6);
|
||||
assertEquals(10, cs4.getFontIndex());
|
||||
|
||||
assertEquals(25, wb.getNumCellStyles());
|
||||
|
||||
|
||||
// And three in rich text
|
||||
HSSFSheet s = wb.createSheet();
|
||||
@ -144,4 +150,91 @@ public class TestHSSFOptimiser extends TestCase {
|
||||
assertEquals(8, r.getCell(1).getRichStringCellValue().getFontAtIndex(6));
|
||||
assertEquals(8, r.getCell(1).getRichStringCellValue().getFontAtIndex(7));
|
||||
}
|
||||
|
||||
public void testOptimiseStyles() throws Exception {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
// Two fonts
|
||||
assertEquals(4, wb.getNumberOfFonts());
|
||||
|
||||
HSSFFont f1 = wb.createFont();
|
||||
f1.setFontHeight((short)11);
|
||||
f1.setFontName("Testing");
|
||||
|
||||
HSSFFont f2 = wb.createFont();
|
||||
f2.setFontHeight((short)22);
|
||||
f2.setFontName("Also Testing");
|
||||
|
||||
assertEquals(6, wb.getNumberOfFonts());
|
||||
|
||||
|
||||
// Several styles
|
||||
assertEquals(21, wb.getNumCellStyles());
|
||||
|
||||
HSSFCellStyle cs1 = wb.createCellStyle();
|
||||
cs1.setFont(f1);
|
||||
|
||||
HSSFCellStyle cs2 = wb.createCellStyle();
|
||||
cs2.setFont(f2);
|
||||
|
||||
HSSFCellStyle cs3 = wb.createCellStyle();
|
||||
cs3.setFont(f1);
|
||||
|
||||
HSSFCellStyle cs4 = wb.createCellStyle();
|
||||
cs4.setFont(f1);
|
||||
cs4.setAlignment((short)22);
|
||||
|
||||
HSSFCellStyle cs5 = wb.createCellStyle();
|
||||
cs5.setFont(f2);
|
||||
cs5.setAlignment((short)111);
|
||||
|
||||
HSSFCellStyle cs6 = wb.createCellStyle();
|
||||
cs6.setFont(f2);
|
||||
|
||||
assertEquals(27, wb.getNumCellStyles());
|
||||
|
||||
|
||||
// Use them
|
||||
HSSFSheet s = wb.createSheet();
|
||||
HSSFRow r = s.createRow(0);
|
||||
|
||||
r.createCell((short)0).setCellStyle(cs1);
|
||||
r.createCell((short)1).setCellStyle(cs2);
|
||||
r.createCell((short)2).setCellStyle(cs3);
|
||||
r.createCell((short)3).setCellStyle(cs4);
|
||||
r.createCell((short)4).setCellStyle(cs5);
|
||||
r.createCell((short)5).setCellStyle(cs6);
|
||||
r.createCell((short)6).setCellStyle(cs1);
|
||||
r.createCell((short)7).setCellStyle(cs2);
|
||||
|
||||
assertEquals(21, r.getCell(0).getCellValueRecord().getXFIndex());
|
||||
assertEquals(26, r.getCell(5).getCellValueRecord().getXFIndex());
|
||||
assertEquals(21, r.getCell(6).getCellValueRecord().getXFIndex());
|
||||
|
||||
|
||||
// Optimise
|
||||
HSSFOptimiser.optimiseCellStyles(wb);
|
||||
|
||||
|
||||
// Check
|
||||
assertEquals(6, wb.getNumberOfFonts());
|
||||
assertEquals(25, wb.getNumCellStyles());
|
||||
|
||||
// cs1 -> 21
|
||||
assertEquals(21, r.getCell(0).getCellValueRecord().getXFIndex());
|
||||
// cs2 -> 22
|
||||
assertEquals(22, r.getCell(1).getCellValueRecord().getXFIndex());
|
||||
// cs3 = cs1 -> 21
|
||||
assertEquals(21, r.getCell(2).getCellValueRecord().getXFIndex());
|
||||
// cs4 --> 24 -> 23
|
||||
assertEquals(23, r.getCell(3).getCellValueRecord().getXFIndex());
|
||||
// cs5 --> 25 -> 24
|
||||
assertEquals(24, r.getCell(4).getCellValueRecord().getXFIndex());
|
||||
// cs6 = cs2 -> 22
|
||||
assertEquals(22, r.getCell(5).getCellValueRecord().getXFIndex());
|
||||
// cs1 -> 21
|
||||
assertEquals(21, r.getCell(6).getCellValueRecord().getXFIndex());
|
||||
// cs2 -> 22
|
||||
assertEquals(22, r.getCell(7).getCellValueRecord().getXFIndex());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user