ITextRenderers html生成pdf 分页+横向

1.pdf横向生成问题:格式化html是加上

@page{size:297mm 210mm;}
 public static String formatPdfHtml(String html,String direction) {
        try {
            StringBuilder htmlStr = new StringBuilder();
            htmlStr.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
            htmlStr.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
            htmlStr.append("<head>");
            htmlStr.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
            htmlStr.append("${style_text}");
            htmlStr.append("</head>");
            htmlStr.append("<body>");
            htmlStr.append("${content_text}");
            htmlStr.append("</body>");
            htmlStr.append("</html>");
            StringBuilder styleStr = new StringBuilder();
            StringBuilder styleBody = new StringBuilder();
            styleStr.append("<style type=\"text/css\" ce_bogus=\"1\">");
            if(StringUtils.isNotBlank(direction) && direction.equals("h")){
                styleStr.append("@page{size:297mm 210mm;} body {font-family: Arial Unicode MS;font-size: 16px;}");
            }else{
                styleStr.append(" body {font-family: Arial Unicode MS;font-size: 16px;}");
            }
            Document docHtml = Jsoup.parse(html);
            Elements styles = docHtml.getElementsByTag("style");
            for (Element style : styles) {
                String[] allStyle = StringUtils.split(style.html(), "}");
                for (String s : allStyle) {
                    String[] styleOne = StringUtils.split(s, "{");
                    String[] body = StringUtils.split(styleOne[1], ";");
                    styleBody.setLength(0);
                    for (String s1 : body) {
                        styleBody.append(StringUtils.trim(s1) + ";");
                    }
                    s = StringUtils.trim(styleOne[0]) + "{" + styleBody.toString() + "}";
                    s = StringUtils.replace(s, ";;", ";");
                    //System.out.println(s);
                    if (!StringUtils.containsIgnoreCase(styleStr.toString(), s)) {
                        styleStr.append(s + "\r\n"); //重复的样式不再添加
                    }
                }
            }
            styleStr.append("</style>");

            Elements allelements = docHtml.getAllElements();
            updateAttributes(allelements);


            Iterator<Element> styleIterator = styles.iterator();
            while (styleIterator.hasNext()) {
                Element element = styleIterator.next(); //将body里面的style样式【类】全部删掉
                element.remove();
            }

            StringBuilder cssStr = new StringBuilder();
            Elements elements = docHtml.select("[style]"); //获取所有元素上的样式【属性】
            Iterator<Element> iterator = elements.iterator();
            while (iterator.hasNext()) {
                cssStr.setLength(0);
                Element element = iterator.next();
                String style = element.attr("style");
                if (StringUtils.isNotBlank(style)) {
                    style = StringUtils.trim(style);
                    String[] ss1 = StringUtils.split(style, ";");
                    for (String s : ss1) {
                        cssStr.append(s + ";");
                    }
                    element.removeAttr("style");
                    element.attr("style", cssStr.toString());
                }
            }
            docHtml.outputSettings(new Document.OutputSettings().syntax(Document.OutputSettings.Syntax.xml));
            String newHtml = StringUtils.replace(htmlStr.toString(), "${content_text}", docHtml.body().html());
            newHtml = StringUtils.replace(newHtml, "${style_text}", styleStr.toString());
            newHtml = StringUtils.replace(newHtml, "&nbsp;", "");
            return newHtml;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return html;
    }

2.分页问题,生成html是在需要分页的地方加上

<div class='page_break_div' style='page-break-after: always'></div>

分页js

/**
 * html生成pdf分页
 * html格式化之前不能隐藏
 * 如需每页都有head或者foot  将head放入<thead></thead> 将foot放入<tfoot></tfoot>
 * 分页代码:<div class='page_break_div' style='page-break-after: always'></div>
 */
/*var page_head = ""; //每页的头部
$(".page_head").each(function () {
    page_head = $(this);
});
var page_foot = "";
$(".page_foot").each(function () {
    page_foot = page_foot + $(this);
});*/

/**
 * 遍历原数据表格,按高度生成新表格
 * */
$(".pdf_data_table").each(function () {
    var table = $(this);
    var direction = $(this).attr("direction")
    var page_height = ''; //每页的高度 默认500px

    if (direction == '') {
        direction = 'v';
    }
    if (page_height == '') {
        if (direction == 'v') {
            page_height = 900; //word纸张方向 竖=500 横=450
        } else {
            page_height = 650; //word纸张方向 竖=500 横=450
        }
    }
    var tbody = table.find("tbody");
    var maxIndex = tbody.find("tr").length - 1;
    var tempTable = null;
    var tempHeight = 0
    tbody.find("tr").each(function (index) {
        var tr = $(this);
        if (index == 0) {
            tempTable = createDivAndTable(table);
            tempTable.find("tbody").append(tr.clone());
            tempHeight = tempTable.height()
        } else {
            /*if (page_head != '') {
                tempHeight = tempHeight + page_head.height();
            }*/
            tempHeight = tempHeight + tr.height();
            /*if (page_foot != '') {
                tempHeight = tempHeight + page_foot.height();
            }*/
            if (tempHeight > page_height) {
                tempTable = createDivAndTable(table);
                tempTable.find("tbody").append(tr.clone());
                tempHeight = 0
            } else {
                tempTable.find("tbody").append(tr.clone());
            }
        }
    });
    $("#content").hide();
});
//data_div为原来html位置
$("#data_div").remove(); //移除旧表格
$('.page_break_div:last').remove(); //删除最后一个表格分页符
// $('.page_break:last').removeAttr('style');


/**
 * 生成新表格对象
 * */
function createDivAndTable(table) {
    //var pageDiv = $("<div style='page-break-after:always' class='page_break'></div>");
    var pageDiv = $("<div style='' class='page_break'></div>");
    var div = $("<div class='page_break_div' style='page-break-after: always'></div>");
    var tempTable = table.clone(); //克隆表格
    var body = tempTable.find("tbody");
    body.find("tr").remove(); //移除tbody中所有的tr,然后重新添加以便正确分页
    /*if (page_head != '') {
        pageDiv.append(page_head.clone());
    }*/

    pageDiv.append(tempTable);
    /*if (page_foot != '') {
        pageDiv.append(page_foot.clone());
    }*/
    pageDiv.append(div);
    //格式话之后html的位置
    $("#data_div_new").append(pageDiv);
    return tempTable;
}

demo

html(freemarker)

<div class="layui-col-xs12" style="margin-top: 15px;" >
    <div class="layui-card" id="content">
        <div class="layui-card-body">
            <div class="layui-row">
                <div class="layui-col-xs12">
                    <div style="-webkit-tap-highlight-color:rgba(0, 0, 0, 0);overflow-x:auto;min-height:0.01%;" id="data_div">
                        <table class="pdf_data_table" direction="h" style="padding:0px;font-size:14px;border-spacing:0px;width:100%;word-wrap:break-word;">
                            <thead>
                            <tr style="text-align: center">
                                <td style="box-sizing:border-box;margin:0px;padding:6px;border:0px;" colspan="${psgzmxes?size+3}">
                                    <span style="font-size: 18px"><b>技术评分表</b></span>
                                </td>
                            </tr>
                            <tr style="height: 15px;">
                                <td style="box-sizing:border-box;margin:0px;padding:6px;border:0px;"
                                    colspan="${psgzmxes?size+3}">
                                    <span>项目名称:${xm.name!}</span>
                                    <span style="float: right">项目编号:${xm.code!}</span>
                                </td>
                            </tr>
                            <tr style="height: 15px;">
                                <td style="box-sizing:border-box;margin:0px;padding:6px;border:0px;"
                                    colspan="${psgzmxes?size+3}">
                                    <span>开标时间:${xm.kbdate?string('yyyy-MM-dd HH:mm')}</span>
                                    <span style="float: right">标包名称:${bd.bdname!}</span>
                                </td>
                            </tr>
                            <tr style="text-align: center">
                                <td rowspan="2"
                                    style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 40px">
                                    序号
                                </td>
                                <td rowspan="2"
                                    style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 280px;">
                                    供应商名称
                                </td>
                                <td colspan="${psgzmxes?size}"
                                    style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;">
                                    技术部分(${jsscoresum}分)
                                </td>
                                <td rowspan="2"
                                    style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 150px">
                                    合计得分
                                </td>
                            </tr>
                            <tr style="text-align: center">
                                <#list psgzmxes as mx>
                                    <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: ${800/psgzmxes?size}px">${mx.pscontent}
                                        <br/>(${mx.highestscore?string('0.00')}分)
                                    </td>
                                </#list>

                            </tr>
                            </thead>
                            <tbody>
                            <#list psTbrList as tbr>
                                <tr style="text-align: center">

                                    <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 40px">${tbr_index+1}</td>
                                    <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 280px;">${(tbr.tbr.ztname)!}</td>
                                    <#list psgzmxes as mx>
                                        <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: ${800/psgzmxes?size}px">
                                            <#list zjdfList as df>
                                                <#if df.psgzmxid== mx.id && df.pbpstbrid==tbr.id>
                                                    <#if df.score??>${df.score?string('0.00')}</#if>
                                                </#if>
                                            </#list>
                                        </td>

                                    </#list>

                                    <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 150px"><#if (tbr.score)??>${tbr.score?string('0.00')}</#if></td>
                                </tr>
                            </#list>
                            <#list psTbrList as tbr>
                                <tr style="text-align: center">

                                    <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 40px">${tbr_index+1}</td>
                                    <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 280px;">${(tbr.tbr.ztname)!}</td>
                                    <#list psgzmxes as mx>
                                        <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: ${800/psgzmxes?size}px">
                                            <#list zjdfList as df>
                                                <#if df.psgzmxid== mx.id && df.pbpstbrid==tbr.id>
                                                    <#if df.score??>${df.score?string('0.00')}</#if>
                                                </#if>
                                            </#list>
                                        </td>

                                    </#list>

                                    <td style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;width: 150px"><#if (tbr.score)??>${tbr.score?string('0.00')}</#if></td>
                                </tr>
                            </#list>
                            <tr style="height: 100px">
                                <td colspan="${psgzmxes?size+3}"
                                    style="box-sizing:border-box;margin:0px;padding:6px;border: 1px solid;font-size: 18px;">
                                    专家签字:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span
                                            style="color: #ffffff">${psTbrList[0].psrname}(签名)</span></td>
                            </tr>
                            </tbody>
                            <tfoot></tfoot>
                        </table>

                    </div>
                    <div id="data_div_new"></div>

                </div>
            </div>
        </div>
    </div>
</div>

java生成代码

public static FileBean html2pdf(FileBean fileBean,String content,String watermark,String direction) throws Exception {
        String fileName = PrimaryKeyUtils.genPrimaryKey();
        content = HtmlUtils.formatPdfHtml(content,direction);
        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ITextRenderer renderer = new ITextRenderer();
            ITextFontResolver fontResolver = (ITextFontResolver) renderer.getSharedContext().getFontResolver();
            //添加字体库 begin
//            File f = new File("C:\\Windows\\Fonts");
            File f = new File(SysCache.APP_PATH + "static" + File.separator + "resok" + File.separator + "Fonts");
            if (f.isDirectory()) {
                File[] files = f.listFiles(new FilenameFilter() {
                    public boolean accept(File dir, String name) {
                        String lower = name.toLowerCase();
                        return lower.endsWith(".otf") || lower.endsWith(".ttf") || lower.endsWith(".ttc");
                    }
                });
                for (int i = 0; i < files.length; i++) {
                    fontResolver.addFont(files[i].getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                }
            }
            //添加字体库end
            renderer.setDocumentFromString(content);
            renderer.layout();
            renderer.createPDF(os);
            renderer.finishPDF();
            byte[] buff = os.toByteArray();
            //保存到磁盘上
            //FileUtil.byte2File(buff,pdfDestPath,pdfName);

            FileUtils.writeByteArrayToFile(new File(fileBean.getPath() + fileName + ".pdf"), buff, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(StringUtils.isNotBlank(watermark)){
            WatermarkUtils.addWatermark(fileBean.getPath() + fileName + ".pdf",watermark);
        }
        return FileSaveUtils.upLoadOther(fileBean.getPath() + fileName + ".pdf");
    }

 

posted @ 2021-09-02 18:14  it_bky  阅读(1075)  评论(0编辑  收藏  举报