Search in sources :

Example 1 with UnicodeString

use of org.apache.poi.hssf.record.common.UnicodeString 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 UnicodeString

use of org.apache.poi.hssf.record.common.UnicodeString in project poi by apache.

the class HSSFCell method setCellValue.

/**
     * Set a string value for the cell.
     *
     * @param value  value to set the cell to.  For formulas we'll set the formula
     * string, for String cells we'll set its value.  For other types we will
     * change the cell to a string cell and set its value.
     * If value is <code>null</code> then we will change the cell to a Blank cell.
     */
public void setCellValue(RichTextString value) {
    int row = _record.getRow();
    short col = _record.getColumn();
    short styleIndex = _record.getXFIndex();
    if (value == null) {
        notifyFormulaChanging();
        setCellType(CellType.BLANK, false, row, col, styleIndex);
        return;
    }
    if (value.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()) {
        throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters");
    }
    if (_cellType == CellType.FORMULA) {
        // Set the 'pre-evaluated result' for the formula
        // note - formulas do not preserve text formatting.
        FormulaRecordAggregate fr = (FormulaRecordAggregate) _record;
        fr.setCachedStringResult(value.getString());
        // Update our local cache to the un-formatted version
        _stringValue = new HSSFRichTextString(value.getString());
        // All done
        return;
    }
    if (_cellType != CellType.STRING) {
        setCellType(CellType.STRING, false, row, col, styleIndex);
    }
    int index = 0;
    HSSFRichTextString hvalue = (HSSFRichTextString) value;
    UnicodeString str = hvalue.getUnicodeString();
    index = _book.getWorkbook().addSSTString(str);
    ((LabelSSTRecord) _record).setSSTIndex(index);
    _stringValue = hvalue;
    _stringValue.setWorkbookReferences(_book.getWorkbook(), ((LabelSSTRecord) _record));
    _stringValue.setUnicodeString(_book.getWorkbook().getSSTString(index));
}
Also used : UnicodeString(org.apache.poi.hssf.record.common.UnicodeString) FormulaRecordAggregate(org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate) LabelSSTRecord(org.apache.poi.hssf.record.LabelSSTRecord)

Example 3 with UnicodeString

use of org.apache.poi.hssf.record.common.UnicodeString in project poi by apache.

the class HSSFCell method setCellType.

/**
     * sets the cell type. The setValue flag indicates whether to bother about
     *  trying to preserve the current value in the new record if one is created.
     *  <p>
     *  The @see #setCellValue method will call this method with false in setValue
     *  since it will overwrite the cell value later
     *
     */
private void setCellType(CellType cellType, boolean setValue, int row, short col, short styleIndex) {
    switch(cellType) {
        case FORMULA:
            FormulaRecordAggregate frec;
            if (cellType != _cellType) {
                frec = _sheet.getSheet().getRowsAggregate().createFormula(row, col);
            } else {
                frec = (FormulaRecordAggregate) _record;
                frec.setRow(row);
                frec.setColumn(col);
            }
            if (setValue) {
                frec.getFormulaRecord().setValue(getNumericCellValue());
            }
            frec.setXFIndex(styleIndex);
            _record = frec;
            break;
        case NUMERIC:
            NumberRecord nrec = null;
            if (cellType != _cellType) {
                nrec = new NumberRecord();
            } else {
                nrec = (NumberRecord) _record;
            }
            nrec.setColumn(col);
            if (setValue) {
                nrec.setValue(getNumericCellValue());
            }
            nrec.setXFIndex(styleIndex);
            nrec.setRow(row);
            _record = nrec;
            break;
        case STRING:
            LabelSSTRecord lrec;
            if (cellType == _cellType) {
                lrec = (LabelSSTRecord) _record;
            } else {
                lrec = new LabelSSTRecord();
                lrec.setColumn(col);
                lrec.setRow(row);
                lrec.setXFIndex(styleIndex);
            }
            if (setValue) {
                String str = convertCellValueToString();
                if (str == null) {
                    // bug 55668: don't try to store null-string when formula
                    // results in empty/null value
                    setCellType(CellType.BLANK, false, row, col, styleIndex);
                    return;
                } else {
                    int sstIndex = _book.getWorkbook().addSSTString(new UnicodeString(str));
                    lrec.setSSTIndex(sstIndex);
                    UnicodeString us = _book.getWorkbook().getSSTString(sstIndex);
                    _stringValue = new HSSFRichTextString();
                    _stringValue.setUnicodeString(us);
                }
            }
            _record = lrec;
            break;
        case BLANK:
            BlankRecord brec = null;
            if (cellType != _cellType) {
                brec = new BlankRecord();
            } else {
                brec = (BlankRecord) _record;
            }
            brec.setColumn(col);
            // During construction the cellStyle may be null for a Blank cell.
            brec.setXFIndex(styleIndex);
            brec.setRow(row);
            _record = brec;
            break;
        case BOOLEAN:
            BoolErrRecord boolRec = null;
            if (cellType != _cellType) {
                boolRec = new BoolErrRecord();
            } else {
                boolRec = (BoolErrRecord) _record;
            }
            boolRec.setColumn(col);
            if (setValue) {
                boolRec.setValue(convertCellValueToBoolean());
            }
            boolRec.setXFIndex(styleIndex);
            boolRec.setRow(row);
            _record = boolRec;
            break;
        case ERROR:
            BoolErrRecord errRec = null;
            if (cellType != _cellType) {
                errRec = new BoolErrRecord();
            } else {
                errRec = (BoolErrRecord) _record;
            }
            errRec.setColumn(col);
            if (setValue) {
                errRec.setValue(FormulaError.VALUE.getCode());
            }
            errRec.setXFIndex(styleIndex);
            errRec.setRow(row);
            _record = errRec;
            break;
        default:
            throw new IllegalStateException("Invalid cell type: " + cellType);
    }
    if (cellType != _cellType && // Special Value to indicate an uninitialized Cell
    _cellType != CellType._NONE) {
        _sheet.getSheet().replaceValueRecord(_record);
    }
    _cellType = cellType;
}
Also used : BoolErrRecord(org.apache.poi.hssf.record.BoolErrRecord) BlankRecord(org.apache.poi.hssf.record.BlankRecord) UnicodeString(org.apache.poi.hssf.record.common.UnicodeString) FormulaRecordAggregate(org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate) RichTextString(org.apache.poi.ss.usermodel.RichTextString) UnicodeString(org.apache.poi.hssf.record.common.UnicodeString) NumberRecord(org.apache.poi.hssf.record.NumberRecord) LabelSSTRecord(org.apache.poi.hssf.record.LabelSSTRecord)

Example 4 with UnicodeString

use of org.apache.poi.hssf.record.common.UnicodeString in project poi by apache.

the class InternalWorkbook method getSSTString.

/**
     * given an index into the SST table, this function returns the corresponding String value
     * @param str the index into the SST table
     * @return String containing the SST String
     */
public UnicodeString getSSTString(int str) {
    if (sst == null) {
        insertSST();
    }
    UnicodeString retval = sst.getString(str);
    LOG.log(DEBUG, "Returning SST for index=", str, " String= ", retval);
    return retval;
}
Also used : UnicodeString(org.apache.poi.hssf.record.common.UnicodeString)

Example 5 with UnicodeString

use of org.apache.poi.hssf.record.common.UnicodeString in project poi by apache.

the class SSTDeserializer method manufactureStrings.

/**
     * This is the starting point where strings are constructed.  Note that
     * strings may span across multiple continuations. Read the SST record
     * carefully before beginning to hack.
     */
public void manufactureStrings(int stringCount, RecordInputStream in) {
    for (int i = 0; i < stringCount; i++) {
        // Extract exactly the count of strings from the SST record.
        UnicodeString str;
        if (in.available() == 0 && !in.hasNextRecord()) {
            logger.log(POILogger.ERROR, "Ran out of data before creating all the strings! String at index " + i + "");
            str = new UnicodeString("");
        } else {
            str = new UnicodeString(in);
        }
        addToStringTable(strings, str);
    }
}
Also used : UnicodeString(org.apache.poi.hssf.record.common.UnicodeString)

Aggregations

UnicodeString (org.apache.poi.hssf.record.common.UnicodeString)16 Test (org.junit.Test)5 LabelSSTRecord (org.apache.poi.hssf.record.LabelSSTRecord)3 ExtendedFormatRecord (org.apache.poi.hssf.record.ExtendedFormatRecord)2 FontRecord (org.apache.poi.hssf.record.FontRecord)2 FormulaRecordAggregate (org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 HashSet (java.util.HashSet)1 EscherBSERecord (org.apache.poi.ddf.EscherBSERecord)1 EscherBlipRecord (org.apache.poi.ddf.EscherBlipRecord)1 EscherRecord (org.apache.poi.ddf.EscherRecord)1 AbstractEscherHolderRecord (org.apache.poi.hssf.record.AbstractEscherHolderRecord)1 BackupRecord (org.apache.poi.hssf.record.BackupRecord)1 BlankRecord (org.apache.poi.hssf.record.BlankRecord)1 BoolErrRecord (org.apache.poi.hssf.record.BoolErrRecord)1 BoundSheetRecord (org.apache.poi.hssf.record.BoundSheetRecord)1 DrawingGroupRecord (org.apache.poi.hssf.record.DrawingGroupRecord)1 FilePassRecord (org.apache.poi.hssf.record.FilePassRecord)1 LabelRecord (org.apache.poi.hssf.record.LabelRecord)1 NameRecord (org.apache.poi.hssf.record.NameRecord)1