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;
|
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
|
* creates a new Cell-type Extneded Format Record and adds it to the end of
|
||||||
|
@ -927,14 +927,13 @@ public class HSSFCell
|
|||||||
* object.
|
* object.
|
||||||
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
|
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public HSSFCellStyle getCellStyle()
|
public HSSFCellStyle getCellStyle()
|
||||||
{
|
{
|
||||||
short styleIndex=record.getXFIndex();
|
short styleIndex=record.getXFIndex();
|
||||||
ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(styleIndex);
|
ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(styleIndex);
|
||||||
return new HSSFCellStyle(styleIndex, xf, book);
|
return new HSSFCellStyle(styleIndex, xf, book);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* used for internationalization, currently -1 for unchanged, 0 for compressed unicode or 1 for 16-bit
|
* 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
|
* @param workbook The workbook in which to optimise the cell styles
|
||||||
*/
|
*/
|
||||||
public static void optimiseCellStyles(HSSFWorkbook workbook) {
|
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;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.model.Workbook;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
public class TestHSSFOptimiser extends TestCase {
|
public class TestHSSFOptimiser extends TestCase {
|
||||||
@ -38,7 +40,7 @@ public class TestHSSFOptimiser extends TestCase {
|
|||||||
assertEquals(f, s.getFont(wb));
|
assertEquals(f, s.getFont(wb));
|
||||||
|
|
||||||
// Optimise styles
|
// Optimise styles
|
||||||
// HSSFOptimiser.optimiseCellStyles(wb);
|
HSSFOptimiser.optimiseCellStyles(wb);
|
||||||
|
|
||||||
assertEquals(5, wb.getNumberOfFonts());
|
assertEquals(5, wb.getNumberOfFonts());
|
||||||
assertEquals(22, wb.getNumCellStyles());
|
assertEquals(22, wb.getNumCellStyles());
|
||||||
@ -77,6 +79,8 @@ public class TestHSSFOptimiser extends TestCase {
|
|||||||
|
|
||||||
|
|
||||||
// Use all three of the four in cell styles
|
// Use all three of the four in cell styles
|
||||||
|
assertEquals(21, wb.getNumCellStyles());
|
||||||
|
|
||||||
HSSFCellStyle cs1 = wb.createCellStyle();
|
HSSFCellStyle cs1 = wb.createCellStyle();
|
||||||
cs1.setFont(f1);
|
cs1.setFont(f1);
|
||||||
assertEquals(5, cs1.getFontIndex());
|
assertEquals(5, cs1.getFontIndex());
|
||||||
@ -93,6 +97,8 @@ public class TestHSSFOptimiser extends TestCase {
|
|||||||
cs4.setFont(f6);
|
cs4.setFont(f6);
|
||||||
assertEquals(10, cs4.getFontIndex());
|
assertEquals(10, cs4.getFontIndex());
|
||||||
|
|
||||||
|
assertEquals(25, wb.getNumCellStyles());
|
||||||
|
|
||||||
|
|
||||||
// And three in rich text
|
// And three in rich text
|
||||||
HSSFSheet s = wb.createSheet();
|
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(6));
|
||||||
assertEquals(8, r.getCell(1).getRichStringCellValue().getFontAtIndex(7));
|
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