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, " ", "");
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;">
专家签字: <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 分页+横向的更多相关文章
- wkhtmltopdfhtml php生成pdf快照,网页截图,网页快照完整版 (原)
首先,安装(linux安装为例) 1.下载wkhtmltopdf wget http://download.gna.org/wkhtmltopdf/obsolete/linux/wkhtmltopdf ...
- C#使用wkhtmltopdf,把HTML生成PDF(包含分页)
最近花了2天多的时间终于把HTML生成PDF弄好了.步骤如下: 1.首先是技术选型.看了好多都是收费的就不考虑了. 免费的有: jsPDF(前端生成,清晰度不高,生成比较慢) iText(严格要求ht ...
- 利用Java动态生成 PDF 文档
利用Java动态生成 PDF 文档,则需要开源的API.首先我们先想象需求,在企业应用中,客户会提出一些复杂的需求,比如会针对具体的业务,构建比较典型的具备文档性质的内容,一般会导出PDF进行存档.那 ...
- Java生成PDF报表
一.前言 前几天,做ASN条码收货模块,需要实现打印下载收货报表,经一番查找,选定iText--用于生成PDF文档的一个Java类库.废话不多说,进入正题. 二.iText简介 iText是著名的开放 ...
- Java生成PDF文件(转)
原文地址:https://www.cnblogs.com/shuilangyizu/p/5760928.html 一.前言 前几天,做ASN条码收货模块,需要实现打印下载收货报表,经一番查找,选定iT ...
- vue生成pdf
主要参考 https://blog.csdn.net/qq_37880968/article/details/94626001 1.添加模块 npm install --save html2canva ...
- [itext]Java生成PDF文件
一.前言 最近在做也导出试卷的功能,刚开始是导出为doc,可是导出来格式都有变化,最后说直接将word转为pdf,可是各种不稳定,各种报错.最后想到直接将文件写入pdf(参考:http://www.c ...
- [轉載]史上最强php生成pdf文件,html转pdf文件方法
之前有个客户需要把一些html页面生成pdf文件,然后我就找一些用php把html页面围成pdf文件的类.方法是可谓是找了很多很多,什么html2pdf,pdflib,FPDF这些都试过了,但是都没有 ...
- 【PDF】java使用Itext生成pdf文档--详解
[API接口] 一.Itext简介 API地址:javadoc/index.html:如 D:/MyJAR/原JAR包/PDF/itext-5.5.3/itextpdf-5.5.3-javadoc/ ...
随机推荐
- centos实现免密登陆及远程操作
----------------------------**********------------------------------------------------- 免密码登陆 第一步: 执 ...
- django使用restframework序列化查询集合(querryset)
第一: pip install djangorestframework 第二: 在setting.py文件中的app添加名为: 'rest_framework', 第三:再项目的APP下面新建名为(可 ...
- 解决Windows 游戏 错误代码 1170000
安装"Xbox标识提供程序" 下载地址:https://www.microsoft.com/store/apps/9wzdncrd1hkw
- P3293-[SCOI2016]美味【主席树】
正题 题目链接:https://www.luogu.com.cn/problem/P3293 题目大意 给出一个长度为\(n\)的序列,\(m\)次询问给出\(b,x,l,r\)表示询问在\([l,r ...
- 华为云计算IE面试笔记-其它知识点
* 虚拟化与云计算的区别?云计算和虚拟化关系?华为云计算怎么做的? 虚拟化是一种具体的技术,实现的是对硬件资源的虚拟化,提升资源利用率,降低能耗,云计算是一种概念各种技术组件的集合,针对的是对各种资源 ...
- 一篇文章告诉你Python接口自动化测试中读取Text,Excel,Yaml文件的方法
前言 不管是做Ui自动化和接口自动,代码和数据要分离,会用到Text,Excel,Yaml.今天讲讲如何读取文件数据 Python也可以读取ini文件,传送门 记住一点:测试的数据是不能写死在代码里面 ...
- 如何评估 Serverless 服务能力?这份报告给出了 40 条标准
编者按:两年前,我们还在讨论什么是 Serverless,Serverless 如何落地.如今,已经有评测机构给出了 40 条标准来对 Serverless 的服务能力进行评估,这些评估细则既是技术生 ...
- 从零入门 Serverless | 课时5 函数的调试与部署
作者 | 江昱 阿里巴巴高级产品经理 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复"入门",即可获取 S ...
- 洛谷4234最小差值生成树 (LCT维护生成树)
这也是一道LCT维护生成树的题. 那么我们还是按照套路,先对边进行排序,然后顺次加入. 不过和别的题有所不同的是: 在本题中,我们需要保证LCT中正好有\(n-1\)条边的时候,才能更新\(ans\) ...
- 无法获取指向控制台的文件描述符 (couldn't get a file descriptor referring to the console)
背景 最近收拾东西,从一堆杂物里翻出来尘封四年多的树莓派 3B 主机来,打扫打扫灰尘,接上电源,居然还能通过之前设置好的 VNC 连上.欣慰之余,开始 clone 我的 git 项目,为它们拓展一个新 ...