在实际开发中,发现在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. FZU Problem 2213 Common Tangents

    其实是不太好意思往博客上放的,因为是一道巨水的题,但是我却错了一次,没有判断重合,放上还是为了警示自己,尽量不要在水题上罚时 #include<iostream> #include< ...

  2. 根据浏览器UA信息进行跳转(移动和pc)

    如何用php判断一个客户端是手机还是电脑?其实很简单,开发人员都知道,通过浏览器访问网站时,浏览器都会向服务器发送UA,即User Agent(用户代理).不同浏览器.同一浏览器的不同版本.手机浏览器 ...

  3. (H5)FormData+AJAX+SpringMVC跨域异步上传文件

    最近都没时间整理资料了,一入职就要弄懂业务,整天被业务弄得血崩. 总结下今天弄了一个早上的跨域异步上传文件.主要用到技术有HTML5的FormData,AJAX,Spring MVC. 首先看下上传页 ...

  4. spring boot + neo4j restful

    整整折腾了三天,终于把spring boot + neo4j的路走通了. 这里介绍3个部分,pom,entity,repository 1)pom <?xml version="1.0 ...

  5. protobuf python api

    摘要: python中一切都可以看作类.那么如何查看每个类的API.使用ipython python  protobuf 的函数在message中定义 此处所有的api说明:https://devel ...

  6. Lua学习系列(四)

    lua 资源:http://www.dcc.ufrj.br/~fabiom/lua/ 第一个Lua程序 http://www.dcc.ufrj.br/~fabiom/lua/ 原文:https://w ...

  7. cocos2dx 3.2 的中国象棋游戏

    改编来源:http://cn.cocos2d-x.org/tutorial/lists?id=103 在cocos2dx官网看到了这么个教程,是cocos2dx 2.x版本的,于是用 cocos2dx ...

  8. arcengine C#关于动态添加图层

    动态加载影像图层为例 研究了两三天算是弄出来了.本例适合影像数据量特别的大程序使用,可以动态的添加删除影像数据,还有不完善的地方,不过基本满足要求. 1.首先得到关键点的图层 m_Map = axMa ...

  9. Monitorix 监控 安装配置

    Monitorix 监控 安装配置 1. 首先安装RPMforge RPMforge 是由 Dag 及其他包裝者合作維護的.他們為 CentOS 提供超過 5000 個套件,包括 wine.vlc.m ...

  10. matlab中gatbx工具箱的添加

    1. 从http://crystalgate.shef.ac.uk/code/下载工具箱压缩包gatbx.zip 2. 解压gatbx.zip,将其子文件夹genetic放在matlab安装目录too ...