Allow the cloning of one HSSFCellStyle onto another, including cloning styles from one HSSFWorkbook onto another

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@676205 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2008-07-12 17:38:10 +00:00
parent eb35f25f3b
commit 511f83925b
9 changed files with 255 additions and 0 deletions

View File

@ -37,6 +37,7 @@
<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="add">Allow the cloning of one HSSFCellStyle onto another, including cloning styles from one HSSFWorkbook onto another</action>
<action dev="POI-DEVELOPERS" type="fix">45289 - finished support for special comparison operators in COUNTIF</action>
<action dev="POI-DEVELOPERS" type="fix">45126 - Avoid generating multiple NamedRanges with the same name, which Excel dislikes</action>
<action dev="POI-DEVELOPERS" type="fix">Fix cell.getRichStringCellValue() for formula cells with string results</action>

View File

@ -34,6 +34,7 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="add">Allow the cloning of one HSSFCellStyle onto another, including cloning styles from one HSSFWorkbook onto another</action>
<action dev="POI-DEVELOPERS" type="fix">45289 - finished support for special comparison operators in COUNTIF</action>
<action dev="POI-DEVELOPERS" type="fix">45126 - Avoid generating multiple NamedRanges with the same name, which Excel dislikes</action>
<action dev="POI-DEVELOPERS" type="fix">Fix cell.getRichStringCellValue() for formula cells with string results</action>

View File

@ -408,6 +408,24 @@ public class Workbook implements Model
return retval;
}
/**
* Retrieves the index of the given font
*/
public int getFontIndex(FontRecord font) {
for(int i=0; i<=numfonts; i++) {
FontRecord thisFont =
( FontRecord ) records.get((records.getFontpos() - (numfonts - 1)) + i);
if(thisFont == font) {
// There is no 4!
if(i > 3) {
return (i+1);
}
return i;
}
}
throw new IllegalArgumentException("Could not find that font!");
}
/**
* creates a new font record and adds it to the "font table". This causes the

View File

@ -915,6 +915,10 @@ public class HSSFCell
public void setCellStyle(HSSFCellStyle style)
{
// Verify it really does belong to our workbook
style.verifyBelongsToWorkbook(book);
// Change our cell record to use this style
record.setXFIndex(style.getIndex());
}

View File

@ -20,6 +20,7 @@ package org.apache.poi.hssf.usermodel;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.ExtendedFormatRecord;
import org.apache.poi.hssf.record.FontRecord;
import org.apache.poi.hssf.util.HSSFColor;
/**
@ -928,6 +929,63 @@ public class HSSFCellStyle
return format.getFillForeground();
}
/**
* Verifies that this style belongs to the supplied Workbook.
* Will throw an exception if it belongs to a different one.
* This is normally called when trying to assign a style to a
* cell, to ensure the cell and the style are from the same
* workbook (if they're not, it won't work)
* @throws IllegalArgumentException if there's a workbook mis-match
*/
public void verifyBelongsToWorkbook(HSSFWorkbook wb) {
if(wb.getWorkbook() != workbook) {
throw new IllegalArgumentException("This Style does not belong to the supplied Workbook. Are you trying to assign a style from one workbook to the cell of a differnt workbook?");
}
}
/**
* Clones all the style information from another
* HSSFCellStyle, onto this one. This
* HSSFCellStyle will then have all the same
* properties as the source, but the two may
* be edited independently.
* Any stylings on this HSSFCellStyle will be lost!
*
* The source HSSFCellStyle could be from another
* HSSFWorkbook if you like. This allows you to
* copy styles from one HSSFWorkbook to another.
*/
public void cloneStyleFrom(HSSFCellStyle source) {
// First we need to clone the extended format
// record
format.cloneStyleFrom(source.format);
// Handle matching things if we cross workbooks
if(workbook != source.workbook) {
// Then we need to clone the format string,
// and update the format record for this
short fmt = workbook.createFormat(
source.getDataFormatString()
);
setDataFormat(fmt);
// Finally we need to clone the font,
// and update the format record for this
FontRecord fr = workbook.createNewFont();
fr.cloneStyleFrom(
source.workbook.getFontRecordAt(
source.getFontIndex()
)
);
HSSFFont font = new HSSFFont(
(short)workbook.getFontIndex(fr), fr
);
setFont(font);
}
}
public int hashCode() {
final int prime = 31;
int result = 1;

View File

@ -38,6 +38,7 @@ public final class AllModelTests {
result.addTestSuite(TestRVA.class);
result.addTestSuite(TestSheet.class);
result.addTestSuite(TestSheetAdditional.class);
result.addTestSuite(TestWorkbook.class);
return result;
}
}

View File

@ -0,0 +1,61 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 org.apache.poi.hssf.record.FontRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import junit.framework.TestCase;
/**
* Unit test for the Workbook class.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class TestWorkbook extends TestCase {
public void testFontStuff() throws Exception {
Workbook wb = (new HW()).getWorkbook();
assertEquals(4, wb.getNumberOfFontRecords());
FontRecord f1 = wb.getFontRecordAt(0);
FontRecord f4 = wb.getFontRecordAt(3);
assertEquals(0, wb.getFontIndex(f1));
assertEquals(3, wb.getFontIndex(f4));
assertEquals(f1, wb.getFontRecordAt(0));
assertEquals(f4, wb.getFontRecordAt(3));
// There is no 4! new ones go in at 5
FontRecord n = wb.createNewFont();
assertEquals(5, wb.getNumberOfFontRecords());
assertEquals(5, wb.getFontIndex(n));
assertEquals(n, wb.getFontRecordAt(5));
}
private class HW extends HSSFWorkbook {
private HW() {
super();
}
protected Workbook getWorkbook() {
return super.getWorkbook();
}
}
}

View File

@ -229,6 +229,80 @@ public class TestCellStyle
// assert((s.getLastRowNum() == 99));
}
/**
* Cloning one HSSFCellStyle onto Another, same
* HSSFWorkbook
*/
public void testCloneStyleSameWB() throws Exception {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFFont fnt = wb.createFont();
fnt.setFontName("TestingFont");
assertEquals(5, wb.getNumberOfFonts());
HSSFCellStyle orig = wb.createCellStyle();
orig.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
orig.setFont(fnt);
orig.setDataFormat((short)18);
assertTrue(HSSFCellStyle.ALIGN_RIGHT == orig.getAlignment());
assertTrue(fnt == orig.getFont(wb));
assertTrue(18 == orig.getDataFormat());
HSSFCellStyle clone = wb.createCellStyle();
assertFalse(HSSFCellStyle.ALIGN_RIGHT == clone.getAlignment());
assertFalse(fnt == clone.getFont(wb));
assertFalse(18 == clone.getDataFormat());
clone.cloneStyleFrom(orig);
assertTrue(HSSFCellStyle.ALIGN_RIGHT == clone.getAlignment());
assertTrue(fnt == clone.getFont(wb));
assertTrue(18 == clone.getDataFormat());
assertEquals(5, wb.getNumberOfFonts());
}
/**
* Cloning one HSSFCellStyle onto Another, across
* two different HSSFWorkbooks
*/
public void testCloneStyleDiffWB() throws Exception {
HSSFWorkbook wbOrig = new HSSFWorkbook();
HSSFFont fnt = wbOrig.createFont();
fnt.setFontName("TestingFont");
assertEquals(5, wbOrig.getNumberOfFonts());
HSSFDataFormat fmt = wbOrig.createDataFormat();
fmt.getFormat("MadeUpOne");
fmt.getFormat("MadeUpTwo");
HSSFCellStyle orig = wbOrig.createCellStyle();
orig.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
orig.setFont(fnt);
orig.setDataFormat(fmt.getFormat("Test##"));
assertTrue(HSSFCellStyle.ALIGN_RIGHT == orig.getAlignment());
assertTrue(fnt == orig.getFont(wbOrig));
assertTrue(fmt.getFormat("Test##") == orig.getDataFormat());
// Now a style on another workbook
HSSFWorkbook wbClone = new HSSFWorkbook();
assertEquals(4, wbClone.getNumberOfFonts());
HSSFDataFormat fmtClone = wbClone.createDataFormat();
HSSFCellStyle clone = wbClone.createCellStyle();
assertEquals(4, wbClone.getNumberOfFonts());
assertFalse(HSSFCellStyle.ALIGN_RIGHT == clone.getAlignment());
assertFalse("TestingFont" == clone.getFont(wbClone).getFontName());
clone.cloneStyleFrom(orig);
assertTrue(HSSFCellStyle.ALIGN_RIGHT == clone.getAlignment());
assertTrue("TestingFont" == clone.getFont(wbClone).getFontName());
assertTrue(fmtClone.getFormat("Test##") == clone.getDataFormat());
assertFalse(fmtClone.getFormat("Test##") == fmt.getFormat("Test##"));
assertEquals(5, wbClone.getNumberOfFonts());
}
public static void main(String [] ignored_args)
{

View File

@ -381,6 +381,43 @@ public final class TestHSSFCell extends TestCase {
throw new AssertionFailedError("Identified bug 44606");
}
}
/**
* Test to ensure we can only assign cell styles that belong
* to our workbook, and not those from other workbooks.
*/
public void testCellStyleWorkbookMatch() throws Exception {
HSSFWorkbook wbA = new HSSFWorkbook();
HSSFWorkbook wbB = new HSSFWorkbook();
HSSFCellStyle styA = wbA.createCellStyle();
HSSFCellStyle styB = wbB.createCellStyle();
styA.verifyBelongsToWorkbook(wbA);
styB.verifyBelongsToWorkbook(wbB);
try {
styA.verifyBelongsToWorkbook(wbB);
fail();
} catch(IllegalArgumentException e) {}
try {
styB.verifyBelongsToWorkbook(wbA);
fail();
} catch(IllegalArgumentException e) {}
HSSFCell cellA = wbA.createSheet().createRow(0).createCell((short)0);
HSSFCell cellB = wbB.createSheet().createRow(0).createCell((short)0);
cellA.setCellStyle(styA);
cellB.setCellStyle(styB);
try {
cellA.setCellStyle(styB);
fail();
} catch(IllegalArgumentException e) {}
try {
cellB.setCellStyle(styA);
fail();
} catch(IllegalArgumentException e) {}
}
public static void main(String [] args) {
junit.textui.TestRunner.run(TestHSSFCell.class);