xhtmlrenderer渲染pdf,中文换行
在实际开发中,发现在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,中文换行的更多相关文章
- 在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all
在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all 前天来了个新需求, 有一个授权书的文件要点击下载, 需要在前端生成, ...
- 吐血整理:人工智能PDF中文教材资源包2.73G基本包含全部学习资料-人工智能学习书单
吐血整理:人工智能PDF中文教材资源包2.73G基本包含全部学习资料 人工智能学习书单(关注微信公众号:aibbtcom获取更多资源) 文末附百度网盘下载地址 人工神经网络与盲信号处理 人工神经网络与 ...
- Gitbook 生成 pdf 中文字体错乱问题解决办法
Gitbook 生成 pdf 中文字体错乱问题解决办法 用过 Gitbook 的都知道, Gitbook 会自动生成 pdf 以提供下载, 但十分遗憾的是自动生成的 pdf 对中文的支持并不好, ...
- Asp.net Core 3.1 Razor视图模版动态渲染PDF
Asp.net Core 3.1 Razor视图模版动态渲染PDF 前言 最近的线上项目受理回执接入了电子签章,老项目一直是html打印,但是接入的电子签章是仅仅对PDF电子签章,目前还没有Html电 ...
- Asp.net MVC Razor视图模版动态渲染PDF,Razor模版生成静态Html
Asp.net MVC Razor视图模版动态渲染PDF,Razor模版生成静态Html 1.前言 上一篇文章我开源了轮子,Asp.net Core 3.1 Razor视图模版动态渲染PDF,然后,很 ...
- CSS强制英文、中文换行与不换行 强制英文换行
1. word-break:break-all;只对英文起作用,以字母作为换行依据 2. word-wrap:break-word; 只对英文起作用,以单词作为换行依据 3. white-space: ...
- css实现中文换行,英文换行,超出省略
英文换行时,是以单词换行,在对应的标签添加对应的属性即可 1 word-break:break-all;只对英文起作用,以字母作为换行依据 2 word-wrap:break-word; 只对英文起作 ...
- CSS强制英文、中文换行与不换行
.p1{ word-break:break-all; width:150px;}/*只对英文起作用,以字母作为换行依据*/ .p2{ word-wrap:break-word; width:150px ...
- chrome和Firefox对p标签中单词换行的渲染(强制换行)
谷歌和火狐对p标签单词的渲染: 今天在p标签展示url链接中,由于有几个下划线拼接的单词特别长, 所以总有那么几行老是超出p标签的范围,然后设置了强制 换行,才得以解决. word-wrap : br ...
随机推荐
- Linux 添加Nginx 到 service 启动
第一步: 编写nginx文件,放入/etc/init.d/ nginx文件内容如下,粉红色部分为自己实际nginx安装的路径. #!/bin/bash # nginx Startup script f ...
- C#设置word段落首行缩进为0
PublicVar.m_WordApp.Selection.ParagraphFormat.CharacterUnitFirstLineIndent = ; PublicVar.m_WordApp.S ...
- PAT (Advanced Level) 1012. The Best Rank (25)
简单排序题. 注意:分数相同的人排名相同. #include<iostream> #include<cstring> #include<cmath> #includ ...
- jQuery.Autocomplete实现自动完成功能-搜索提示功能
$(function(){ var availableTags=["ads","abc","acc"]; $("#tags&quo ...
- [转] Eclipse 使用 Link 方式进行插件的安装
下方来自 http://www.iteye.com/topic/1113353 Eclipse 的插件安装方法一般有以下几种(以安装 SVN 插件为例说明,Eclipse 版本为:3.7/Indigo ...
- RabbitMQ 消息队列 配置
CentOS 7 x64 rabbitmq 一.CentOS 7 yum 添加epel 源 yum -y install epel-release 1. yum -y install erlang ...
- 在阿里云ECS(CentOS6.5)上安装tomcat
切换到你要安装的目录下 命令: cd /home/ 下载你要安装的tomcat 命令: wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7. ...
- ZOJ 2059 The Twin Towers
双塔DP. dp[i][j]表示前i个物品,分成两堆(可以不全用),价值之差为j的时候,较小一堆的价值为dp[i][j]. #include<cstdio> #include<cst ...
- 100套新鲜免费的PS笔刷下载
这篇文章所有的Photoshop笔刷都是免费且高质量的.笔刷总类齐全:有飞鸟.冰块.水.树枝.喷墨.科技元素.皮肤纹理.烟火等等!用它们来加速你的工作流程,提升作品档次吧!”一挪妖娆举动,一刷风情万种 ...
- Mysql导入zabbix的sql语句时报错:ERROR 1045 (28000)
#Warning: Using a password on the command line interface can be insecure.#ERROR 1045 (28000): Access ...