Search in sources :

Example 1 with FontRecord

use of org.apache.poi.hssf.record.FontRecord in project poi by apache.

the class HSSFOptimiser method optimiseFonts.

/**
	 * Goes through the Workbook, optimising the fonts by
	 *  removing duplicate ones.
	 * For now, only works on fonts used in {@link HSSFCellStyle}
	 *  and {@link HSSFRichTextString}. Any other font uses
	 *  (eg charts, pictures) may well end up broken!
	 * This can be a slow operation, especially if you have
	 *  lots of cells, cell styles or rich text strings
	 * @param workbook The workbook in which to optimise the fonts
	 */
public static void optimiseFonts(HSSFWorkbook workbook) {
    // Where each font has ended up, and if we need to
    //  delete the record for it. Start off with no change
    short[] newPos = new short[workbook.getWorkbook().getNumberOfFontRecords() + 1];
    boolean[] zapRecords = new boolean[newPos.length];
    for (int i = 0; i < newPos.length; i++) {
        newPos[i] = (short) i;
        zapRecords[i] = false;
    }
    // Get each font record, so we can do deletes
    //  without getting confused
    FontRecord[] frecs = new FontRecord[newPos.length];
    for (int i = 0; i < newPos.length; i++) {
        // There is no 4!
        if (i == 4)
            continue;
        frecs[i] = workbook.getWorkbook().getFontRecordAt(i);
    }
    // Note - don't change built in fonts (those before 5)
    for (int i = 5; 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++) {
            if (j == 4)
                continue;
            FontRecord frCheck = workbook.getWorkbook().getFontRecordAt(j);
            if (frCheck.sameProperties(frecs[i])) {
                earlierDuplicate = j;
            }
        }
        // If we got a duplicate, mark it as such
        if (earlierDuplicate != -1) {
            newPos[i] = (short) earlierDuplicate;
            zapRecords[i] = true;
        }
    }
    // Only need to worry about user fonts
    for (int i = 5; 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 font records
    for (int i = 5; i < newPos.length; i++) {
        if (zapRecords[i]) {
            workbook.getWorkbook().removeFontRecord(frecs[i]);
        }
    }
    // Tell HSSFWorkbook that it needs to
    //  re-start its HSSFFontCache
    workbook.resetFontCache();
    //  new locations of the fonts
    for (int i = 0; i < workbook.getWorkbook().getNumExFormats(); i++) {
        ExtendedFormatRecord xfr = workbook.getWorkbook().getExFormatAt(i);
        xfr.setFontIndex(newPos[xfr.getFontIndex()]);
    }
    // Update the rich text strings to point at
    //  the new locations of the fonts
    // Remember that one underlying unicode string
    //  may be shared by multiple RichTextStrings!
    HashSet<UnicodeString> doneUnicodeStrings = new HashSet<UnicodeString>();
    for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
        HSSFSheet s = workbook.getSheetAt(sheetNum);
        for (Row row : s) {
            for (Cell cell : row) {
                if (cell.getCellTypeEnum() == CellType.STRING) {
                    HSSFRichTextString rtr = (HSSFRichTextString) cell.getRichStringCellValue();
                    UnicodeString u = rtr.getRawUnicodeString();
                    // Have we done this string already?
                    if (!doneUnicodeStrings.contains(u)) {
                        // Update for each new position
                        for (short i = 5; i < newPos.length; i++) {
                            if (i != newPos[i]) {
                                u.swapFontUse(i, newPos[i]);
                            }
                        }
                        // Mark as done
                        doneUnicodeStrings.add(u);
                    }
                }
            }
        }
    }
}
Also used : FontRecord(org.apache.poi.hssf.record.FontRecord) ExtendedFormatRecord(org.apache.poi.hssf.record.ExtendedFormatRecord) UnicodeString(org.apache.poi.hssf.record.common.UnicodeString) Row(org.apache.poi.ss.usermodel.Row) Cell(org.apache.poi.ss.usermodel.Cell) HashSet(java.util.HashSet)

Example 2 with FontRecord

use of org.apache.poi.hssf.record.FontRecord in project poi by apache.

the class InternalWorkbook method getFontRecordAt.

/**
     * gets the font record at the given index in the font table.  Remember
     * "There is No Four" (someone at M$ must have gone to Rocky Horror one too
     * many times)
     *
     * @param idx the index to look at (0 or greater but NOT 4)
     * @return FontRecord located at the given index
     */
public FontRecord getFontRecordAt(int idx) {
    int index = idx;
    if (index > 4) {
        // adjust for "There is no 4"
        index -= 1;
    }
    if (index > (numfonts - 1)) {
        throw new ArrayIndexOutOfBoundsException("There are only " + numfonts + " font records, you asked for " + idx);
    }
    FontRecord retval = (FontRecord) records.get((records.getFontpos() - (numfonts - 1)) + index);
    return retval;
}
Also used : FontRecord(org.apache.poi.hssf.record.FontRecord)

Example 3 with FontRecord

use of org.apache.poi.hssf.record.FontRecord in project poi by apache.

the class InternalWorkbook method createNewFont.

/**
     * creates a new font record and adds it to the "font table".  This causes the
     * boundsheets to move down one, extended formats to move down (so this function moves
     * those pointers as well)
     *
     * @return FontRecord that was just created
     */
public FontRecord createNewFont() {
    FontRecord rec = createFont();
    records.add(records.getFontpos() + 1, rec);
    records.setFontpos(records.getFontpos() + 1);
    numfonts++;
    return rec;
}
Also used : FontRecord(org.apache.poi.hssf.record.FontRecord)

Example 4 with FontRecord

use of org.apache.poi.hssf.record.FontRecord in project poi by apache.

the class InternalWorkbook method createFont.

/**
     * creates a Font record with the following magic values: <P>
     * fontheight           = 0xc8<P>
     * attributes           = 0x0<P>
     * color palette index  = 0x7fff<P>
     * bold weight          = 0x190<P>
     * Font Name Length     = 5 <P>
     * Font Name            = Arial <P>
     */
private static FontRecord createFont() {
    FontRecord retval = new FontRecord();
    retval.setFontHeight((short) 0xc8);
    retval.setAttributes((short) 0x0);
    retval.setColorPaletteIndex((short) 0x7fff);
    retval.setBoldWeight((short) 0x190);
    retval.setFontName("Arial");
    return retval;
}
Also used : FontRecord(org.apache.poi.hssf.record.FontRecord)

Example 5 with FontRecord

use of org.apache.poi.hssf.record.FontRecord in project poi by apache.

the class HSSFWorkbook method getFontAt.

/**
     * Get the font at the given index number
     * @param idx  index number
     * @return HSSFFont at the index
     */
@Override
public HSSFFont getFontAt(short idx) {
    if (fonts == null) {
        fonts = new HashMap<Short, HSSFFont>();
    }
    // So we don't confuse users, give them back
    //  the same object every time, but create
    //  them lazily
    Short sIdx = Short.valueOf(idx);
    if (fonts.containsKey(sIdx)) {
        return fonts.get(sIdx);
    }
    FontRecord font = workbook.getFontRecordAt(idx);
    HSSFFont retval = new HSSFFont(idx, font);
    fonts.put(sIdx, retval);
    return retval;
}
Also used : FontRecord(org.apache.poi.hssf.record.FontRecord)

Aggregations

FontRecord (org.apache.poi.hssf.record.FontRecord)7 HashSet (java.util.HashSet)1 ExtendedFormatRecord (org.apache.poi.hssf.record.ExtendedFormatRecord)1 UnicodeString (org.apache.poi.hssf.record.common.UnicodeString)1 HSSFWorkbook (org.apache.poi.hssf.usermodel.HSSFWorkbook)1 TestHSSFWorkbook (org.apache.poi.hssf.usermodel.TestHSSFWorkbook)1 Cell (org.apache.poi.ss.usermodel.Cell)1 Row (org.apache.poi.ss.usermodel.Row)1 Test (org.junit.Test)1