在实际开发中,发现在table中显示中文,渲染出来的pdf,中文内容不自动换行。经过搜索发现了一种解决方案,如下:

重写Breaker,修改right计算方式

/*
* 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;
}
}

xhtmlrenderer渲染pdf,中文换行的更多相关文章

  1. 在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all

    在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all 前天来了个新需求, 有一个授权书的文件要点击下载, 需要在前端生成, ...

  2. 吐血整理:人工智能PDF中文教材资源包2.73G基本包含全部学习资料-人工智能学习书单

    吐血整理:人工智能PDF中文教材资源包2.73G基本包含全部学习资料 人工智能学习书单(关注微信公众号:aibbtcom获取更多资源) 文末附百度网盘下载地址 人工神经网络与盲信号处理 人工神经网络与 ...

  3. Gitbook 生成 pdf 中文字体错乱问题解决办法

    Gitbook 生成 pdf 中文字体错乱问题解决办法   用过 Gitbook 的都知道, Gitbook 会自动生成 pdf 以提供下载, 但十分遗憾的是自动生成的 pdf 对中文的支持并不好, ...

  4. Asp.net Core 3.1 Razor视图模版动态渲染PDF

    Asp.net Core 3.1 Razor视图模版动态渲染PDF 前言 最近的线上项目受理回执接入了电子签章,老项目一直是html打印,但是接入的电子签章是仅仅对PDF电子签章,目前还没有Html电 ...

  5. Asp.net MVC Razor视图模版动态渲染PDF,Razor模版生成静态Html

    Asp.net MVC Razor视图模版动态渲染PDF,Razor模版生成静态Html 1.前言 上一篇文章我开源了轮子,Asp.net Core 3.1 Razor视图模版动态渲染PDF,然后,很 ...

  6. CSS强制英文、中文换行与不换行 强制英文换行

    1. word-break:break-all;只对英文起作用,以字母作为换行依据 2. word-wrap:break-word; 只对英文起作用,以单词作为换行依据 3. white-space: ...

  7. css实现中文换行,英文换行,超出省略

    英文换行时,是以单词换行,在对应的标签添加对应的属性即可 1 word-break:break-all;只对英文起作用,以字母作为换行依据 2 word-wrap:break-word; 只对英文起作 ...

  8. CSS强制英文、中文换行与不换行

    .p1{ word-break:break-all; width:150px;}/*只对英文起作用,以字母作为换行依据*/ .p2{ word-wrap:break-word; width:150px ...

  9. chrome和Firefox对p标签中单词换行的渲染(强制换行)

    谷歌和火狐对p标签单词的渲染: 今天在p标签展示url链接中,由于有几个下划线拼接的单词特别长, 所以总有那么几行老是超出p标签的范围,然后设置了强制 换行,才得以解决. word-wrap : br ...

随机推荐

  1. java中创建多线程的方式

    在java中比较常用的有三种创建多线程的方式. 方式一:继承Thread类,要重写run方法. 在MyThread类 public class MyThread extends Thread { @O ...

  2. ASP.NET MVC3中的路由系统(Routes) .

    MVC中,用户访问的地址并不映射到服务器中对应的文件,而是映射到对应Control里对应的ActionMethod,由ActionMethod来决定返回用户什么样的信息.而把用户访问的地址对应到对应的 ...

  3. Android JNI入门第六篇——C调用Java

    本篇将介绍在JNI编程中C调用Java实现. 源码下载地址:http://download.csdn.net/detail/xyz_lmn/4868265 关键代码: java: public cla ...

  4. 目前所有的ANN神经网络算法大全

    http://blog.sina.com.cn/s/blog_98238f850102w7ik.html 目前所有的ANN神经网络算法大全 (2016-01-20 10:34:17) 转载▼ 标签: ...

  5. [转] SpringJdbc的几种不同的用法

    转自:http://vsp.iteye.com/blog/1182887 Spring对jdbc做了良好的封装,本人在学习时做了以下几种方式的尝试 首页先来创建一个dao接口 package com. ...

  6. 安装PIL遇到的问题

    配置:Win7 64位 不过折腾到最后,没有使用PIL,官方的PIL很久木有更新了,换了Pillow,是PIL的衍生吧,一直有更新,但是两者不可在同一环境共存. 1 Python version 2. ...

  7. Unity 3d中Shader是什么,可以吃吗?

    众所周知,Unity3d是一款跨平台非常广的游戏引擎,上手容易,界面友好,集成功能众多,是目前开发手游的主流引擎.本人有幸使用Unity 3d进行开发已一年多时间,已领略了这歀引擎的强大之处. 编写s ...

  8. FTP服务器配置部分

    构建基于虚拟用户的vsftpd服务器1.建立虚拟FTP用户的帐号数据库文件 (1) 建立虚拟用户的账户名.密码列表->奇数行为帐号名,偶数行为上一行中帐号的密码 (2) 转化为Berkeley ...

  9. jquery刷新iframe页面的方法(兼容主流)

    1,reload 方法,该方法强迫浏览器刷新当前页面.语法:location.reload([bForceGet])   参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取 ...

  10. Xcode6之后创建Pch预编译文件

    在Xcode6之前,创建一个新工程xcode会在Supporting files文件夹下面自动创建一个“工程名-Prefix.pch”文件,也是一个头文件,pch头文件的内容能被项目中的其他所有源文件 ...