天天看点

itextpdf将html转成pdf,包含中文字体以及中文换行

1、maven文件下载

    <dependency>  

            <groupId>com.itextpdf</groupId>  

            <artifactId>itextpdf</artifactId>  

            <version>5.5.9</version>

        </dependency>  

         <dependency>  

            <groupId>com.itextpdf.tool</groupId>  

            <artifactId>xmlworker</artifactId>  

            <version>5.5.9</version>

        </dependency>  

        <dependency>  

            <groupId>com.itextpdf</groupId>  

            <artifactId>itext-asian</artifactId>  

            <version>5.2.0</version>

        </dependency>  

        <dependency>

            <groupId>org.xhtmlrenderer</groupId>

            <artifactId>flying-saucer-pdf-itext5</artifactId>

            <version>9.0.3</version>

        </dependency>

2、重写Breaker.java文件,用于中文换行

      新建org.xhtmlrenderer.layout文件夹,新建一个java文件,将以下内容粘贴进去

package org.xhtmlrenderer.layout;

import org.xhtmlrenderer.css.constants.IdentValue;

import org.xhtmlrenderer.css.style.CalculatedStyle;

import org.xhtmlrenderer.render.FSFont;

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;

    }

}

3、html转换pdf代码

public class FileTypeConvertUtil {

    public static void html2pdf(String content, String pdfFile) throws Exception {

        OutputStream os = new FileOutputStream(pdfFile);

        ITextRenderer renderer = new ITextRenderer();

        StringBuffer html = new StringBuffer(); 

        content = content.replace("宋体", "SimSun");

        content = content.replace("黑体", "SimHei");

        content = content.replace("微软雅黑", "Microsoft YaHei");

        content = content.replace("微软正黑体", "Microsoft JhengHei");

        content = content.replace("新宋体", "NSimSun");

        content = content.replace("仿宋", "FangSong");

        content = content.replace("楷体", "KaiTi");

        content = content.replace("仿宋_GB2312", "FangSong_GB2312");

        content = content.replace("楷体_GB2312", "KaiTi_GB2312");

        content = content.replace("font-family:&quot;", "font-family:SimSun;");

        content = content.replace("font-family:&quot;&quot;", "font-family:SimSun;");

        // DOCTYPE 必需写否则类似于 这样的字符解析会出现错误  

        html.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");  

        html.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">").append("<head>")  

            .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />")

            .append("<meta name=\"viewport\" content=\"initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width\"/>")

            .append("<link rel=\"stylesheet\" href=\"https://static.loyalvalleycapital.com/web/css/frame.css\"/>")

            .append("<style type=\"text/css\" mce_bogus=\"1\">"

                    + "body {font-family: 宋体;} "

                    + "table { border-collapse: collapse; table-layout: fixed;word-break:break-strict;font-size: 10px; width: 100%;text-align: center;widths:\"50;10;40\"}"

                    + "td {word-break:break-all;word-wrap : break-word; } "

                    + "@page { size:210mm 297mm;margin: 0.25in; -fs-flow-bottom: \"footer\"; -fs-flow-left: \"left\"; -fs-flow-right: \"right\"; padding: 1em; } "

                    + "#footer { font-size: 90%; font-style: italic; position: absolute; top: 0; left: 0; -fs-move-to-flow: \"footer\"; } "

                    + "#pagenumber:before { content: counter(page); } #pagecount:before {content: counter(pages); }</style>")

            .append("</head>")  

            .append("<body style = \"font-family: SimSun;\">"

                    + "<div style=\"width: 700px;\"><div id=\"footer\" style=\"\">  Page <span id=\"pagenumber\"/> of <span id=\"pagecount\"/> </div>")

            .append("<div class='inner' style='width:698px;overflow-x:auto;font-size:14px;color:#333;font-family:微软雅黑;line-height:2;'>");

        html.append("<div>"+content+"</div></div></div>");  

        html.append("</body></html>");

renderer.setDocumentFromString(html.toString());

        ITextFontResolver fontResolver = renderer.getFontResolver();

        if("linux".equals(getCurrentOperatingSystem())){

            fontResolver.addFont("/usr/share/fonts/chiness/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

        }else{

            fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/simfang.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/msyh.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/msyhbd.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/STKAITI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/STLITI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/仿宋_GB2312.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            fontResolver.addFont("C:/Windows/Fonts/楷体_GB2312.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

        }

        renderer.layout();

        renderer.createPDF(os);

        os.close();

        System.out.println("create pdf done!!");

    }

    public static String getCurrentOperatingSystem(){

        String os = System.getProperty("os.name").toLowerCase();

        System.out.println("---------当前操作系统是-----------" + os);

        return os;

    }

    public static void main(String[] args) {

        String content = "html内容";

        String pdfFile = "d:/testoone.pdf";

        try {

            FileTypeConvertUtil.html2pdf(content, pdfFile);

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

备注:html里面需要添加上一下代码

 html.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");  

        html.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">").append("<head>")  

            .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />")

table的样式需要添加table-layout: fixed;word-break:break-strict;是为了中文代码换行。