xhtmlrenderer进行HTML转PDF【解决中文、数字、英文过长自动换行问题】

首先,当然是找到能够解析PDF的完美组件,百度和谷歌不约而同的告诉我们。IText是王道。而目前开源的组件中,Itext的确是一个First Choice,如果各位单纯是做把图片转成PDF或者自己写了Velocity或者FreeMarker模板生成了HTML是非常推荐直接用Itext来进行的。

下面就是用Flying Saucer(xhtmlrendere)来实现的代码:

loading...

传入对应的HTML路径和PDF生成完成后的输入路径,字体我是先在工程中建立一个文件夹然后把对应的字体放入进去,这样做的一个好处不管工程是在Windows还是linux都可以识别出来使用的字体。renderer.getSharedContext().setBaseURL(src);指定图片的路径。

修改源码包中的BREAK.class重新计算右边距即可解决,代码:

/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. **/
/*     */ package org.xhtmlrenderer.layout;
/*     */
/*     */ import org.xhtmlrenderer.css.constants.IdentValue;
/*     */ import org.xhtmlrenderer.css.style.CalculatedStyle;
/*     */ import org.xhtmlrenderer.extend.TextRenderer;
/*     */ import org.xhtmlrenderer.render.FSFont;
/*     */
/*     */ public class Breaker
/*     */ {
/*     */ public static void breakFirstLetter(LayoutContext c, LineBreakContext context, int avail,
CalculatedStyle style)
/*     */ {
/*  12 */ FSFont font = style.getFSFont(c);
/*  13 */ context.setEnd(getFirstLetterEnd(context.getMaster(), context.getStart()));
/*  14 */ context.setWidth(
c.getTextRenderer().getWidth(/*  15 */ c.getFontContext(), font, context.getCalculatedSubstring()));
/*     */
/*  17 */ if (context.getWidth() > avail) {
/*  18 */ context.setNeedsNewLine(true);
/*  19 */ context.setUnbreakable(true);
/*     */ }
/*     */ }
/*     */
/*     */ private static int getFirstLetterEnd(String text, int start) {
/*  24 */ int i = start;
/*  25 */ while (i < text.length()) {
/*  26 */ char c = text.charAt(i);
/*  27 */ int type = Character.getType(c);
/*  28 */ if ((type != 21) &&
/*  29 */ (type != 22) &&
/*  30 */ (type != 29) &&
/*  31 */ (type != 30) &&
/*  32 */ (type != 24))
break;
/*  33 */ ++i;
/*     */ }
/*     */
/*  36 */ if (i < text.length()) {
/*  37 */ ++i;
/*     */ }
/*  39 */ return i;
/*     */ }
/*     */
/*     */ public static void breakText(LayoutContext c, LineBreakContext context, int avail, CalculatedStyle style)
/*     */ {
/*  44 */ FSFont font = style.getFSFont(c);
/*  45 */ IdentValue whitespace = style.getWhitespace();
/*     */
/*  47 */ if (whitespace == IdentValue.NOWRAP) {
/*  48 */ context.setEnd(context.getLast());
/*  49 */ context.setWidth(
c.getTextRenderer().getWidth(/*  50 */ c.getFontContext(), font, context.getCalculatedSubstring()));
/*  51 */ return;
/*     */ }
/*     */
/*  54 */ if ((whitespace == IdentValue.PRE) ||
/*  55 */ (whitespace == IdentValue.PRE_WRAP) ||
/*  56 */ (whitespace == IdentValue.PRE_LINE)) {
/*  57 */ int n = context.getStartSubstring().indexOf("\n");
/*  58 */ if (n > -1) {
/*  59 */ context.setEnd(context.getStart() + n + 1);
/*  60 */ context.setWidth(c.getTextRenderer().getWidth(/*  61 */ c.getFontContext(), font,
context.getCalculatedSubstring()));
/*  62 */ context.setNeedsNewLine(true);
/*  63 */ context.setEndsOnNL(true);
/*  64 */ } else if (whitespace == IdentValue.PRE) {
/*  65 */ context.setEnd(context.getLast());
/*  66 */ context.setWidth(c.getTextRenderer().getWidth(/*  67 */ c.getFontContext(), font,
context.getCalculatedSubstring()));
/*     */ }
/*     */
/*     */ }
/*     */
/*  72 */ if ((whitespace == IdentValue.PRE) || (
/*  73 */ (context.isNeedsNewLine()) && (context.getWidth() <= avail))) {
/*  74 */ return;
/*     */ }
/*     */
/*  77 */ context.setEndsOnNL(false);
/*     */
/*  79 */ String currentString = context.getStartSubstring();
/*  80 */ int left = 0;
/*     */
/*  82 */ int right = getStrRight(currentString, left + 1);
/*  83 */ int lastWrap = 0;
/*  84 */ int graphicsLength = 0;
/*  85 */ int lastGraphicsLength = 0;
/*     */
/*  87 */ while ((right > 0) && (graphicsLength <= avail)) {
/*  88 */ lastGraphicsLength = graphicsLength;
/*     */
/*  91 */ graphicsLength = graphicsLength + c.getTextRenderer()/*  91 */ .getWidth(c.getFontContext(), font,
currentString.substring(left, right));
/*  92 */ lastWrap = left;
/*  93 */ left = right;
/*     */
/*  95 */ right = getStrRight(currentString, left + 1);
/*     */ }
/*     */
/*  98 */ if (graphicsLength <= avail)
/*     */ {
/* 100 */ lastWrap = left;
/* 101 */ lastGraphicsLength = graphicsLength;
/*     */
/* 104 */ graphicsLength = graphicsLength
+ c.getTextRenderer()/* 104 */ .getWidth(c.getFontContext(), font, currentString.substring(left));
/*     */ }
/*     */
/* 107 */ if (graphicsLength <= avail) {
/* 108 */ context.setWidth(graphicsLength);
/* 109 */ context.setEnd(context.getMaster().length());
/*     */
/* 111 */ return;
/*     */ }
/*     */
/* 114 */ context.setNeedsNewLine(true);
/*     */
/* 116 */ if (lastWrap != 0) {
/* 117 */ context.setEnd(context.getStart() + lastWrap);
/* 118 */ context.setWidth(lastGraphicsLength);
/*     */ } else {
/* 120 */ if (left == 0) {
/* 121 */ left = currentString.length();
/*     */ }
/*     */
/* 124 */ context.setEnd(context.getStart() + left);
/* 125 */ context.setUnbreakable(true);
/*     */
/* 127 */ if (left == currentString.length())
/* 128 */ context.setWidth(c.getTextRenderer().getWidth(/* 129 */ c.getFontContext(), font,
context.getCalculatedSubstring()));
/*     */ else/* 131 */ context.setWidth(graphicsLength);
/*     */ }
/*     */ }
/*     */
/*     */ private static boolean isChinese(char c)
/*     */ {
/* 137 */ Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
/*     */
/* 144 */ return ((ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS) ||
/* 139 */ (ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS) ||
/* 140 */ (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A) ||
/* 141 */ (ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION) ||
/* 142 */ (ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) ||
/* 143 */ (ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS));
/*     */ }
/*     */
/*     */ private static int getStrRight(String a, int left)
/*     */ {
/* 150 */ if (left > a.length())
return -1;
/* 151 */ char[] ch = a.toCharArray();
/* 152 */ int i = left;
if (i < ch.length) {
/* 153 */ if ((isChinese(ch[i])) || (' ' == ch[i])) {
/* 154 */ return ((i == 0) ? i + 1 : i);
/*     */ }
/* 156 */ return ((i == 0) ? i + 1 : i);
/*     */ }
/*     */
/* 159 */ return -1;
/*     */ }
/*     */ }

本人是个新手程序员,如有写错请大牛指导,有关xhtmlrenderer进行HTML转PDF的知识可以互相交流。

展开阅读全文

没有更多推荐了,返回首页