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/ ...
随机推荐
- Microfacet模型采样下的brdf
本文前言 在学习图形学(games101 from bilibili)的时候,也遇到了像这样的问题,Cook-Torrance模型无法实现粗糙度为0时,物体微表面呈现绝对镜面的效果(呈现出一面镜子), ...
- P4585-[FJOI2015]火星商店问题【线段树,可持久化Trie】
正题 题目链接:https://www.luogu.com.cn/problem/P4585 题目大意 \(n\)个集合,开始每个集合中有一个数字. 开启新的一天并且往集合\(s\)中插入数字\(v\ ...
- 用SpringBoot实现策略模式
问题的提出 阅读别人代码的时候最讨厌遇到的就是大段大段的if-else分支语句,一般来说读到下面的时候就忘了上面在判断什么了.很多资料上都会讲到使用策略模式来改进这种代码逻辑. 策略模式的类图如下: ...
- 14-Java锁的概述
14-锁的概述 乐观锁与悲观锁 乐观锁与悲观锁是数据库中引入的名词,但是在并发包里也引入了类似的思想,在这里我们还是有必要需要了解一下. 悲观锁指数据被外界修改持保守态度,认为数据会很容易被其 ...
- C++学习笔记:09 函数模板与类模板
课程<C++语言程序设计进阶>清华大学 郑莉老师) 引入 考虑一个求绝对值函数myabs,对于int,double,float等数据类型需要重载多次,编写多个函数体.函数体逻辑代码完全一致 ...
- Git学习笔记01-安装
首先,什么是git? git是开源的分布式系统,能够将团队的项目上传至git,供团队修改demo 第一步:安装好git(推荐淘宝镜像下载,地址https://npm.taobao.org/mirror ...
- Hadoop面试题总结(三)——MapReduce
1.谈谈Hadoop序列化和反序列化及自定义bean对象实现序列化? 1)序列化和反序列化 (1)序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储(持久化)和网络传输. (2) ...
- 简单的 Go 入门教程
Go(又称 Golang )是 Google 开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言 Docker 和 Kubernetes 都是使用 Go 进行开发的,这几年 Go 越来 ...
- Poetry(1)Poetry介绍与安装
介绍 Poetry 是Python 中的依赖管理和打包工具,当然它也可以配置虚拟环境.它允许您声明项目所依赖的库,并为您管理(安装/更新)它们. 之前一直使用virtualenvwrapper管理虚拟 ...
- 【数据结构】<栈的应用>回文判断
通过栈与队列相关内容的学习,我们知道,栈是"先进后出"的线性表,而队列是"先进先出"的线性表.可以通过构造栈与队列来实现在这一算法.将要判断的字符序列依次压栈和 ...