您的位置:首页 > 其它

iText+Flying Saucer生成pdf文档,中文不显示和不自动换行问题

2015-01-09 11:34 661 查看
一、重写Breaker,添加中文识别

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html // Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: Breaker.java
package org.xhtmlrenderer.layout;
import java.text.BreakIterator;
import org.xhtmlrenderer.css.constants.IdentValue;
import org.xhtmlrenderer.css.style.CalculatedStyle;
import org.xhtmlrenderer.extend.TextRenderer;
// Referenced classes of package org.xhtmlrenderer.layout:
// LineBreakContext, LayoutContext
public class Breaker
{
public Breaker()
{
}
public static void breakFirstLetter(LayoutContext c, LineBreakContext context, int avail, CalculatedStyle style)
{
org.xhtmlrenderer.render.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;
do
{
if (i >= text.length())
break;
char c = text.charAt(i);
int type = Character.getType(c);
if (type != 21 && type != 22 && type != 29 && type != 30 && type != 24)
break;
i++;
} while (true);
if (i < text.length())
i++;
return i;
}
public static void breakText(LayoutContext c, LineBreakContext context, int avail, CalculatedStyle style)
{
org.xhtmlrenderer.render.FSFont font = style.getFSFont(c);
IdentValue whitespace = style.getWhitespace();
if (whitespace == IdentValue.NOWRAP)
{
context.setEnd(context.getLast());
context.setWidth(c.getTextRenderer().getWidth(c.getFontContext(), font, context.getCalculatedSubstring()));
return;
}
if (whitespace == IdentValue.PRE || whitespace == IdentValue.PRE_WRAP || whitespace == IdentValue.PRE_LINE)
{
int n = context.getStartSubstring().indexOf("\n");
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()));
}
}
if (whitespace == IdentValue.PRE || context.isNeedsNewLine() && context.getWidth() <= avail)
return;
context.setEndsOnNL(false);
String currentString = context.getStartSubstring();
int left = 0;
int right = getStrRight(currentString,left+1);
int lastWrap = 0;
int graphicsLength = 0;
int lastGraphicsLength = 0;
for (; right > 0 && graphicsLength <= avail; right =getStrRight(currentString,left+1))
{
lastGraphicsLength = graphicsLength;
graphicsLength += c.getTextRenderer().getWidth(c.getFontContext(), font, currentString.substring(left, right));
lastWrap = left;
left = right;
}
if (graphicsLength <= avail)
{
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());
return;
}
context.setNeedsNewLine(true);
if (lastWrap != 0)
{
context.setEnd(context.getStart() + lastWrap);
context.setWidth(lastGraphicsLength);
} else
{
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);
}
}
public static BreakIterator getWordStream(String s) {
BreakIterator i = BreakIterator.getWordInstance();
i.setText(s);
return i;
}
/**
* 判断是否是中文
* @param c
* @return
*/
private static boolean isChinses(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;
}
/**
* 替换原先本类中所以获取right的方法
* int right = getStrRight(currentString,left+1);
* @param s
* @param left
* @return
*/
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(isChinses(ch[i]) || '\0'==ch[i]){
return i==0?i+1:i;
}
}
return -1;
}
}


二,生成pdf,添加生成pdf所使用的字符集.注:这里字符集要和模板中使用的字符集一一致。 比如:java中使用宋体 renderer.getFontResolver().addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); 那么html的body中样式必须加上 style='font-family:SimSun',要是使用其他字符生成pdf时候,中文就会不显示生成pdf 的

//生成pdf例子
public class MyPdf {
/**
* 使用flying sauce生成pdf
* @param htmlPath c:\\Users\\dfhc\\Desktop\\1015101900000000020.html
* @param savePDFPath c:\\Users\\dfhc\\Desktop\\ssPdf.pdf
* @throws Exception
*/
public static void createPDFByFly(String htmlPath,String savePDFPath) throws Exception{
// step 1
String inputFile = htmlPath;
String url = new File(inputFile).toURI().toURL().toString();
String outputFile = savePDFPath;
// System.out.println(url);
// step 2
OutputStream os = null;
try {
os=new FileOutputStream(outputFile);
org.xhtmlrenderer.pdf.ITextRenderer renderer = new org.xhtmlrenderer.pdf.ITextRenderer();
// linux:
// fontResolver.addFont("/usr/share/fonts/TTF/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.getFontResolver().addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.setDocument(url);
renderer.layout();
renderer.createPDF(os);
renderer.finishPDF();
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException(e.getMessage());
}finally{
if (os != null) {
try {
os.close();
} catch (IOException e) {
// ignore
}
}
}
}
public static void main(String[] args) {
try {
createPDFByFly("c:\\Users\\dfhc\\Desktop\\1000101900000000015.html", "c:\\Users\\dfhc\\Desktop\\1000101900000000015.pdf");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


三、设置pdf的页面大小模板页面中添加该样式:@page { size: 8.5in 11in; }这时候生成pdf页面正好是A4纸大小

四、所需的jar包http://download.csdn.net/detail/shiyuqiong/8343881,该核心jar是修改后的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: