poi-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 45260] Excel file unreadable due to applyFont()
Date Mon, 02 Mar 2009 09:04:02 GMT
https://issues.apache.org/bugzilla/show_bug.cgi?id=45260





--- Comment #14 from Werner Schindling <w.schindling@netconomy.net>  2009-03-02 01:03:59
PST ---
(In reply to comment #13)
> Is there anything special in the way you create / set rich text strings? Can
> you post the code you used to generated the attached files? 
> 
> Compare two code snippets:
> 
>         HSSFRichTextString str1 = new HSSFRichTextString("Andritz AG, Graz
> Short Name: AAG");
>         str1.applyFont(0, 16, FONT_CELL_HEADER_BLUE.getIndex());
>         str1.applyFont(17, 29, FONT_ITALIC.getIndex());
>         str1.applyFont(29, 32, FONT.getIndex());
>         cell.setCellValue(str1);
> 
> 
>         HSSFRichTextString str2 = new HSSFRichTextString("Andritz AG, Graz
> Short Name: AAG");
>         cell2.setCellValue(str2);
>         str2.applyFont(0, 16, FONT_CELL_HEADER_BLUE.getIndex());
>         str2.applyFont(17, 29, FONT_ITALIC.getIndex());
>         str2.applyFont(29, 32, FONT.getIndex());
> 
> They are not equivalent. The second one is incorrect and can produce wrong
> results. Once a HSSFRichTextString  is assigned, it is supposed to be
> immutable. I would say in the latter case the code should throw
> IllegalStateException. We don't do that only because of backwards
> compatibility. 
> 
> One of the problems with beta5fileMissingFonts.xls is that the internal cache
> of strings is incorrect. There are duplicate entries and as result,
> beta5fileMissingFonts.xls is 504 KB while beta3fileAllFonts.xls is just 331 KB. 
> Internally, Excel stores all strings in a shared string table which is shared
> across workbook. Text cells just contain indexes into the string table as the
> value of a cell, instead of the full string. If the string cache is broken, it
> is very likely to be the reason why some fonts are missing. 
> 
> Regards,
> Yegor

Hi Yegor,

thanks for taking the time on this!
In my code setCellValue(text) is called after all the fonts have been applied.
The biggest problem for me is that you just can't append to a
HSSFRichTextString. I have to run 2 identical loops, one for piecing the String
together and then another one to apply the fonts to the finished
HSSFRichTextString.
Here's the code ;) ... (I've tried to remove unimportant lines)


StringBuffer buffer = new StringBuffer();

        for (POICellContent content : this.content){


            for (int i = 0; i < content.indent; i++){
                // insert leading whitespaces
                buffer.append(" ");
            }
            // insert content
            buffer.append(content.toString());

            if (this.companyReport.showHistory && content.getInterval() !=
null){
                String dateString =
companyReport.createDateString(content.getInterval());
                if (!"".equals(dateString)){
                    int dateLength = dateString.length();
                    int textLength = 0;
                    if (buffer.indexOf("\n") != - 1){
                        textLength = (buffer.length() - 1) -
buffer.lastIndexOf("\n");
                    } else textLength = buffer.length();

                    // factor: variable to determine, whether the date string
fits in the same line
                    // or a new line is needed
                    double fontHeight =
content.getFont().getFontHeightInPoints();
                    if (fontHeight == 9) fontHeight = SMALL_FONT_MAGNIFICATION;
                    double widthFactor =
CompanyReportXlsGenerator.LINE_BREAK_FACTOR * fontHeight;
                    double approxColumnWidth = column.getWidth() / widthFactor;
                    boolean makeNewLine = content.dateWrap && textLength <
approxColumnWidth 
                            && textLength + dateLength + 1 > approxColumnWidth;


                    if (makeNewLine){
                        buffer.append(CompanyReportXlsGenerator.NEW_LINE);
                        if (content.dateIndent > 0){
                            for (int i = 0; i < content.dateIndent; i++){
                                dateString = " " + dateString;
                            }
                        } else if (content.indent > 0){
                            for (int i = 0; i < content.indent; i++){
                                dateString = " " + dateString;
                            }
                        }
                        buffer.append(dateString);
                    } else {
                        buffer.append(" " + dateString);
                    }    
                }
            }
        }

        HSSFRichTextString resultString = new
HSSFRichTextString(buffer.toString());
        // build the cell String again to apply fonts
        buffer = new StringBuffer();

        int end = 0;
        int start = 0;
        for (POICellContent content : this.content){

            start = end;
            end = start + content.toString().length();
            for (int i = 0; i < content.indent; i++) {
                // insert leading whitespaces
                buffer.append(" ");
            }
            end += content.indent;

            // insert content
            buffer.append(content.toString());
            HSSFFont font = content.getFont();
            if (!font.getStrikeout() && row.getEntry().isStrikeOut() &&
content.strikeOutEnabled){
                // use strikeOut Font
                font = companyReport.getStrikeOutFont(content.getFont());
            }
            HSSFFont indentFont = companyReport.getNoStrikeOutFont(font);
            if ((companyReport.useFormatting || row.getEntry().isStrikeOut())
&& content.indent > 0){            
                resultString.applyFont(start, start + content.indent,
indentFont);
                resultString.applyFont(start + content.indent, end, font);
            } else if (companyReport.useFormatting ||
row.getEntry().isStrikeOut()){
                resultString.applyFont(start, end, font);
            }
            if (this.companyReport.showHistory && content.getInterval() !=
null){
                String dateString =
companyReport.createDateString(content.getInterval());
                if (!"".equals(dateString)){
                    int dateLength = dateString.length();                       
                    if (dateLength > 0){
                        start = end;
                        end = end + dateLength;
                        // + 1 because of whitespace/new line
                        end++;

                        int textLength =  buffer.length();
                        if (buffer.indexOf("\n") != - 1){
                            textLength = (buffer.length() - 1) -
buffer.lastIndexOf("\n");
                        }


                            if (content.dateIndent > 0){
                                for (int i = 0; i < content.dateIndent; i++){
                                    dateString = " " + dateString;
                                    end++;
                                }
                            } else if (content.indent > 0){
                                for (int i = 0; i < content.indent; i++){
                                    dateString = " " + dateString;
                                    end++;
                                }
                            }
                            buffer.append(dateString);

                        HSSFFont dateFont = this.companyReport.FONT_DATE;
                        if (font.getStrikeout() ||
row.getEntry().isStrikeOut()) {
                            dateFont = this.companyReport.FONT_DATE_STRIKE;
                        }
                        if (companyReport.useFormatting ||
row.getEntry().isStrikeOut()){
                            try {
                                if (makeNewLine && content.dateIndent > 0){
                                    resultString.applyFont(start, start +
content.dateIndent, 
                                            companyReport.FONT_DATE);
                                    resultString.applyFont(start +
content.dateIndent, end, dateFont);    
                                } else if (makeNewLine && content.indent > 0){
                                    resultString.applyFont(start, start +
content.indent, 
                                            companyReport.FONT_DATE);
                                    resultString.applyFont(start +
content.indent, end, dateFont);
                                } else {
                                    resultString.applyFont(start, end,
dateFont);
                                }
                            } catch (IllegalArgumentException e){
                                logger.error("Company Report error: font
indices messed up: " + e.getMessage());
                            }
                        }
                    }
                }
            }
        }

        return resultString;

-- 
Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
For additional commands, e-mail: dev-help@poi.apache.org


Mime
View raw message