html转pdf问题记录,中文不显示,中文不换行,css样式无效

1 篇文章 0 订阅

代码示例:

public static void htmlToPDF(String pdfPath, String htmlPath) throws Exception {
        try {
            ITextRenderer renderer = new ITextRenderer();
            ITextFontResolver fontResolver = renderer.getFontResolver();
            OutputStream os = new FileOutputStream(pdfPath);

            String url = new File(htmlPath).toURI().toURL().toString();
            renderer.setDocument(url);
            
            //设置字体库路径,获取文件再磁盘上的绝对路径
            String simsunpath="";
            String arialpath="";
            fontResolver.addFont(simsunpath, BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
            fontResolver.addFont(arialpath, BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
            renderer.layout();
            renderer.createPDF(os, false);
            renderer.finishPDF();
            os.close();
        } catch (Exception e) {
            //处理异常
            //_log.error("htmlToPDF出现异常!", e);
        }
    }

常见问题:

一.中文不显示:

1.引用字体文件,simsun.ttc和arial.ttf,百度下载

2.html格式符合要求,必须有html标签,且所有标签必须闭合,且body必须设置字体,示例如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

<body style="font-family:SimSun;">
中文
test
<img src="../_images/cms/pl.png" height="16" width="16"/>
</body>
</html>

二.中文不换行

原来的jar不支持中文换行,需要自己增加语言环境判断和中文兼容

不管使用core-renderer还是flying-saucer-pdf,都可以修改org.xhtmlrenderer.layout.Breaker

从jar包中反编译出代码,修改换行代码:

示例:

package org.xhtmlrenderer.layout;

/**
 * @author 12550
 * @program: 02src
 * @description: 解决中文不换行
 * @date 2021-04-20 14:46:40
 */

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) {
        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 != 21) && (type != 22) && (type != 29) && (type != 30) && (type != 24)) {
                break;
            }

            i++;
        }

        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();

        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 = currentString.indexOf(" ", 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(" ", left + 1);
            right = getStrRight(currentString, left+1);
        }

        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);
        }
    }

    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;
    }

}

三 css样式文件无效

。。。待补充

 

 

 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
1、解决中文问题 2、附字体 3、动态html拼接pdf public static void htmlCodeComeString(String linkcss,String htmlCode, String outputFile,String title) throws Exception { OutputStream os = new FileOutputStream(outputFile); ITextRenderer renderer = new ITextRenderer(); renderer.setDocumentFromString(getConversionHtmlCode(linkcss,htmlCode,title)); ITextFontResolver fontResolver = renderer.getFontResolver(); URL fontPath = ItextUtil.class.getResource("simsun.ttc"); fontResolver.addFont(fontPath.toString(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 解决图片的相对路径问题 // renderer.getSharedContext().setBaseURL("file:/F:/teste/html/"); renderer.layout(); renderer.createPDF(os); System.out.println("======换成功!"); os.close(); os.flush(); } public static void main(String[] args) { ItextUtil itextUtil = new ItextUtil(); String html = ""; html += ""; html += "企业信息"; html += " "; html += " "; html += " 登记日期"; html += " 2006-04-28"; html += " "; html += " "; html += " 纳税人编号"; html += " HSJIHKS002"; html += " "; html += " "; html += " 有效标志"; html += " Y"; html += " "; html += " "; html += " 社会信用代码"; html += " 916101317H"; html += " "; html += " "; html += " 评估机关代码"; html += " 盛世"; html += " "; html += " "; html += " 工商注销日期"; html += " 2006-04-28"; html += " "; html += " "; html += ""; String outputFile = "D:\\pdf\\aa.pdf"; try { itextUtil.htmlCodeComeString("",html,outputFile,""); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("生成结束!!!"); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值