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

ITextRenderers html生成pdf 分页+横向的更多相关文章

  1. wkhtmltopdfhtml php生成pdf快照,网页截图,网页快照完整版 (原)

    首先,安装(linux安装为例) 1.下载wkhtmltopdf wget http://download.gna.org/wkhtmltopdf/obsolete/linux/wkhtmltopdf ...

  2. C#使用wkhtmltopdf,把HTML生成PDF(包含分页)

    最近花了2天多的时间终于把HTML生成PDF弄好了.步骤如下: 1.首先是技术选型.看了好多都是收费的就不考虑了. 免费的有: jsPDF(前端生成,清晰度不高,生成比较慢) iText(严格要求ht ...

  3. 利用Java动态生成 PDF 文档

    利用Java动态生成 PDF 文档,则需要开源的API.首先我们先想象需求,在企业应用中,客户会提出一些复杂的需求,比如会针对具体的业务,构建比较典型的具备文档性质的内容,一般会导出PDF进行存档.那 ...

  4. Java生成PDF报表

    一.前言 前几天,做ASN条码收货模块,需要实现打印下载收货报表,经一番查找,选定iText--用于生成PDF文档的一个Java类库.废话不多说,进入正题. 二.iText简介 iText是著名的开放 ...

  5. Java生成PDF文件(转)

    原文地址:https://www.cnblogs.com/shuilangyizu/p/5760928.html 一.前言 前几天,做ASN条码收货模块,需要实现打印下载收货报表,经一番查找,选定iT ...

  6. vue生成pdf

    主要参考 https://blog.csdn.net/qq_37880968/article/details/94626001 1.添加模块 npm install --save html2canva ...

  7. [itext]Java生成PDF文件

    一.前言 最近在做也导出试卷的功能,刚开始是导出为doc,可是导出来格式都有变化,最后说直接将word转为pdf,可是各种不稳定,各种报错.最后想到直接将文件写入pdf(参考:http://www.c ...

  8. [轉載]史上最强php生成pdf文件,html转pdf文件方法

    之前有个客户需要把一些html页面生成pdf文件,然后我就找一些用php把html页面围成pdf文件的类.方法是可谓是找了很多很多,什么html2pdf,pdflib,FPDF这些都试过了,但是都没有 ...

  9. 【PDF】java使用Itext生成pdf文档--详解

    [API接口]  一.Itext简介 API地址:javadoc/index.html:如 D:/MyJAR/原JAR包/PDF/itext-5.5.3/itextpdf-5.5.3-javadoc/ ...

随机推荐

  1. Zend Studio 配置SVN并导入SVN项目

    php 开发过程中,一个项目比较大的话,就需要很多人共同来完成.那么怎样来管理之间的相互配合,分工等呢??那么SVN这个神器就有用处了.SVN:代码版本管理软件.更多svn详细信息请查阅相关文档,这里 ...

  2. [转载]用redis实现跨服务器session

    地址:http://blog.chinaunix.net/uid-11121450-id-3284875.html 这个月我们新开发了一个项目,由于使用到了4台机器做web,使用dns做负载均衡, 上 ...

  3. P5470-[NOI2019]序列【模拟费用流】

    正题 题目链接:https://www.luogu.com.cn/problem/P5470 题目大意 两个长度为\(n\)的序列\(a,b\),求出它们两个长度为\(K\)的子序列,且这两个子序列至 ...

  4. Loj#6247-九个太阳【单位根反演】

    正题 题目链接:https://loj.ac/p/6247 题目大意 给出\(n,k\)求 \[\sum_{0\leq i\leq n,i|k}\binom{n}{i} \] 对\(998244353 ...

  5. k8s负载资源StatefulSet工作解析

    在k8s中工作负载资源StatefulSet用于管理有状态应用. 什么是无状态? 组成一个应用的pod是对等的,它们之前没有关联和依赖关系,不依赖外部存储. 即我们上篇小作文中deployment创建 ...

  6. unittest基本原理及介绍

    unittest基本原理: unittest是python自带的测试框架,还有一个框架是:pytest,这里简单介绍下unittest模块的简单应用 unittest是python的标准测试库,相比于 ...

  7. [洛谷日报#204] StackEdit——Markdown 编辑器的功能介绍

    本文同时发表于洛谷日报,您也可以通过洛谷博客进行查看. 1.介绍与开始使用 1.1 这是什么? StackEdit是基于PageDown.Stack Overflow和其他堆栈交换站点使用的Markd ...

  8. Rigidbody钢体移动时抖动问题

    Rigidbody移动时抖动问题 撞墙抖动 Unity中物体移动有非常多的方式: 比如: transform.position += dir*speed*Time.deltaTime; transfo ...

  9. 第十一章 Dockerfile安装Jenkins-2.249.3-1.1

    一.安装Docker Docker部署Jenkins前提已经安装Docker,这边脚本安装Docker. #1.编写Docker安装脚本 [root@ip-10-0-12-212 ~]# vim In ...

  10. 求求你了,用Docker吧

    这是一个开始使用 Docker 的 Tutorial 大无语事件发生!大数据课实验课要用到Hadoop,实验指导是在一个Ubuntu虚机上通过安装包安装Hadoop并运行一个词频统计程序,整个实验就是 ...