读书人

总算搞定jsp-pdf

发布时间: 2012-12-28 10:29:04 作者: rapoo

终于搞定jsp-pdf

/*参考flying saucer 中文分行: http://bettereveryday.iteye.com/blog/611561修改了org.xhtmlrenderer.layout.Breaker类,添加了2个方法,修改了109行和121行,由原来的按空格分组改为调用getStrRight按新的方式分组来获取字符的右边界值:(在我的应用中,直接按任意字符为组,防止在table-layout:fixed样式下,长英文单词不换行问题) ?* Breaker.java * Copyright (c) 2004, 2005 Torbj?rn Gannholm,  * Copyright (c) 2005 Wisconsin Court System * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */package org.xhtmlrenderer.layout;import org.xhtmlrenderer.css.constants.IdentValue;import org.xhtmlrenderer.css.style.CalculatedStyle;import org.xhtmlrenderer.render.FSFont;/** * A utility class that scans the text of a single inline box, looking for the  * next break point. * @author Torbj?rn Gannholm */public class Breaker {    public static void breakFirstLetter(LayoutContext c, LineBreakContext context,            int avail, CalculatedStyle style) {        FSFont font = style.getFSFont(c);        context.setEnd(getFirstLetterEnd(context.getMaster(), context.getStart()));        context.setWidth(c.getTextRenderer().getWidth(                c.getFontContext(), font, context.getCalculatedSubstring()));                if (context.getWidth() > avail) {            context.setNeedsNewLine(true);            context.setUnbreakable(true);        }    }        private static int getFirstLetterEnd(String text, int start) {        int i = start;        while (i < text.length()) {            char c = text.charAt(i);            int type = Character.getType(c);            if (type == Character.START_PUNCTUATION ||                     type == Character.END_PUNCTUATION ||                    type == Character.INITIAL_QUOTE_PUNCTUATION ||                    type == Character.FINAL_QUOTE_PUNCTUATION ||                    type == Character.OTHER_PUNCTUATION) {                i++;            } else {                break;            }        }        if (i < text.length()) {            i++;        }        return i;    }            public static void breakText(LayoutContext c,             LineBreakContext context, int avail, CalculatedStyle style) {        FSFont font = style.getFSFont(c);        IdentValue whitespace = style.getWhitespace();                // ====== handle nowrap        if (whitespace == IdentValue.NOWRAP) {        context.setEnd(context.getLast());        context.setWidth(c.getTextRenderer().getWidth(                    c.getFontContext(), font, context.getCalculatedSubstring()));            return;        }        //check if we should break on the next newline        if (whitespace == IdentValue.PRE ||                whitespace == IdentValue.PRE_WRAP ||                whitespace == IdentValue.PRE_LINE) {            int n = context.getStartSubstring().indexOf(WhitespaceStripper.EOL);            if (n > -1) {                context.setEnd(context.getStart() + n + 1);                context.setWidth(c.getTextRenderer().getWidth(                        c.getFontContext(), font, context.getCalculatedSubstring()));                context.setNeedsNewLine(true);                context.setEndsOnNL(true);            } else if (whitespace == IdentValue.PRE) {            context.setEnd(context.getLast());                context.setWidth(c.getTextRenderer().getWidth(                        c.getFontContext(), font, context.getCalculatedSubstring()));              }        }        //check if we may wrap        if (whitespace == IdentValue.PRE ||                 (context.isNeedsNewLine() && context.getWidth() <= avail)) {            return;        }                context.setEndsOnNL(false);        String currentString = context.getStartSubstring();        int left = 0;//        int right = currentString.indexOf(WhitespaceStripper.SPACE, left + 1);        int right = getStrRight(currentString,left);        int lastWrap = 0;        int graphicsLength = 0;        int lastGraphicsLength = 0;        while (right > 0 && graphicsLength <= avail) {            lastGraphicsLength = graphicsLength;            graphicsLength += c.getTextRenderer().getWidth(                    c.getFontContext(), font, currentString.substring(left, right));            lastWrap = left;            left = right;//            right = currentString.indexOf(WhitespaceStripper.SPACE, left + 1);            right = getStrRight(currentString,left+1);        }        if (graphicsLength <= avail) {            //try for the last bit too!            lastWrap = left;            lastGraphicsLength = graphicsLength;            graphicsLength += c.getTextRenderer().getWidth(                    c.getFontContext(), font, currentString.substring(left));        }        if (graphicsLength <= avail) {            context.setWidth(graphicsLength);            context.setEnd(context.getMaster().length());            //It fit!            return;        }                context.setNeedsNewLine(true);        if (lastWrap != 0) {//found a place to wrap            context.setEnd(context.getStart() + lastWrap);            context.setWidth(lastGraphicsLength);        } else {//unbreakable string            if (left == 0) {                left = currentString.length();            }                        context.setEnd(context.getStart() + left);            context.setUnbreakable(true);                        if (left == currentString.length()) {                context.setWidth(c.getTextRenderer().getWidth(                        c.getFontContext(), font, context.getCalculatedSubstring()));            } else {                context.setWidth(graphicsLength);            }        }        return;    }    private static boolean isChinese(char c) {        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {            return true;        }        return false;    }    private static int getStrRight(String s,int left){        if(left>=s.length())            return -1;        char[] ch = s.toCharArray();        for(int i = left;i<ch.length;i++){            if(isChinese(ch[i]) || ' ' == ch[i]){                return i==0?i+1:i;            }        }        return -1;    }}

运行只需要core-renderer.jar即可,不用core-renderer-minimal.jar


与itext-2.1.7.jar兼容问题,以flyingsaucer-R8-src源代码目录为例,把itext-2.1.7.jar替换lib目录下的iText-2.0.8.jar,cmd进入flyingsaucer-R8-src源代码目录,%ANT_HOME%\bin\ant jar,重新编译生成core-renderer.jar




对于中文换行,修改org.xhtmlrenderer.layout.Breaker 类,重新编译生成core-renderer.jar,使用注意对于中文换行:

在用textarea的table中加入
style="table-layout:fixed; word-break:break-strict;">??
或在table中加入style="table-layout:fixed“
在textarea中在用style="word-wrap:break-word;“等也可以换行 
关键是table要用样式table-layout:fixed; 然后用强制换行样式

另外,提醒一下,如果替换了? yye_javaeye? 提供的jar包,还不能实现中文换行,可能是因为项目中存在core-renderer-minimal.jar包冲突,

删除它就可以了。

读书人网 >PowerDesigner

热点推荐