iText+Flying Saucer生成pdf文档,中文不显示和不自动换行问题
2015-01-09 11:34
661 查看
一、重写Breaker,添加中文识别
二,生成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的页面大小模板页面中添加该样式:@page { size: 8.5in 11in; }这时候生成pdf页面正好是A4纸大小
四、所需的jar包http://download.csdn.net/detail/shiyuqiong/8343881,该核心jar是修改后的
// 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是修改后的
相关文章推荐
- 使用itext将html生成pdf中文换行问题解决方案
- 用itext生成带表格的PDF,并显示中文问题
- itext+flying saucer 生成PDF不换行
- ITEXT5.5.8转html为pdf文档解决linux不显示中文问题
- springMVC中itext生成PDF,根本上解决中文乱码以及不显示问题
- iText7 生成 PDF 文件,解决各种操作系统中文问题,控制指定位置显示图片、文字、图文混排
- Java iText 动态 生成 PDF 文档表格中文问题
- 使用itext将html生成pdf中文换行问题解决方案2
- 通过swagger2markup+asciidoctorj生成html和pdf文档并解决asciidoctorj生成的pdf文件中文显示不全问题(maven方式及java代码方式)
- 利用jasperreports报表生成pdf文档中文不能显示问题解决方法
- 利用itext导出HTML到PDF,解决中文不显示和中文不换行的问题
- iText自动生成多页PDF时,解决背景(水印)只显示第一页的问题
- java 用itext-asian解决itext pdf中文不显示问题
- 用itext生成pdf报表下篇(解决中文问题)
- Android用itext生成含中文的PDF文档
- itext应用HTML模版生成PDF并加水印,处理了中文问题
- iReport5.0.1生成PDF文档解决中文不显示方法
- android中的使用itextpdf转成pdf时,显示中文的问题
- java-pdf-itext 生成pdf 文档(支持中文字体)
- .net iText 生成pdf 图片平铺,表格边框隐藏和中文问题