在项目中,利用iText和flying saucer生成pdf文件,网上所说的中文不显示的问题倒是没有遇到,不过就是中文字体时,由于字符宽度是按字母计算的,同样字数会导致一行显示很长不换行,从而超过版面宽度显示不全的问题。经过分析和查找,终于的到解决方案,另外也解决了中文标点符号出现在行首的现象。
首先,我们要明白这几个东西的真实含义:
Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS : 4E00-9FBF:CJK 统一表意符号
Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS :F900-FAFF:CJK 兼容象形文字Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A :3400-4DBF:CJK 统一表意符号扩展 A
CJK的意思是“Chinese,Japanese,Korea”的简写 ,实际上就是指中日韩三国的象形文字的Unicode编码
Character.UnicodeBlock.GENERAL_PUNCTUATION :2000-206F:常用标点Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION :3000-303F:CJK 符号和标点Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS :FF00-FFEF:半角及全角形式
在flying saucer生成pdf的过程中,源代码中是按组和行宽来换行的,具体逻辑如下:
以空格为分组符,任意两个相邻空格之间的字符都是不可换行的,当该行多组字符的总长到达最接近行宽的时候,也就是再加一个字符组就会超过行宽的时候,就会换行
这种方式对英文是很凑效的,但是对中文是不行的,因为中文不是以空格分隔的。yye_javaeye老兄对源码做了改进,判断是否是中文字符,如果是中文字符,则把每个中文字符做一组,然后再用组+行宽来换行。他添加了两个方法:isChinese(char c)和getStrRight(String s,int left), 改过后的部分源码如下:
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 Torbjrn Gannholm
*/
public class Breaker {
。。。。。。
public static void breakText(LayoutContext c,
LineBreakContext context, int avail, CalculatedStyle style) {
。。。。。。
String currentString &